Browse Source

mount: fix weed inode nlookup do not equel kernel inode nlookup (#7682)

* mount: fix weed inode nlookup do not equel kernel inode nlookup

* mount: add underflow protection for nlookup decrement in Forget

* mount: use consistent == 0 check for uint64 nlookup

* Update weed/mount/inode_to_path.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* mount: snapshot data before unlock in Forget to avoid using deleted InodeEntry

---------

Co-authored-by: chrislu <chris.lu@gmail.com>
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
pull/7607/merge
Chen Pu 1 day ago
committed by GitHub
parent
commit
40eee23be9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 43
      weed/mount/inode_to_path.go
  2. 3
      weed/mount/weedfs_dir_read.go

43
weed/mount/inode_to_path.go

@ -1,11 +1,12 @@
package mount
import (
"sync"
"time"
"github.com/hanwen/go-fuse/v2/fuse"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/util"
"sync"
"time"
)
type InodeToPath struct {
@ -41,7 +42,6 @@ func (ie *InodeEntry) removeOnePath(p util.FullPath) bool {
ie.paths[x] = ie.paths[x+1]
}
ie.paths = ie.paths[0 : len(ie.paths)-1]
ie.nlookup--
return true
}
@ -230,9 +230,6 @@ func (i *InodeToPath) removePathFromInode2Path(inode uint64, path util.FullPath)
if !ie.removeOnePath(path) {
return
}
if len(ie.paths) == 0 {
delete(i.inode2path, inode)
}
}
func (i *InodeToPath) MovePath(sourcePath, targetPath util.FullPath) (sourceInode, targetInode uint64) {
@ -259,9 +256,6 @@ func (i *InodeToPath) MovePath(sourcePath, targetPath util.FullPath) (sourceInod
}
}
entry.isChildrenCached = false
if !targetFound {
entry.nlookup++
}
} else {
glog.Errorf("MovePath %s to %s: sourceInode %d not found", sourcePath, targetPath, sourceInode)
}
@ -269,24 +263,39 @@ func (i *InodeToPath) MovePath(sourcePath, targetPath util.FullPath) (sourceInod
}
func (i *InodeToPath) Forget(inode, nlookup uint64, onForgetDir func(dir util.FullPath)) {
var dirPaths []util.FullPath
callOnForgetDir := false
i.Lock()
path, found := i.inode2path[inode]
if found {
path.nlookup -= nlookup
if path.nlookup <= 0 {
if nlookup > path.nlookup {
glog.Errorf("kernel forget over-decrement: inode %d paths %v current %d forget %d", inode, path.paths, path.nlookup, nlookup)
path.nlookup = 0
} else {
path.nlookup -= nlookup
}
glog.V(4).Infof("kernel forget: inode %d paths %v nlookup %d", inode, path.paths, path.nlookup)
if path.nlookup == 0 {
if path.isDirectory && onForgetDir != nil {
dirPaths = append([]util.FullPath(nil), path.paths...)
callOnForgetDir = true
}
for _, p := range path.paths {
delete(i.path2inode, p)
}
delete(i.inode2path, inode)
} else {
glog.V(4).Infof("kernel forget but nlookup not zero: inode %d paths %v nlookup %d", inode, path.paths, path.nlookup)
}
} else {
glog.Warningf("kernel forget but inode not found: inode %d", inode)
}
i.Unlock()
if found {
if path.isDirectory && path.nlookup <= 0 && onForgetDir != nil {
path.isChildrenCached = false
for _, p := range path.paths {
onForgetDir(p)
}
if callOnForgetDir {
for _, p := range dirPaths {
onForgetDir(p)
}
}
}

3
weed/mount/weedfs_dir_read.go

@ -169,7 +169,7 @@ func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPl
processEachEntryFn := func(entry *filer.Entry) bool {
dirEntry.Name = entry.Name()
dirEntry.Mode = toSyscallMode(entry.Mode)
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Crtime.Unix(), entry.IsDirectory(), len(entry.HardLinkId) > 0, entry.Inode, isPlusMode)
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Crtime.Unix(), entry.IsDirectory(), len(entry.HardLinkId) > 0, entry.Inode, false)
dirEntry.Ino = inode
if !isPlusMode {
if !out.AddDirEntry(dirEntry) {
@ -187,6 +187,7 @@ func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPl
entry = filer.FromPbEntry(string(dirPath), fh.GetEntry().GetEntry())
}
wfs.outputFilerEntry(entryOut, inode, entry)
wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Crtime.Unix(), entry.IsDirectory(), len(entry.HardLinkId) > 0, entry.Inode, true)
}
return true
}

Loading…
Cancel
Save