Skip to content

Commit

Permalink
fix: avoid inode unlink due to net error
Browse files Browse the repository at this point in the history
When creating a file, the client will create inode first and then send a
create dentry request. If create dentry request fails due to a net
error (e.g. send the request to metanode but timed out when getting
response), there is a tiny chance that the dentry is created
successfully on metanode. Thus we cannot unlink the inode created
previously because we would rather leave the orphan inode than create
an orphan dentry.

Signed-off-by: Shuoran Liu <[email protected]>
  • Loading branch information
shuoranliu committed Mar 4, 2020
1 parent 4212ac5 commit 4b7f438
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions sdk/meta/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ func (mw *MetaWrapper) Create_ll(parentID uint64, name string, mode, uid, gid ui

create_dentry:
status, err = mw.dcreate(parentMP, parentID, name, info.Inode, mode)
if err != nil || status != statusOK {
if status == statusExist {
return nil, syscall.EEXIST
} else {
if err != nil {
return nil, statusToErrno(status)
} else if status != statusOK {
if status != statusExist {
mw.iunlink(mp, info.Inode)
mw.ievict(mp, info.Inode)
return nil, statusToErrno(status)
}
return nil, statusToErrno(status)
}
return info, nil
}
Expand Down Expand Up @@ -297,15 +297,13 @@ func (mw *MetaWrapper) Rename_ll(srcParentID uint64, srcName string, dstParentID
// create dentry in dst parent
status, err = mw.dcreate(dstParentMP, dstParentID, dstName, inode, mode)
if err != nil {
mw.iunlink(srcMP, inode)
return syscall.EAGAIN
}

// Note that only regular files are allowed to be overwritten.
if status == statusExist && proto.IsRegular(mode) {
status, oldInode, err = mw.dupdate(dstParentMP, dstParentID, dstName, inode)
if err != nil {
mw.iunlink(srcMP, inode)
return syscall.EAGAIN
}
}
Expand All @@ -317,7 +315,9 @@ func (mw *MetaWrapper) Rename_ll(srcParentID uint64, srcName string, dstParentID

// delete dentry from src parent
status, _, err = mw.ddelete(srcParentMP, srcParentID, srcName)
if err != nil || status != statusOK {
if err != nil {
return statusToErrno(status)
} else if status != statusOK {
var (
sts int
e error
Expand Down Expand Up @@ -469,13 +469,13 @@ func (mw *MetaWrapper) Link(parentID uint64, name string, ino uint64) (*proto.In

// create new dentry and refer to the inode
status, err = mw.dcreate(parentMP, parentID, name, ino, info.Mode)
if err != nil || status != statusOK {
if status == statusExist {
return nil, syscall.EEXIST
} else {
if err != nil {
return nil, statusToErrno(status)
} else if status != statusOK {
if status != statusExist {
mw.iunlink(mp, ino)
return nil, syscall.EAGAIN
}
return nil, statusToErrno(status)
}
return info, nil
}
Expand Down

0 comments on commit 4b7f438

Please sign in to comment.