Re: [PATCH v4 0/2] fuse: allow parallel direct writes for passthrough
Amir Goldstein <[email protected]> Sat, 1 Aug 2026 21:41:11 +0200
| Newsgroups | dev.linux.lists.fuse-devel,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAOQ4uxhHx5kHT0PfyZ+yb1Y2s0LS6ph-jQ3n66w9Zw13v-5L9Q@mail.gmail.com> |
On Sun, Jul 26, 2026 at 3:59=E2=80=AFAM Russ Fellows <[email protected]= m> wrote: > > This is v4, about six weeks after v3 [1] -- apologies for the delay. > Thanks to Amir Goldstein for the detailed review of v3 and for the > suggested patches; this revision implements that feedback. The v3 > thread [1] has the full context and Amir's comments. > > The series is also available at: > https://github.com/russfellows/linux-fuse-passthrough-patches > > FUSE passthrough writes are fully serialised on the inode lock, even when > the server advertises FOPEN_PARALLEL_DIRECT_WRITES and the write is a > direct, non-append, within-EOF overwrite. Native FUSE direct-IO writes > already take a shared lock in that case; there is no reason passthrough > cannot do the same. With a passthrough backing file on XFS, this is the > difference between serialised and fully parallel 4K random-write O_DIRECT > throughput. > > Patch 1 stops fuse_file_io_open() from stripping > FOPEN_PARALLEL_DIRECT_WRITES on passthrough opens (which bypass the page > cache without FOPEN_DIRECT_IO). Patch 2 lets fuse_passthrough_write_iter= () > take the shared lock for eligible writes by sharing the existing direct-I= O > write-lock helper rather than duplicating it. > > Rebased onto v6.18.39 (LTS). Hi Russ, This version looks good and very well tested. Please add Reviewed-by: Amir Goldstein <[email protected]> to both patches. The only thing is that your patches need to apply to the current upstream master branch not to an LTS kernel. Kernel patches always need to be merged upstream and only then backported to LTS kernels. The merge conflicts with master are minor, but please rebase and test on ma= ster. With that done, I hope that Miklos will be able to include v5 in 7.3 PR aft= er he gets back from vacation. Thanks, Amir. > > Changes since v3: > - Patch 1: keep only the FOPEN_IOMODE_CACHED() helper (drop the > IS_DIRECT / IS_PASSTHROUGH macros, which described how I/O is performe= d > rather than the ff->iomode state and were misleading); fold the > O_DIRECT/fcntl note into the FOPEN_PARALLEL_DIRECT_WRITES comment; and > simplify fuse_file_io_open() so a pure direct-IO open needs no early > return. (Per Amir's review and suggested diff.) > - Patch 2: instead of duplicating fuse_dio_lock() into passthrough.c, > generalise it: fuse_io_wr_exclusive_lock() now also handles passthroug= h, > the uncached-io refcount is factored into fuse_parallel_dio_start/end(= ) > (no-ops for passthrough's permanent uncached iomode), and > fuse_dio_lock()/fuse_dio_unlock() are renamed fuse_io_wr_lock()/ > fuse_io_wr_unlock() and shared by both write paths. (Per Amir's revie= w > and suggested diff.) > > Testing (fstests / xfstests) > ---------------------------- > Run with the libfuse passthrough_hp server under xfstests (FSTYP=3Dfuse), > './check -fuse -g quick' (642 tests), on v6.18.39, backing XFS on a > RAM-backed null_blk device. An unpatched v6.18.39 baseline was captured > first, then the same tree with this series applied; results were diffed t= o > isolate any patch-induced change. Two server configs were exercised, as > suggested by Amir: > > passthrough (default): unpatched 25 failed / patched 25 failed > passthrough --direct-io: unpatched 27 failed / patched 27 failed > > In both configs the failing set is identical with and without the series > (the --direct-io set is the default set plus generic/355 and generic/362)= . > Every failure is pre-existing on the unpatched kernel and is a known > passthrough_hp / fuse limitation (permission/ACL/atime/mmap-coherency > tests), unrelated to this change: > > =3D> zero regressions introduced by the series in either config. > > No kernel warnings, lockdep reports, or splats were observed in any run. > > Performance > ----------- > Custom FUSE passthrough daemon advertising FOPEN_PASSTHROUGH | > FOPEN_PARALLEL_DIRECT_WRITES, XFS on a RAM-backed null_blk device, kernel > v6.18.39. fio 4K random write, O_DIRECT, libaio, iodepth=3D64, single sh= ared > file: > > numjobs | unpatched (IOPS) | patched (IOPS) > --------|------------------|--------------- > 1 | 352,000 | 352,000 > 2 | 440,000 | 648,000 > 3 | 429,000 | 951,000 > 4 | 423,000 | 987,000 > > Unpatched write throughput is flat regardless of job count (the exclusive > inode lock serialises all writers to the file); with the series it scales > with concurrency, ~2.3x at 4 jobs, up to the backing device ceiling. > Single-job is unchanged (no lock contention), and 4K random *read* > throughput is unchanged (~1.37M IOPS with and without the series), since > reads never took the exclusive lock. > > [1] v3: https://lore.kernel.org/all/20260616231325.16788-1-russ.fellows@g= mail.com/ > > Russ Fellows (2): > fuse: preserve FOPEN_PARALLEL_DIRECT_WRITES for passthrough opens > fuse: allow parallel direct writes in passthrough write_iter > > fs/fuse/file.c | 53 ++++++++++++++++++++++++++++++++++--------- > fs/fuse/fuse_i.h | 2 ++ > fs/fuse/iomode.c | 23 ++++++++++--------- > fs/fuse/passthrough.c | 6 ++--- > 4 files changed, 59 insertions(+), 25 deletions(-) > > -- > 2.51.0