mount: let a readdirplus stop taking references at a cap

The inode table only shrinks when the kernel returns a reference, so a walk
over a large tree grows it with every child it touches and nothing gives any
of it back until the kernel reclaims dentries. On a mount with tens of
millions of files that is most of the process's heap.

-maxInodeEntries stops the speculative half of that. Past the cap a
readdirplus still reports every name, but leaves the EntryOut zeroed: Linux
reads a zero nodeid as 'no attributes for this entry', takes no reference, and
looks up the ones the client actually needs. A LOOKUP is never refused, so the
table can still grow past the cap by what a client really asks for, and
nothing here evicts. Default 0 keeps today's behavior.
This commit is contained in:
Chris Lu
2026-08-18 21:00:49 -07:00
parent ed75a61fb0
commit bd3b75b534
7 changed files with 75 additions and 7 deletions
+2
View File
@@ -21,6 +21,7 @@ type MountOptions struct {
concurrentReaders *int
cacheMetaTtlSec *int
cacheDirMaxEntries *int
maxInodeEntries *int
cacheDirForRead *string
cacheDirForWrite *string
cacheSizeMBForRead *int64
@@ -116,6 +117,7 @@ func init() {
mountOptions.writeBufferSizeMB = cmdMount.Flag.Int64("writeBufferSizeMB", 0, "global cap on the per-mount write buffer (memory + swap) in MB, 0 means unlimited. Bounds /tmp growth when volume uploads stall")
mountOptions.cacheMetaTtlSec = cmdMount.Flag.Int("cacheMetaTtlSec", 60, "metadata cache validity seconds")
mountOptions.cacheDirMaxEntries = cmdMount.Flag.Int("cacheDirMaxEntries", 100000, "a directory with more children than this is not cached locally but read directly from the filer; 0 caches everything")
mountOptions.maxInodeEntries = cmdMount.Flag.Int("maxInodeEntries", 0, "stop handing the kernel references from readdirplus once this many inodes are tracked; listings stay complete and the kernel looks up what it needs. Does not evict - the table shrinks only as the kernel returns references. 0 is unlimited")
mountOptions.dataCenter = cmdMount.Flag.String("dataCenter", "", "prefer to write to the data center")
mountOptions.allowOthers = cmdMount.Flag.Bool("allowOthers", true, "allows other users to access the file system")
mountOptions.defaultPermissions = cmdMount.Flag.Bool("defaultPermissions", true, "enforce permissions by the operating system")
+1
View File
@@ -204,6 +204,7 @@ func buildSeaweedFileSystem(option *MountOptions, p fileSystemParams) *mount.WFS
WriteBufferSizeMB: *option.writeBufferSizeMB,
CacheMetaTTlSec: *option.cacheMetaTtlSec,
CacheDirMaxEntries: *option.cacheDirMaxEntries,
MaxInodeEntries: *option.maxInodeEntries,
DataCenter: *option.dataCenter,
Quota: int64(*option.collectionQuota) * 1024 * 1024,
LogicalDiskUsage: *option.logicalDiskUsage,