Skip to content

Add FUSE_DEV_IOC_CLONE support for multi-threaded reading#421

Closed
ejc3 wants to merge 3 commits intocberner:masterfrom
ejc3:master
Closed

Add FUSE_DEV_IOC_CLONE support for multi-threaded reading#421
ejc3 wants to merge 3 commits intocberner:masterfrom
ejc3:master

Conversation

@ejc3
Copy link

@ejc3 ejc3 commented Dec 19, 2025

Summary

Add support for multi-threaded FUSE request processing using FUSE_DEV_IOC_CLONE ioctl.

This enables multiple threads to read FUSE requests in parallel from cloned file descriptors, improving throughput for high-concurrency workloads.

API

// Primary session handles INIT and runs in main thread
let session = Session::new(fs, mountpoint, &Config::default())?;

// Clone fd for additional reader threads
let cloned_fd = session.clone_fd()?;
let reader_session = Session::from_fd_initialized(fs_clone, cloned_fd, SessionACL::All);
std::thread::spawn(move || reader_session.run());

session.run()?;

Changes

  • Add Session::clone_fd() - clones the FUSE fd using FUSE_DEV_IOC_CLONE ioctl (Linux only)
  • Add Session::from_fd_initialized() - creates a session from a cloned fd that skips INIT handshake
  • Make Session::run() public for external multi-reader use
  • Add conditional handshake skip when proto_version is pre-set

Tests

Added two integration tests:

  • clone_fd_multi_reader - verifies clone_fd() creates a valid fd
  • from_fd_initialized_works - tests concurrent readers processing requests

Platform Support

clone_fd() is only available on Linux (#[cfg(target_os = "linux")]).

@cberner
Copy link
Owner

cberner commented Dec 19, 2025

Please add a test for this functionality. Also, I don't really like the idea of making channel public. I think we should find a way to hide this functionality behind mount() or something like that

@ejc3 ejc3 marked this pull request as ready for review December 20, 2025 09:20
@cberner
Copy link
Owner

cberner commented Jan 26, 2026

@stepancheg I think you're working on a similar feature. Want to take a look and lemme know how they overlap, if at all?

@stepancheg
Copy link
Contributor

I left a comment in the other thread.

@ejc3
Copy link
Author

ejc3 commented Jan 26, 2026

I left a comment in the other thread.

Hi @stepancheg, can you point me there? I might not be on that issue / pull request. Thanks!

@cberner
Copy link
Owner

cberner commented Jan 31, 2026

It's this one: #572

@ejc3
Copy link
Author

ejc3 commented Feb 1, 2026

It's this one: #572

I rebased onto main, so those changes are incorporated now.

@cberner
Copy link
Owner

cberner commented Feb 1, 2026

The approach @stepancheg described seems better to me, because it provides a simpler interface to users. Can you take a look at that and let me know if your use case requires additional functionality or lower level access?

@ejc3 ejc3 force-pushed the master branch 8 times, most recently from ffe3ad3 to 984aaff Compare February 2, 2026 01:21
@ejc3
Copy link
Author

ejc3 commented Feb 2, 2026

I rebased again. #627 won’t work as is (as mentioned) because it doesn’t support the clone fd ioctl. Otherwise, if that was added, it should work.

@stepancheg
Copy link
Contributor

#627 won’t work as is (as mentioned) because it doesn’t support the clone fd ioctl

multiple event loops can work with and without ioctl. This is how libfuse works — single thread, multiple threads shared fd, or multiple threads clone fd with ioctl.

I started without ioctl, because I presume we should make version without ioctl work first, and then add ioctl on top.

@ejc3
Copy link
Author

ejc3 commented Feb 2, 2026 via email

@stepancheg
Copy link
Contributor

I was saying that there isn’t a perf improvement if we don’t do the clone though.

It is perf improvement if filesystem implementation does something non-trivial. But not as big as with ioctl.

@ejc3 ejc3 force-pushed the master branch 2 times, most recently from 5e50391 to 49443a4 Compare February 5, 2026 05:04
ejc3 added 2 commits February 6, 2026 01:36
Replace ch.clone() (which just clones the Arc, sharing one fd) with
actual FUSE_DEV_IOC_CLONE ioctl that creates independent fds.

Without clone_fd: all threads serialize on one fd
With clone_fd: kernel distributes requests across fds (true parallelism)

- Add Channel::clone_fd() using FUSE_DEV_IOC_CLONE ioctl
- Update run() to use clone_fd() on Linux
- Fall back to ch.clone() on non-Linux (no true parallelism)
- Use existing fuse_dev_ioc_clone from ll/ioctl.rs instead of
  defining the ioctl inline
- Make clone_fd opt-in via Config.clone_fd (default false)
- Remove tests/clone_fd_test.rs (tests live in fuser-tests,
  examples/hello.rs already demonstrates the feature)
@cberner
Copy link
Owner

cberner commented Feb 6, 2026

Is this a duplicate of #636 ?

Uses a barrier that requires N threads to arrive simultaneously:
- 4 client threads lookup different files (barrier0, barrier1, etc.)
- Server's lookup() waits at barrier before responding
- Test passes only if 4 server threads handle requests concurrently

Requires FUSE_PARALLEL_DIROPS flag to allow parallel directory ops.
Uses different file names to avoid VFS dentry-level serialization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants