Add sync_fs() to service FUSE_SYNCFS#692
Open
edmc-ss wants to merge 1 commit into
Open
Conversation
Wire up the FUSE_SYNCFS opcode (50) so a filesystem can service syncfs(2)/sync(2): a new header-only SyncFs request, an Operation variant, request parsing/dispatch, and a Filesystem::sync_fs() trait method that defaults to ENOSYS (which the kernel treats as a permanent success, matching fsync/statfs). Also add the InitFlags::FUSE_HAS_SYNCFS (1 << 43, protocol 7.46) opt-in capability. Because Init negotiation already carries the high-32 flags2 via FUSE_INIT_EXT, a server enables it by requesting it through KernelConfig::add_capabilities(); add_capabilities() returns Err when the kernel doesn't offer it, so a server can detect an unsupporting kernel and fall back. FUSE_KERNEL_MINOR_VERSION is intentionally left at 40: the kernel gates this flag on the opener's privilege rather than the negotiated minor, and it rides in flags2, so it works without claiming the intervening 7.41-7.45 features fuser doesn't implement.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for servicing
FUSE_SYNCFS— the opcode the kernel issues forsyncfs(2)/sync(2)— plus the opt-inFUSE_HAS_SYNCFSINIT capability that lets a privileged/dev/fuseserver receive it.Filesystem::sync_fs(&self, req, ino, ReplyEmpty)trait method; defaults toENOSYS, which the kernel treats as a permanent success (same convention asfsync/statfs).FUSE_SYNCFS = 50opcode, a header-onlySyncFsrequest, itsOperationvariant, and request parsing/dispatch/Display.InitFlags::FUSE_HAS_SYNCFS = 1 << 43(protocol 7.46), requested by a server viaKernelConfig::add_capabilities().Dependency on the Linux VFS fuse driver (please read)
This is the important caveat. Although the
FUSE_SYNCFSopcode has existed for a while (added for virtiofs), the in-kernel fuse driver only propagatessyncfs()/sync()to the userspace server (fc->sync_fs) for virtiofs and fuseblk mounts. A plain/dev/fuseserver never receives it today — regardless of what it advertises — because an untrusted server could stallsync()indefinitely.Consequences:
fuserservers (they already receiveFUSE_SYNCFS), and is a harmless no-op for plain servers./dev/fuseservers to receive it, the kernel needs the in-flight opt-in: a newFUSE_HAS_SYNCFSINIT flag, honored only when the server opened/dev/fusewithCAP_SYS_ADMINin the initial user namespace (the same privilege that mounting virtiofs/fuseblk already requires). That series — "fuse: allow FUSE_SYNCFS for privileged userspace servers" — is on LKML (patch, LWN summary) and not yet merged. The1 << 43bit and protocol minor 7.46 here match that patch's UAPI.Because
KernelConfig::add_capabilities(InitFlags::FUSE_HAS_SYNCFS)returnsErrwhen the running kernel doesn't offer the flag, a server can cleanly detect an unsupporting kernel and fall back (e.g. to an out-of-band flush) rather than silently never being called.Design notes
FUSE_KERNEL_MINOR_VERSIONis intentionally left at 40. The kernel gates this flag on the opener's privilege rather than the negotiated minor, and it rides in the high-32flags2(already carried viaFUSE_INIT_EXT), so it works without claiming the intervening 7.41–7.45 featuresfuserdoesn't yet implement. Happy to bump the minor if you'd prefer.SyncFsis modeled onStatFs: filesystem-wide and header-only (the wirefuse_syncfs_inis a single reservedu64padding word, so there's no argument to expose).syncfsop, which likewise repliesENOSYSwhen unimplemented.Testing
cargo test(including a newFUSE_SYNCFSparse test),cargo clippy --all-targets,cargo fmt --check, andcargo doc(with-D rustdoc::broken_intra_doc_links) all pass on Linux (aarch64, toolchain 1.85). Not exercised against a live mount, since the privileged-plain-server kernel path isn't in a shipping kernel yet (see above).