Some work on FUSE#306
Draft
cgwalters wants to merge 4 commits into
Draft
Conversation
fuser 0.17 is needed to support multithreaded FUSE sessions: the new API requires `Filesystem: Send + Sync + 'static`, which forces proper Arc-based ownership of the filesystem state and makes it possible to safely hand the implementation to multiple worker threads. The breaking API changes and how they are addressed: - `&self` instead of `&mut self` on all trait methods: the only mutable state (open file handles) is now protected by a Mutex. - New newtypes (INodeNo, FileHandle, LockOwner, Generation) and bitflags (OpenFlags, FopenFlags) — updated at call sites. - readdir/read offsets changed from i64 to u64. - Session::from_fd now takes SessionACL + Config separately. - Session::run() is no longer public; replaced by spawn().join(). - reply.error() takes fuser::Errno instead of raw i32. To satisfy the `'static` bound, serve_tree_fuse() now takes `Arc<FileSystem>` and `Arc<Repository>`. A pre-built flat Vec<InodeData> (indexed by ino-1) replaces the old HashMap<Ino, InodeRef<'a>>, removing the lifetime that was incompatible with `'static`. An InodeLookup index (path→ino for dirs, LeafId→ino for leaves) handles child ino resolution without raw pointers. Assisted-by: OpenCode (claude-sonnet-4-6) Signed-off-by: Colin Walters <walters@verbum.org>
Wire the composefs-fuse crate into cfsctl behind a new `fuse` cargo
feature (on by default) and expose it through both the command line and
the varlink RPC API, with an integration test exercising the FUSE mount
end to end.
CLI surface:
- `cfsctl fuse-serve <image> <mountpoint>` serves an EROFS composefs
image over FUSE from a file on disk.
- `cfsctl oci mount --fuse[=<opts>]` FUSE-serves an OCI image's EROFS
instead of doing a kernel composefs mount, so it works without
fs-verity on the backing store. `--fuse=passthrough` opts into
kernel-bypass reads (Linux 6.9+). Options are parsed via a small
FuseOptions FromStr so the surface can grow without new flags.
Varlink surface:
- `org.composefs.Repository.FuseServe` and `org.composefs.Oci.OciFuseMount`
let a client drive FUSE mounts over the RPC socket. Both take a
`wait` parameter: with `wait=true` the call blocks for the session;
with `wait=false` the FUSE session is detached into a background task
and the call returns once the mount is registered, so a caller can
mount and then go on to use the filesystem.
The privileged_fuse_dumpfile_roundtrip integration test spawns
`cfsctl fuse-serve` as a subprocess, polls for mount readiness via st_dev
change, reads external files directly, and compares the dumpfile produced
by `cfsctl create-dumpfile` over the FUSE mount against the expected
output from write_dumpfile, asserting the FUSE implementation reports
every piece of metadata the dumpfile format captures. Uses
similar_asserts for readable diffs on mismatch.
Assisted-by: OpenCode (claude-sonnet-4-6)
Signed-off-by: Colin Walters <walters@verbum.org>
Implement readdirplus (combined readdir + lookup in one round-trip), no-op forget (inode table is static for session lifetime), and FOPEN_KEEP_CACHE on open replies. Serve with one thread per logical CPU using FUSE_DEV_IOC_CLONE (clone_fd=true) so each worker gets its own /dev/fuse fd, eliminating per-request channel lock contention. Arc<OwnedFd> allows read() to clone the handle and drop the mutex before calling pread, so concurrent reads on the same file don't serialise. Add FUSE passthrough support (Linux 6.9+): when FuseConfig::passthrough is true and the kernel advertises FUSE_PASSTHROUGH, external file reads are routed directly in-kernel to the repository object fds. Opt-in via FuseConfig because passthrough requires root and a non-tmpfs backing filesystem. Assisted-by: OpenCode (claude-sonnet-4-6) Signed-off-by: Colin Walters <walters@verbum.org>
Demonstrates composefs-oci as a container storage layer end to end, the same way podman + containers-storage work: pull a real image into a composefs repo (content-addressed, deduped, fs-verity protected), mount its EROFS image in-kernel as a read-only container rootfs, and run a command inside it with crun. There is no daemon and no FUSE. `cfsctl oci mount` does a synchronous fsmount/move_mount and returns, leaving a normal kernel mount at a host path; crun then bind-mounts that path into the container's mount namespace and pivots into it — the path-based handoff podman uses. A MountGuard lazily detaches the mount on drop, so nothing leaks even if crun fails. Runs privileged in a bcvk ephemeral VM via the existing require_privileged harness, so it gets real root and CAP_SYS_ADMIN. The repo lives on a loop-mounted ext4+verity filesystem (not the VM's tmpfs /var) so the secure in-kernel composefs mount works without --insecure — faithful to the real fs-verity-protected story. Fedora is used as the image because (unlike busybox) it ships the /proc, /sys and /dev mountpoint directories crun needs on a read-only rootfs. The runtime spec's env/cwd are synthesized from the image config. To prove the container actually runs on composefs (rather than just that some process ran), the container command is `findmnt -J /` and the test parses that output from inside the container, asserting the root is an overlay mount whose source is `composefs:<image-id>` and whose options carry `verity=require` — the unambiguous signature of a verity-backed composefs rootfs. crun is added to the test image dependencies. Assisted-by: OpenCode (claude-sonnet-4-6) Signed-off-by: Colin Walters <walters@verbum.org>
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.
See commits for details.