Re: [PATCH v2 21/21] docs: fuse: document extended passthrough (FUSE_PASSTHROUGH_INO)

Joanne Koong <[email protected]> Mon, 18 May 2026 14:23:02 -0700
Newsgroups org.kernel.vger.linux-unionfs,dev.linux.lists.fuse-devel
Message-ID <CAJnrk1ZD8hQX1jrnRzQ3aDTsihvDC5g9fV-NDG1V53gE7TL_ig@mail.gmail.com>
On Sat, May 16, 2026 at 1:59 PM Amir Goldstein <[email protected]> wrote:
>
> On Sat, May 16, 2026 at 8:23 PM Amir Goldstein <[email protected]> wrote:
> >
> > On Sat, May 16, 2026 at 2:53 AM Joanne Koong <[email protected]> wrote:
> > >
> > > Add section about extended passthrough (FUSE_PASSTHROUGH_INO) mode.
> > >
> > > Signed-off-by: Joanne Koong <[email protected]>
> > > ---
> > >  .../filesystems/fuse/fuse-passthrough.rst     | 126 ++++++++++++++++++
> > >  1 file changed, 126 insertions(+)
> > >
> > > diff --git a/Documentation/filesystems/fuse/fuse-passthrough.rst b/Documentation/filesystems/fuse/fuse-passthrough.rst
> > > index 2b0e7c2da54a..751d27c6fc5c 100644
> > > --- a/Documentation/filesystems/fuse/fuse-passthrough.rst
> > > +++ b/Documentation/filesystems/fuse/fuse-passthrough.rst
> > > @@ -25,6 +25,11 @@ operations.
> > >
> > > +Extended Passthrough (FUSE_PASSTHROUGH_INO)
> > > +============================================
> > > +
> > > +``FUSE_PASSTHROUGH_INO`` is a stricter variant of ``FUSE_PASSTHROUGH`` in
> > > +which the backing file inode number must match the fuse inode number, enforcing
> > > +a one-to-one mapping. The kernel offers this flag during ``FUSE_INIT`` if
> > > +``CONFIG_FUSE_PASSTHROUGH`` is enabled and the architecture has 64-bit
> > > +``ino_t``. The daemon accepts by returning it back in the init reply.
> >
> > IIUC, ino_t is now always 64-bit.

When Jeff's changes for u64 inode->i_ino land in the fuse tree, I'll
get rid of this and update the 1st patch accordingly.

> >
> > > +
> > > +IO Mode State Machine
> > > +---------------------
> > > +
> > > +The ``iocachectr`` field in ``struct fuse_inode`` prevents conflicting access
> > > +modes on the same inode (page-cache I/O and passthrough I/O cannot coexist)::
> > > +
> > > +    iocachectr > 0    Cached mode
> > > +    iocachectr == 0   Idle. No files open, no passthrough
> >
> > More accurately, no open files in caching or passthough.
> > files open with FOPEN_DIRECT_IO may exist and they
> > do not deny entering either caching or passthrough iomode.

Good point, I'll update this to be more precise.

> >
> > > +    iocachectr < 0    Uncached/passthrough mode
> > > +
> > > +Each open file in passthrough mode holds one reference (``iocachectr--``).
> > > +The inode-level passthrough setup holds one additional long-lived reference
> > > +if the backing has inode ops (getattr/setattr). This long-lived reference is
> > > +released on inode eviction.
> > > +
> > > +Cached mode and passthrough mode are mutually exclusive. Attempting either
> > > +while the other is active returns ``-ETXTBSY``.
> > > +
> > > +For directories, the same mechanism arbitrates between cached readdir
> > > +(``FOPEN_CACHE_DIR``) and passthrough readdir. A directory opened without
> > > +``FOPEN_CACHE_DIR`` and without ``FOPEN_PASSTHROUGH`` is treated as direct I/O
> > > +and does not affect io mode.
> > > +
> > > +Things to note
> > > +--------------
> > > +
> > > +- ``FUSE_PASSTHROUGH_INO`` requires 64-bit ``ino_t``.
> >
> > Not relevant I think.
> >
> > > +- Readdirplus does not set up inode passthrough. Inodes created via readdirplus
> > > +  use normal FUSE operations until a fresh lookup occurs.
> > > +- An inode's backing association is set once and cannot be changed.
> > > +- Passthrough and cached I/O cannot coexist on the same inode.
> > > +- If any inode operations are passed through, this means all opened files need
> > > +  to set the ``FOPEN_PASSTHROUGH`` flag in the open response, even if reads
> > > +  and writes are not passed through. If reads and writes are not passed
> > > +  through, they will go directly to the daemon.
> >
> > I had not considered this.
> > Setting OP_GETATTR/SETATTR in LOOKUP without any OP_RW bits
> > and then requiring that the server open files with FOPEN_PASSTHROUGH
> > with the backing_id sounds strange -
> > I understand why it was done this way, but for users this could be perplexing.
> >
> > The thing is that if the server is only doing GETATTR passthrough there is not
> > really a reason to deny open file in caching mode (I think?).
> >
> > The limitation that requires FOPEN_PASSTHROUGH is encoded in
> > fuse_file_cached_io_open()
> >     fuse_is_io_cache_wait()
> >         !fuse_inode_backing()
> >
> > We have two options.
> >
> > Either we decide that server passing through GETATTR and opening
> > files in caching mode is not interesting to support (for now) and then just
> > maybe we need to better document the reason that server needs to
> > use FOPEN_PASSTHROUGH despite not doing io passthrough.
> >
> > Or we relax the limitation w.r.t cached io mode, something like this
> > (completely untested most likely broken based or earlier review
> > suggestion regarding fuse_passthrough_op):
> >
> > Thanks,
> > Amir.
> >
> > diff --git a/fs/fuse/iomode.c b/fs/fuse/iomode.c
> > index c5f3e2201c6ab..7c33e7a974f6c 100644
> > --- a/fs/fuse/iomode.c
> > +++ b/fs/fuse/iomode.c
> > @@ -20,7 +20,8 @@ static inline bool fuse_is_io_cache_wait(struct inode *inode)
> >         struct fuse_inode *fi = get_fuse_inode(inode);
> >
> >         return S_ISREG(inode->i_mode) &&
> > -               READ_ONCE(fi->iocachectr) < 0 && !fuse_inode_backing(fi);
> > +               READ_ONCE(fi->iocachectr) < 0 &&
> > +               !fuse_passthrough_op(inode, FUSE_PASSTHROUGH_RW_OPS);
> >  }
>
> Obviously, this was naive and not close to enough, because
> fuse_inode_set_passthrough() still takes the negative iocachectr
> refcount.
>
> Please ignore this. Supporting caching iomode and GETATTR
> passthrough is left for a future exercise, if anyone is ever interested.

Sounds good, I will continue to leave this unsupported for now.

Thanks for reviewing these patches.
>
> Thanks,
> Amir.