Re: [PATCH v2 19/21] fuse: add passthrough setattr
Amir Goldstein <[email protected]> Sun, 17 May 2026 00:29:09 +0200
| Newsgroups | org.kernel.vger.linux-unionfs,dev.linux.lists.fuse-devel |
|---|---|
| Message-ID | <CAOQ4uxgxXMYjptBMggikrEfnhKmdGKxEauD4waT8JotKtgYs-A@mail.gmail.com> |
On Sat, May 16, 2026 at 2:53 AM Joanne Koong <[email protected]> wrote: > > Add passthrough setattr which sets attributes directly on the backing > inode through backing_inode_setattr() instead of sending FUSE_SETATTR to > the server. > > Passthrough setattr is checked before the > handle_killpriv/handle_killpriv_v2 suid/sgid stripping because the > stripping is handled natively by notify_change() on the backing inode. > > Signed-off-by: Joanne Koong <[email protected]> Reviewed-by: Amir Goldstein <[email protected]> > --- > fs/fuse/dir.c | 3 +++ > fs/fuse/fuse_i.h | 3 ++- > fs/fuse/passthrough.c | 28 ++++++++++++++++++++++++++++ > include/uapi/linux/fuse.h | 1 + > 4 files changed, 34 insertions(+), 1 deletion(-) > > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c > index 4c7e3e1604af..b67b3b334e69 100644 > --- a/fs/fuse/dir.c > +++ b/fs/fuse/dir.c > @@ -2506,6 +2506,9 @@ static int fuse_setattr(struct mnt_idmap *idmap, struct dentry *entry, > if (!fuse_allow_current_process(get_fuse_conn(inode))) > return -EACCES; > > + if (fuse_passthrough_op(inode, FUSE_SETATTR)) > + return fuse_passthrough_setattr(entry, attr); > + > if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { > attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | > ATTR_MODE); > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index 89c9333e9702..0d978a9837a0 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -1279,7 +1279,7 @@ ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from); > > /* Inode passthrough operations for backing file attached to inode */ > #define FUSE_PASSTHROUGH_INODE_OPS \ > - (FUSE_PASSTHROUGH_OP_GETATTR) > + (FUSE_PASSTHROUGH_OP_GETATTR | FUSE_PASSTHROUGH_OP_SETATTR) > > #define FUSE_BACKING_MAP_OP(map, op) \ > ((map)->ops_mask & FUSE_PASSTHROUGH_OP(op)) > @@ -1367,6 +1367,7 @@ static inline bool fuse_passthrough_op(struct inode *inode, enum fuse_opcode op) > > int fuse_passthrough_getattr(struct inode *inode, struct kstat *stat, > u32 request_mask, unsigned int flags); > +int fuse_passthrough_setattr(struct dentry *entry, struct iattr *attr); > > static inline bool fuse_use_entry2(struct fuse_conn *fc) > { > diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c > index ae0137caa06d..c083ab68537e 100644 > --- a/fs/fuse/passthrough.c > +++ b/fs/fuse/passthrough.c > @@ -9,6 +9,8 @@ > > #include <linux/file.h> > #include <linux/backing-file.h> > +#include <linux/backing-inode.h> > +#include <linux/posix_acl.h> > #include <linux/splice.h> > > static void fuse_file_accessed(struct file *file) > @@ -275,3 +277,29 @@ int fuse_passthrough_getattr(struct inode *inode, struct kstat *stat, > > return 0; > } > + > +int fuse_passthrough_setattr(struct dentry *entry, struct iattr *attr) > +{ > + struct inode *inode = d_inode(entry); > + struct fuse_conn *fc = get_fuse_conn(inode); > + struct fuse_inode *fi = get_fuse_inode(inode); > + struct fuse_backing *fb = fuse_inode_backing(fi); > + struct path path; > + int err; > + > + err = setattr_prepare(&nop_mnt_idmap, entry, attr); > + if (err) > + return err; > + > + path.mnt = fb->file->f_path.mnt; > + path.dentry = fb->file->f_path.dentry; > + > + err = backing_inode_setattr(entry, &path, attr, fb->cred); > + if (err) > + return err; > + > + if (fc->posix_acl) > + forget_all_cached_acls(inode); > + > + return 0; > +} > diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h > index 3963631558f9..040fee549bb9 100644 > --- a/include/uapi/linux/fuse.h > +++ b/include/uapi/linux/fuse.h > @@ -1158,6 +1158,7 @@ struct fuse_backing_map { > #define FUSE_PASSTHROUGH_OP_WRITE FUSE_PASSTHROUGH_OP(FUSE_WRITE) > #define FUSE_PASSTHROUGH_OP_READDIR FUSE_PASSTHROUGH_OP(FUSE_READDIR) > #define FUSE_PASSTHROUGH_OP_GETATTR FUSE_PASSTHROUGH_OP(FUSE_GETATTR) > +#define FUSE_PASSTHROUGH_OP_SETATTR FUSE_PASSTHROUGH_OP(FUSE_SETATTR) > > /* Device ioctls: */ > #define FUSE_DEV_IOC_MAGIC 229 > -- > 2.52.0 >