From 735e94f6ba3209522fd0af123afcda44cef098cc Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 28 Apr 2026 13:42:58 -0700 Subject: [PATCH] mount: expose -fuse.maxBackground and -fuse.congestionThreshold flags (closes #9258) (#9268) * mount: expose `-fuse.maxBackground` flag (closes #9258) The Linux FUSE driver caps in-flight async requests via `/sys/fs/fuse/connections//max_background` (and a derived `congestion_threshold = 3/4 * max_background`). Heavy upload workloads need this raised, but the cap currently lives only in `/sys`, so it resets on reboot/remount. `weed mount` was hardcoding `MaxBackground: 128`. Promote it to a flag, default unchanged. Setting `-fuse.maxBackground=2048` reproduces the manual `echo 2048 > .../max_background` (and gives 1536 for congestion_threshold automatically) persistently across remounts. `congestion_threshold` is not exposed as a separate flag because go-fuse derives it as 3/4 of MaxBackground in InitOut and offers no hook to override; users wanting a different ratio can still write /sys/fs/fuse/connections//congestion_threshold post-mount. * mount: add `-fuse.congestionThreshold` flag, bump go-fuse to v2.9.3 go-fuse v2.9.3 exposes CongestionThreshold as a separate MountOption, so we can now let users override the kernel's default 3/4-of-max_background ratio at mount time instead of having to write /sys/fs/fuse/connections//congestion_threshold post-mount on every remount/reboot. Default 0 preserves existing behavior (kernel derives it as 3/4 * max_background). Non-zero is sent to the kernel verbatim; the kernel clamps it to max_background if higher. --- go.mod | 2 +- go.sum | 2 ++ weed/command/mount.go | 10 +++++++--- weed/command/mount_std.go | 12 +++++++++++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 025633139..78c1e442e 100644 --- a/go.mod +++ b/go.mod @@ -148,7 +148,7 @@ require ( github.com/rdleal/intervalst v1.5.0 github.com/redis/go-redis/v9 v9.18.0 github.com/schollz/progressbar/v3 v3.19.0 - github.com/seaweedfs/go-fuse/v2 v2.9.2 + github.com/seaweedfs/go-fuse/v2 v2.9.3 github.com/shirou/gopsutil/v4 v4.26.2 github.com/tarantool/go-tarantool/v2 v2.4.2 github.com/testcontainers/testcontainers-go v0.40.0 diff --git a/go.sum b/go.sum index e26d805fc..e7fbdab87 100644 --- a/go.sum +++ b/go.sum @@ -1842,6 +1842,8 @@ github.com/seaweedfs/cockroachdb-parser v0.0.0-20260225204133-2f342c5ea564 h1:Tg github.com/seaweedfs/cockroachdb-parser v0.0.0-20260225204133-2f342c5ea564/go.mod h1:JSKCh6uCHBz91lQYFYHCyTrSVIPge4SUFVn28iwMNB0= github.com/seaweedfs/go-fuse/v2 v2.9.2 h1:IfP/yFjLGO4rALcJY2Gb39PlebHxLnj7dkIiQAjFres= github.com/seaweedfs/go-fuse/v2 v2.9.2/go.mod h1:zABdmWEa6A0bwaBeEOBUeUkGIZlxUhcdv+V1Dcc/U/I= +github.com/seaweedfs/go-fuse/v2 v2.9.3 h1:rJufGrHImTx7yoGUmetUi+To4LrmTQJROJnBHWt92ic= +github.com/seaweedfs/go-fuse/v2 v2.9.3/go.mod h1:zABdmWEa6A0bwaBeEOBUeUkGIZlxUhcdv+V1Dcc/U/I= github.com/seaweedfs/goexif v1.0.3 h1:ve/OjI7dxPW8X9YQsv3JuVMaxEyF9Rvfd04ouL+Bz30= github.com/seaweedfs/goexif v1.0.3/go.mod h1:Oni780Z236sXpIQzk1XoJlTwqrJ02smEin9zQeff7Fk= github.com/seaweedfs/raft v1.1.7 h1:3mVJZ2p4rdvBtbbrHROPjYKtH+q5qjMBc56G6VRu1kA= diff --git a/weed/command/mount.go b/weed/command/mount.go index 1e7c926a3..d23cdfc1b 100644 --- a/weed/command/mount.go +++ b/weed/command/mount.go @@ -68,9 +68,11 @@ type MountOptions struct { posixDirNlink *bool // FUSE performance options - writebackCache *bool - asyncDio *bool - cacheSymlink *bool + writebackCache *bool + asyncDio *bool + cacheSymlink *bool + fuseMaxBackground *int + fuseCongestionThreshold *int // macOS-specific FUSE options novncache *bool @@ -159,6 +161,8 @@ func init() { 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") mountOptions.cacheSymlink = cmdMount.Flag.Bool("cacheSymlink", false, "enable symlink caching to reduce metadata lookups") + mountOptions.fuseMaxBackground = cmdMount.Flag.Int("fuse.maxBackground", 128, "FUSE max_background: maximum in-flight asynchronous requests the kernel will queue. Heavy upload workloads may benefit from higher values (e.g. 2048). Equivalent to writing /sys/fs/fuse/connections//max_background. If -fuse.congestionThreshold is 0, the kernel derives it as 3/4 of this value.") + mountOptions.fuseCongestionThreshold = cmdMount.Flag.Int("fuse.congestionThreshold", 0, "FUSE congestion_threshold: in-flight async request count at which the kernel marks the FUSE bdi as congested and throttles new submissions. 0 means use the default (3/4 of -fuse.maxBackground). Equivalent to writing /sys/fs/fuse/connections//congestion_threshold. The kernel silently clamps this to -fuse.maxBackground when set higher.") // macOS-specific FUSE options mountOptions.novncache = cmdMount.Flag.Bool("sys.novncache", false, "(macOS only) disable vnode name caching to avoid stale data") diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index 35bbe36df..f74964acd 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -242,11 +242,21 @@ func RunMount(option *MountOptions, umask os.FileMode) bool { fsName = "fuse" } + maxBackground := 128 + if option.fuseMaxBackground != nil && *option.fuseMaxBackground > 0 { + maxBackground = *option.fuseMaxBackground + } + congestionThreshold := 0 + if option.fuseCongestionThreshold != nil && *option.fuseCongestionThreshold > 0 { + congestionThreshold = *option.fuseCongestionThreshold + } + // mount fuse fuseMountOptions := &fuse.MountOptions{ AllowOther: *option.allowOthers, Options: option.extraOptions, - MaxBackground: 128, + MaxBackground: maxBackground, + CongestionThreshold: congestionThreshold, MaxWrite: 1024 * 1024 * 2, MaxReadAhead: 1024 * 1024 * 2, IgnoreSecurityLabels: false,