On Wed, Oct 14, 2026 at 11:26 AM Miklos Szeredi <[email protected]> wrote:
>
> [Restored Cc list]
>
> On Thu, Oct 8, 2026 at 1:36 PM <[email protected]> wrote:
>
> > > diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c
> > > index e9ab1aea34e27..040817ad76e94 100644
> > > --- a/fs/fuse/passthrough.c
> > > +++ b/fs/fuse/passthrough.c
> > [ ... ]
> > > @@ -74,10 +73,13 @@ ssize_t fuse_passthrough_write_iter(struct kiocb 
> > > *iocb,
> > >       if (!count)
> > >               return 0;
> > >
> > > -     inode_lock(inode);
> > > +     guard(rwsem_write)(&inode->i_rwsem);
> > > +
> > > +     if (!backing_file)
> > > +             return fuse_ext_map_write_iter(iocb, iter);
> >
> > [Severity: High]
> > Does this introduce an ABBA deadlock between pipe_lock and the inode lock?
> >
> > For normal passthrough, fuse_passthrough_splice_write() acquires the inode
> > lock first, and then calls backing_file_splice_write(), which ultimately
> > acquires pipe_lock() via the backing file's splice_write callback.
> >
> > However, the EXTMAP DAX path added below for splice_write() directly calls
> > iter_file_splice_write(), which acquires pipe_lock() first. That function 
> > then
> > invokes fuse_passthrough_write_iter() where the inode lock is acquired here
> > via guard(rwsem_write).
>
> Brute force fix would be to prevent mixing plain and ext-map
> passthrough.   Might be a good idea anyway.

You mean not mix on the same fs?
Make sense. So another init flag?

>
> However I'm thinking about why fuse_passthrough_splice_write() needs
> to lock the fuse inode.
>
> Tracing back through git history that inode lock really originates
> from commit 2a92e07edc5e ("ovl: add ovl_write_iter()"), which added
> stacked writes.  That was copied into ovl_splice_write() by commit
> 9b91b6b019fd ("ovl: fix deadlock in splice write").   Which was then
> added to fuse_passthrough_splice_write() by commit 5ca73468612d
> ("fuse: implement splice read/write passthrough").
>
> Even for the original ovl code, I don't see an explanation for the
> inode lock, but I'm probably missing something.
>
> Amir, any thoughts about why that inode_lock() could be necessary?
>

It is my understanding that the inode lock is used to synchronize the
copy of size/mtime from the backing inode to the ovl inode by
ovl_file_end_write().

We don't have this model in fuse passthrough (yet).
I think that fuse_passthrough_end_write() do not need to be synchronized
so could probably lose the inode lock in fuse passthrough.
If we even implement the inode passthrough mode where the
backing inode attributes are the source of truth, it will surely be
a mode that does not mix ext-map.

Thanks,
Amir.

Reply via email to