[PATCH v2 0/2] fuse: fix passthrough parallel direct writes with a minimal series

From: Russ Fellows

Date: Mon Jun 15 2026 - 21:45:29 EST


From: Russ Fellows <rfellows@xxxxxxxxxx>

This series contains the current minimal submit-ready fix for passthrough write
parallelism.

The first patch preserves FOPEN_PARALLEL_DIRECT_WRITES for passthrough opens.
Without that, fuse_file_io_open() strips the flag before passthrough writes see
it, so the kernel never reaches the shared-lock path.

The second patch keeps the lock decision local to passthrough.c and allows
shared inode locking only for safe direct overwrite writes. Append writes,
buffered writes, and writes that may extend EOF remain serialized.

This intentionally replaces the older broader patch direction. The current
minimal series does not export fuse_dio_lock()/fuse_dio_unlock() from file.c,
does not add declarations to fuse_i.h, and does not include the separate
iocachectr/fi->lock cleanup work.

Regarding fuse_passthrough_end_write() safety: the shared lock is only taken
for within-EOF direct overwrites, where i_size does not change. In that case
fuse_passthrough_end_write() -> fuse_write_update_attr() only updates mtime/
ctime, which is safe under a shared inode lock. Past-EOF writes still take
the exclusive lock, so i_size updates are always serialized correctly.

Validated on kernel 6.17.13-p4min with fio 4K random direct writes on a FUSE
passthrough mount backed by XFS on a RAM-backed null_blk device:

numjobs | FUSE IOPS
--------|----------
1 | 481,837
2 | 931,883
4 | 1,533,058
8 | 1,730,477

Raw XFS on the same device at numjobs=8: 1,693,406 IOPS.

Changes since v1:
- Removed use of fuse_dio_lock()/fuse_dio_unlock() from file.c; the lock
decision is now self-contained in passthrough.c using inode_lock_shared()
and inode_unlock_shared() directly.
- Added explicit IOCB_DIRECT check: parallel locking is only allowed for
direct I/O, preventing accidental shared locking on buffered writes.
- Added explicit IOCB_APPEND check: append writes always serialize.
- Added explicit past-EOF check: writes that extend i_size always serialize.
- Removed all symbol exports from file.c (fuse_dio_lock, fuse_dio_unlock).
- Removed all declarations added to fuse_i.h.
- Split into two patches: iomode.c flag preservation as a prerequisite
(patch 1) and passthrough.c locking logic as the main change (patch 2).

Russ Fellows (2):
fuse: preserve FOPEN_PARALLEL_DIRECT_WRITES for passthrough opens
fuse: allow parallel direct writes in passthrough write_iter

fs/fuse/iomode.c | 7 +++++--
fs/fuse/passthrough.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 49 insertions(+), 4 deletions(-)

--
2.51.0