enhance(client): ingnore exist error when rebuild parent dir

Signed-off-by: chihe <chi.he@oppo.com>
This commit is contained in:
chihe 2023-11-22 18:07:21 -08:00
parent db0cae90ff
commit 505bd658c7
7 changed files with 43 additions and 32 deletions

View File

@ -164,7 +164,8 @@ func (d *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.Cr
auditlog.LogClientOp("Create", fullPath, "nil", err, time.Since(start).Microseconds(), newInode, 0)
}()
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(req.Mode.Perm()), req.Uid, req.Gid, nil, fullPath)
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(req.Mode.Perm()), req.Uid, req.Gid, nil,
fullPath, false)
if err != nil {
log.LogErrorf("Create: parent(%v) req(%v) err(%v)", d.info.Inode, req, err)
return nil, nil, ParseError(err)
@ -222,7 +223,8 @@ func (d *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error
auditlog.LogClientOp("Mkdir", fullPath, "nil", err, time.Since(start).Microseconds(), newInode, 0)
}()
log.LogDebugf("TRACE Mkdir:enter")
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(os.ModeDir|req.Mode.Perm()), req.Uid, req.Gid, nil, fullPath)
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(os.ModeDir|req.Mode.Perm()), req.Uid,
req.Gid, nil, fullPath, false)
if err != nil {
log.LogErrorf("Mkdir: parent(%v) req(%v) err(%v)", d.info.Inode, req, err)
return nil, ParseError(err)
@ -689,7 +691,8 @@ func (d *Dir) Mknod(ctx context.Context, req *fuse.MknodRequest) (fs.Node, error
metric.SetWithLabels(err, map[string]string{exporter.Vol: d.super.volname})
}()
fullPath := path.Join(d.getCwd(), req.Name)
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(req.Mode), req.Uid, req.Gid, nil, fullPath)
info, err := d.super.mw.Create_ll(d.info.Inode, req.Name, proto.Mode(req.Mode), req.Uid, req.Gid,
nil, fullPath, false)
if err != nil {
log.LogErrorf("Mknod: parent(%v) req(%v) err(%v)", d.info.Inode, req, err)
return nil, ParseError(err)
@ -720,7 +723,8 @@ func (d *Dir) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, e
metric.SetWithLabels(err, map[string]string{exporter.Vol: d.super.volname})
}()
fullPath := path.Join(d.getCwd(), req.NewName)
info, err := d.super.mw.Create_ll(parentIno, req.NewName, proto.Mode(os.ModeSymlink|os.ModePerm), req.Uid, req.Gid, []byte(req.Target), fullPath)
info, err := d.super.mw.Create_ll(parentIno, req.NewName, proto.Mode(os.ModeSymlink|os.ModePerm), req.Uid,
req.Gid, []byte(req.Target), fullPath, false)
if err != nil {
log.LogErrorf("Symlink: parent(%v) NewName(%v) err(%v)", parentIno, req.NewName, err)
return nil, ParseError(err)

View File

@ -118,7 +118,7 @@ func (f *File) getParentPath() string {
node, ok := f.super.nodeCache[f.parentIno]
f.super.fslock.Unlock()
if !ok {
log.LogErrorf("Get node cache failed: ino(%v)", f.parentIno)
log.LogWarnf("Get node cache failed: ino(%v)", f.parentIno)
return "unknown"
}
parentDir, ok := node.(*Dir)

View File

@ -1370,13 +1370,13 @@ func (c *client) setattr(info *proto.InodeInfo, valid uint32, mode, uid, gid uin
func (c *client) create(pino uint64, name string, mode uint32, fullPath string) (info *proto.InodeInfo, err error) {
fuseMode := mode & 0777
return c.mw.Create_ll(pino, name, fuseMode, 0, 0, nil, fullPath)
return c.mw.Create_ll(pino, name, fuseMode, 0, 0, nil, fullPath, false)
}
func (c *client) mkdir(pino uint64, name string, mode uint32, fullPath string) (info *proto.InodeInfo, err error) {
fuseMode := mode & 0777
fuseMode |= uint32(os.ModeDir)
return c.mw.Create_ll(pino, name, fuseMode, 0, 0, nil, fullPath)
return c.mw.Create_ll(pino, name, fuseMode, 0, 0, nil, fullPath, false)
}
func (c *client) openStream(f *file) {

View File

@ -301,7 +301,7 @@ func (v *Volume) SetXAttr(path string, key string, data []byte, autoCreate bool)
return err
}
var inodeInfo *proto.InodeInfo
if inodeInfo, err = v.mw.Create_ll(parentID, filename, DefaultFileMode, 0, 0, nil, path); err != nil {
if inodeInfo, err = v.mw.Create_ll(parentID, filename, DefaultFileMode, 0, 0, nil, path, false); err != nil {
return err
}
inode = inodeInfo.Inode
@ -1916,7 +1916,8 @@ func (v *Volume) recursiveMakeDirectory(path string) (ino uint64, err error) {
}
if err == syscall.ENOENT {
var info *proto.InodeInfo
info, err = v.mw.Create_ll(ino, pathItem.Name, uint32(DefaultDirMode), 0, 0, nil, path[:pathIterator.cursor])
info, err = v.mw.Create_ll(ino, pathItem.Name, uint32(DefaultDirMode), 0, 0, nil,
path[:pathIterator.cursor], false)
if err != nil && err == syscall.EEXIST {
existInode, mode, e := v.mw.Lookup_ll(ino, pathItem.Name)
if e != nil {
@ -1974,7 +1975,7 @@ func (v *Volume) lookupDirectories(dirs []string, autoCreate bool) (inode uint64
if lookupErr == syscall.ENOENT {
var inodeInfo *proto.InodeInfo
var createErr error
inodeInfo, createErr = v.mw.Create_ll(parentId, dir, uint32(DefaultDirMode), 0, 0, nil, "/"+dir)
inodeInfo, createErr = v.mw.Create_ll(parentId, dir, uint32(DefaultDirMode), 0, 0, nil, "/"+dir, false)
if createErr != nil && createErr != syscall.EEXIST {
log.LogErrorf("lookupDirectories: meta create fail, parentID(%v) name(%v) mode(%v) err(%v)", parentId, dir, os.ModeDir, createErr)
return 0, createErr

View File

@ -110,7 +110,7 @@ func (mw *MetaWrapper) Statfs() (total, used, inodeCount uint64) {
return
}
func (mw *MetaWrapper) Create_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte, fullPath string) (*proto.InodeInfo, error) {
func (mw *MetaWrapper) Create_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte, fullPath string, ignoreExist bool) (*proto.InodeInfo, error) {
// if mw.EnableTransaction {
txMask := proto.TxOpMaskOff
if proto.IsRegular(mode) {
@ -124,13 +124,14 @@ func (mw *MetaWrapper) Create_ll(parentID uint64, name string, mode, uid, gid ui
}
txType := proto.TxMaskToType(txMask)
if mw.enableTx(txMask) && txType != proto.TxTypeUndefined {
return mw.txCreate_ll(parentID, name, mode, uid, gid, target, txType, fullPath)
return mw.txCreate_ll(parentID, name, mode, uid, gid, target, txType, fullPath, ignoreExist)
} else {
return mw.create_ll(parentID, name, mode, uid, gid, target, fullPath)
return mw.create_ll(parentID, name, mode, uid, gid, target, fullPath, ignoreExist)
}
}
func (mw *MetaWrapper) txCreate_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte, txType uint32, fullPath string) (info *proto.InodeInfo, err error) {
func (mw *MetaWrapper) txCreate_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte, txType uint32,
fullPath string, ignoreExist bool) (info *proto.InodeInfo, err error) {
var (
status int
mp *MetaPartition
@ -219,7 +220,8 @@ create_dentry:
return info, nil
}
func (mw *MetaWrapper) create_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte, fullPath string) (*proto.InodeInfo, error) {
func (mw *MetaWrapper) create_ll(parentID uint64, name string, mode, uid, gid uint32, target []byte,
fullPath string, ignoreExist bool) (*proto.InodeInfo, error) {
var (
status int
err error
@ -289,7 +291,7 @@ create_dentry:
if mw.EnableQuota {
status, err = mw.quotaDcreate(parentMP, parentID, name, info.Inode, mode, quotaIds, fullPath)
} else {
status, err = mw.dcreate(parentMP, parentID, name, info.Inode, mode, fullPath)
status, err = mw.dcreate(parentMP, parentID, name, info.Inode, mode, fullPath, ignoreExist)
}
if err != nil {
if status == statusOpDirQuota || status == statusNoSpace {
@ -1058,7 +1060,7 @@ func (mw *MetaWrapper) rename_ll(srcParentID uint64, srcName string, dstParentID
}
// create dentry in dst parent
status, err = mw.dcreate(dstParentMP, dstParentID, dstName, inode, mode, dstFullPath)
status, err = mw.dcreate(dstParentMP, dstParentID, dstName, inode, mode, dstFullPath, false)
if err != nil {
if status == statusOpDirQuota {
return statusToErrno(status)
@ -1216,7 +1218,7 @@ func (mw *MetaWrapper) DentryCreate_ll(parentID uint64, name string, inode uint6
}
var err error
var status int
if status, err = mw.dcreate(parentMP, parentID, name, inode, mode, fullPath); err != nil || status != statusOK {
if status, err = mw.dcreate(parentMP, parentID, name, inode, mode, fullPath, false); err != nil || status != statusOK {
return statusToErrno(status)
}
return nil
@ -1487,7 +1489,7 @@ func (mw *MetaWrapper) link(parentID uint64, name string, ino uint64, fullPath s
// create new dentry and refer to the inode
status, err = mw.quotaDcreate(parentMP, parentID, name, ino, info.Mode, quotaIds, fullPath)
} else {
status, err = mw.dcreate(parentMP, parentID, name, ino, info.Mode, fullPath)
status, err = mw.dcreate(parentMP, parentID, name, ino, info.Mode, fullPath, false)
}
if err != nil {
return nil, statusToErrno(status)

View File

@ -571,7 +571,8 @@ func (mw *MetaWrapper) quotaDcreate(mp *MetaPartition, parentID uint64, name str
return
}
func (mw *MetaWrapper) dcreate(mp *MetaPartition, parentID uint64, name string, inode uint64, mode uint32, fullPath string) (status int, err error) {
func (mw *MetaWrapper) dcreate(mp *MetaPartition, parentID uint64, name string, inode uint64, mode uint32,
fullPath string, ignoreExistError bool) (status int, err error) {
bgTime := stat.BeginStat()
defer func() {
stat.EndStat("dcreate", err, bgTime, 1)
@ -615,7 +616,7 @@ func (mw *MetaWrapper) dcreate(mp *MetaPartition, parentID uint64, name string,
if (status != statusOK) && (status != statusExist) {
err = errors.New(packet.GetResultMsg())
log.LogErrorf("dcreate: packet(%v) mp(%v) req(%v) result(%v)", packet, mp, *req, packet.GetResultMsg())
} else if status == statusExist {
} else if status == statusExist && ignoreExistError == false {
log.LogWarnf("dcreate: packet(%v) mp(%v) req(%v) result(%v)", packet, mp, *req, packet.GetResultMsg())
}
if proto.IsDir(mode) {

View File

@ -103,7 +103,7 @@ func (trash *Trash) InitTrashRoot() (err error) {
return err
}
_, err = trash.CreateDirectory(parentDirInfo.Inode, TrashPrefix,
parentDirInfo.Mode, parentDirInfo.Uid, parentDirInfo.Gid, TrashPrefix)
parentDirInfo.Mode, parentDirInfo.Uid, parentDirInfo.Gid, TrashPrefix, false)
if err != nil {
log.LogErrorf("action[InitTrashRoot]create trash root failed: %v", err.Error())
return err
@ -120,7 +120,7 @@ func (trash *Trash) initTrashRootInodeInfo() {
trash.trashRootGid = trashRootInfo.Gid
}
func (trash *Trash) createCurrent() (err error) {
func (trash *Trash) createCurrent(ingoreExist bool) (err error) {
trashCurrent := path.Join(trash.trashRoot, CurrentName)
log.LogDebugf("action[createCurrent] enter")
if trash.pathIsExist(trashCurrent) {
@ -139,7 +139,7 @@ func (trash *Trash) createCurrent() (err error) {
return nil
}
inodeInfo, err := trash.CreateDirectory(trash.trashRootIno, CurrentName,
trash.trashRootMode, trash.trashRootUid, trash.trashRootGid, path.Join(TrashPrefix, CurrentName))
trash.trashRootMode, trash.trashRootUid, trash.trashRootGid, path.Join(TrashPrefix, CurrentName), ingoreExist)
if err != nil {
if err != syscall.EEXIST {
log.LogErrorf("action[createCurrent]create trash current failed: %v", err.Error())
@ -201,7 +201,7 @@ func (trash *Trash) MoveToTrash(parentPathAbsolute string, parentIno uint64, fil
log.LogDebugf("action[MoveToTrash] : parentPathAbsolute(%v) fileName(%v) consume %v", parentPathAbsolute, fileName, time.Since(start).Seconds())
}()
log.LogDebugf("action[MoveToTrash] : parentPathAbsolute(%v) fileName(%v) parentIno%v", parentPathAbsolute, fileName, parentIno)
if err = trash.createCurrent(); err != nil {
if err = trash.createCurrent(true); err != nil {
return err
}
//save current ino to prevent renaming current to expired
@ -600,10 +600,10 @@ func (trash *Trash) IsDir(path string) bool {
}
func (trash *Trash) CreateDirectory(pino uint64, name string, mode, uid, gid uint32, fullName string) (info *proto.InodeInfo, err error) {
func (trash *Trash) CreateDirectory(pino uint64, name string, mode, uid, gid uint32, fullName string, ignoreExist bool) (info *proto.InodeInfo, err error) {
fuseMode := mode & 0777
fuseMode |= uint32(os.ModeDir)
return trash.mw.Create_ll(pino, name, fuseMode, uid, gid, nil, fullName)
return trash.mw.Create_ll(pino, name, fuseMode, uid, gid, nil, fullName, ignoreExist)
}
func (trash *Trash) LookupEntry(parentID uint64, name string) (*proto.InodeInfo, error) {
@ -646,7 +646,7 @@ func (trash *Trash) createParentPathInTrash(parentPath, rootDir string) (err err
var trashCurrent string
if rootDir == CurrentName {
trashCurrent = path.Join(trash.trashRoot, CurrentName)
if err = trash.createCurrent(); err != nil {
if err = trash.createCurrent(true); err != nil {
return
}
} else {
@ -694,17 +694,20 @@ func (trash *Trash) createParentPathInTrash(parentPath, rootDir string) (err err
info, err = trash.LookupPath(parentPath, true)
if err != nil {
log.LogWarnf("action[createParentPathInTrash] LookupPath origin %v failed:%v", parentPath, err.Error())
log.LogDebugf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
//log.LogDebugf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
return
}
if info == nil {
panic(fmt.Sprintf("info should not be nil for parentPath %v", parentPath))
return
}
parentInfo, err = trash.CreateDirectory(parentIno, sub, info.Mode, info.Uid, info.Gid, path.Join(parentPath, sub))
parentInfo, err = trash.CreateDirectory(parentIno, sub, info.Mode, info.Uid, info.Gid, path.Join(parentPath, sub), true)
if err != nil {
log.LogWarnf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
log.LogDebugf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
if err == syscall.EEXIST {
log.LogDebugf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
} else {
log.LogWarnf("action[createParentPathInTrash] CreateDirectory %v in trash failed: %v", cur, err.Error())
}
return
}
if parentInfo == nil {