Re: [PATCH v2 02/21] fuse: prepare for passthrough of inode operations
Amir Goldstein <[email protected]> Sat, 16 May 2026 18:11:37 +0200
| Newsgroups | org.kernel.vger.linux-unionfs,dev.linux.lists.fuse-devel |
|---|---|
| Message-ID | <CAOQ4uxhyZU_6jbv8kY8od_SgG9yQ6aX+KcB2c1um4DajJdSPqA@mail.gmail.com> |
On Sat, May 16, 2026 at 3:34 AM Joanne Koong <[email protected]> wrote: > > On Fri, May 15, 2026 at 5:52 PM Joanne Koong <[email protected]> wrote: > > > > From: Amir Goldstein <[email protected]> > > > > So far, fuse passthrough was implemented for read/write/splice/mmap > > operations for regular files opened with FOPEN_PASSTHROUGH. > > > > A backing file is attached to a fuse inode, but only for as long as > > there are FOPEN_PASSTHROUGH files opened on this inode. > > > > We would like to attach a backing file to fuse inode also without an > > open file to allow passthrough of some inode operations. > > > > Add field ops_mask to the input argument of FUSE_DEV_IOC_BACKING_OPEN > > ioctl to declare the operations that would passthrough to the backing > > file once it has been attached to the fuse inode on lookup. > > > > Setting the FUSE_READ/FUSE_WRITE operations in the ops_mask is not > > required because those operations are implied by FOPEN_PASSTHROUGH. > > > > When setting operations other than FUSE_READ/FUSE_WRITE in ops_mask, > > non-regular backing files are allowed, so we need to verify when > > attaching a backing file to a fuse inode, that their file types match. > > > > For simplification of inode attribute caching, for now, require a > > filesystem with FUSE_PASSTHROUGH_INO (one-to-one mapping from fuse inode > > to backing inode) for setting up passthrough of any inode operations. > > We may consider relaxing this requirement for some inode operations > > in the future. > > > > Reviewed-by: Joanne Koong <[email protected]> > > Signed-off-by: Amir Goldstein <[email protected]> > > --- > > fs/fuse/backing.c | 13 ++++++++++--- > > fs/fuse/fuse_i.h | 30 ++++++++++++++++++++++++++++++ > > fs/fuse/iomode.c | 16 ++++++++++++++++ > > include/uapi/linux/fuse.h | 9 ++++++++- > > 4 files changed, 64 insertions(+), 4 deletions(-) > > > > diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h > > index 4be9ccc5b3ff..0f1e1c1ec367 100644 > > --- a/include/uapi/linux/fuse.h > > +++ b/include/uapi/linux/fuse.h > > @@ -243,6 +243,7 @@ > > > > +#define FUSE_PASSTHROUGH_OP(op) (1ULL << ((op) - 1)) > > + > > +/* op bits for fuse_backing_map ops_mask */ > > +#define FUSE_PASSTHROUGH_OP_READ FUSE_PASSTHROUGH_OP(FUSE_READ) > > +#define FUSE_PASSTHROUGH_OP_WRITE FUSE_PASSTHROUGH_OP(FUSE_WRITE) > > Do you think we should couple the passthrough op code to the fuse > opcode so closely, instead of defining the passthrough ops separately, > eg doing something like this?: > > #define FUSE_PASSTHROUGH_READ (1 << 0) > #define FUSE_PASSTHROUGH_WRITE (1 << 1) Don't drop the _OP_ please Need it to distinguish from FUSE_PASSTHROUGH{,_INO} and we need to think if we want to format this as 32bit and extend later or start with a u64 ops_mask format from the start. > > In the (far) future when some more advanced passthrough features get > added (eg full subtree passthrough), it seems like we'd want to add a > passthrough op for that, I don't know. fuse_backing_map has flags, why would we want to put that in ops_mask. > but that wouldn't map to a fuse op. I think > there are also some fuse ops we might skip defining as passthrough ops > but are implicitly passed through (eg FUSE_STATX which is covered by > FUSE_GETATTR), This could also become the case with FUSE_CREATE{,_HANDLE} or {FUSE,FUSEX}_CREAT. TBH, the fact that some ops will never be in the mask and that some ops have a canonical bit in itself does not justify creating a different mapping. Do we also want to squeeze the mask into 32bit and leave reserved space? my intuition is to leave it u64. > so it seems more intuitive to define the passthrough > ops as describing capabilities rather than implying that it describes > what specific opcodes get passed through? hmm. I guess you have a point that it is a bit limiting to commit to this arithmetic in UAPI. My thinking behind this was ease of use with these helpers: if (!fuse_passthrough_op(file_inode(in), FUSE_READ)) but those could just as well be macros: static inline bool fuse_inode_passthrough_op(struct inode *inode, u64 opbit)... #define FUSE_PASSTHROUGH_OP(inode, opname) \ fuse_passthrough_op(inode, FUSE_PASSTHROUGH_OP_ ## opname) #define FUSE_BACKING_MAP_OP(map, opname) \ ((map)->ops_mask & FUSE_PASSTHROUGH_OP ## opname)) ... if (!FUSE_PASSTHROUGH_OP(file_inode(in), READ)) wdyt? Thanks, Amir.