mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-29 00:10:42 +01:00
fix(mount): gate directory nlink counting behind -posix.dirNLink option (#9026)
The directory nlink counting (2 + subdirectory count) requires listing cached directory entries on every stat, which has a performance cost. Gate it behind the -posix.dirNLink flag (default: off). When disabled, directories report nlink=2 (POSIX baseline). When enabled, directories report nlink=2 + number of subdirectories from cached entries.
This commit is contained in:
1 parent
39e76b8e94
commit
8aa5809824
5 files changed
+18
-3
No files matched your search
@@ -55,6 +55,9 @@ type MountOptions struct {
|
||||
// Distributed lock for cross-mount write coordination
|
||||
distributedLock *bool
|
||||
|
||||
// POSIX compliance options
|
||||
posixDirNlink *bool
|
||||
|
||||
// FUSE performance options
|
||||
writebackCache *bool
|
||||
asyncDio *bool
|
||||
@@ -131,6 +134,9 @@ func init() {
|
||||
// Distributed lock for cross-mount write coordination
|
||||
mountOptions.distributedLock = cmdMount.Flag.Bool("dlm", false, "enable distributed lock for cross-mount write coordination (only one mount can write a file at a time)")
|
||||
|
||||
// POSIX compliance options
|
||||
mountOptions.posixDirNlink = cmdMount.Flag.Bool("posix.dirNLink", false, "report POSIX-compliant directory nlink (2 + subdirectory count); costs one directory listing per stat")
|
||||
|
||||
// FUSE performance options
|
||||
mountOptions.writebackCache = cmdMount.Flag.Bool("writebackCache", false, "enable FUSE writeback cache for improved write performance (at risk of data loss on crash)")
|
||||
mountOptions.asyncDio = cmdMount.Flag.Bool("asyncDio", false, "enable async direct I/O for better concurrency")
|
||||
|
||||
@@ -354,6 +354,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
DirIdleEvictSec: *option.dirIdleEvictSec,
|
||||
EnableDistributedLock: option.distributedLock != nil && *option.distributedLock,
|
||||
WritebackCache: option.writebackCache != nil && *option.writebackCache,
|
||||
PosixDirNlink: option.posixDirNlink != nil && *option.posixDirNlink,
|
||||
})
|
||||
|
||||
// create mount root
|
||||
|
||||
@@ -93,6 +93,12 @@ type Option struct {
|
||||
// When true, Flush() returns immediately and data upload + metadata flush happen in background.
|
||||
WritebackCache bool
|
||||
|
||||
// PosixDirNlink enables POSIX-compliant directory nlink counting
|
||||
// (nlink = 2 + number_of_subdirectories). This requires listing
|
||||
// cached directory entries on every stat, which has a performance cost.
|
||||
// When false (default), directories report nlink=2.
|
||||
PosixDirNlink bool
|
||||
|
||||
uniqueCacheDirForRead string
|
||||
uniqueCacheDirForWrite string
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse
|
||||
glog.V(4).Infof("GetAttr %v", input.NodeId)
|
||||
if input.NodeId == 1 {
|
||||
wfs.setRootAttr(out)
|
||||
wfs.applyDirNlink(&out.Attr, util.FullPath(wfs.option.FilerMountRootPath))
|
||||
if wfs.option.PosixDirNlink {
|
||||
wfs.applyDirNlink(&out.Attr, util.FullPath(wfs.option.FilerMountRootPath))
|
||||
}
|
||||
return fuse.OK
|
||||
}
|
||||
|
||||
@@ -27,7 +29,7 @@ func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse
|
||||
out.AttrValid = 1
|
||||
wfs.setAttrByPbEntry(&out.Attr, inode, entry, true)
|
||||
wfs.applyInMemoryAtime(&out.Attr, inode)
|
||||
if entry.IsDirectory {
|
||||
if entry.IsDirectory && wfs.option.PosixDirNlink {
|
||||
wfs.applyDirNlink(&out.Attr, path)
|
||||
}
|
||||
return status
|
||||
|
||||
@@ -44,7 +44,7 @@ func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name strin
|
||||
|
||||
wfs.outputFilerEntry(out, inode, localEntry)
|
||||
|
||||
if localEntry.IsDirectory() {
|
||||
if localEntry.IsDirectory() && wfs.option.PosixDirNlink {
|
||||
wfs.applyDirNlink(&out.Attr, fullFilePath)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user