Linux Overlay Filesystem development
 help / color / mirror / Atom feed
From: Joanne Koong <joannelkoong@gmail.com>
To: amir73il@gmail.com, miklos@szeredi.hu
Cc: fuse-devel@lists.linux.dev, linux-unionfs@vger.kernel.org
Subject: [PATCH v2 19/21] fuse: add passthrough setattr
Date: Fri, 15 May 2026 17:40:02 -0700	[thread overview]
Message-ID: <20260516004004.1455526-20-joannelkoong@gmail.com> (raw)
In-Reply-To: <20260516004004.1455526-1-joannelkoong@gmail.com>

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 <joannelkoong@gmail.com>
---
 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


  parent reply	other threads:[~2026-05-16  0:53 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-16  0:39 [PATCH v2 00/21] fuse: extend passthrough to inode operations Joanne Koong
2026-05-16  0:39 ` [PATCH v2 01/21] fuse: introduce FUSE_PASSTHROUGH_INO mode Joanne Koong
2026-05-16  0:39 ` [PATCH v2 02/21] fuse: prepare for passthrough of inode operations Joanne Koong
2026-05-16  1:34   ` Joanne Koong
2026-05-16  0:39 ` [PATCH v2 03/21] fuse: prepare for readdir passthrough on directories Joanne Koong
2026-05-16  0:39 ` [PATCH v2 04/21] fuse: implement passthrough for readdir Joanne Koong
2026-05-16  0:39 ` [PATCH v2 05/21] fuse: prepare for long lived reference on backing file Joanne Koong
2026-05-16  0:39 ` [PATCH v2 06/21] fuse: implement passthrough for getattr/statx Joanne Koong
2026-05-16  0:39 ` [PATCH v2 07/21] fuse: prepare to setup backing inode passthrough on lookup Joanne Koong
2026-05-16  0:39 ` [PATCH v2 08/21] fuse: handle zero ops_mask in FUSE_DEV_IOC_BACKING_OPEN Joanne Koong
2026-05-16  0:39 ` [PATCH v2 09/21] fuse: handle partial io passthrough for read/write, splice, and mmap Joanne Koong
2026-05-16  0:39 ` [PATCH v2 10/21] fuse: prepare to cache statx attributes from entry replies Joanne Koong
2026-05-16  0:39 ` [PATCH v2 11/21] fuse: clean up fuse_dentry_revalidate() Joanne Koong
2026-05-16  0:39 ` [PATCH v2 12/21] fuse: add struct fuse_entry2_out and helpers for extended entry replies Joanne Koong
2026-05-16  0:39 ` [PATCH v2 13/21] fuse: add passthrough lookup Joanne Koong
2026-05-16  0:39 ` [PATCH v2 14/21] fuse: add passthrough support for entry creation Joanne Koong
2026-05-16  0:39 ` [PATCH v2 15/21] fuse: add passthrough support for create+open Joanne Koong
2026-05-16  0:39 ` [PATCH v2 16/21] fuse: allow backing_id=0 in open to inherit inode's backing file Joanne Koong
2026-05-16  0:40 ` [PATCH v2 17/21] backing-inode: add backing_inode_copyattr() Joanne Koong
2026-05-16  0:40 ` [PATCH v2 18/21] backing-inode: add backing_inode_setattr() Joanne Koong
2026-05-16  0:40 ` Joanne Koong [this message]
2026-05-16  1:04   ` [PATCH v2 19/21] fuse: add passthrough setattr Joanne Koong
2026-05-16  0:40 ` [PATCH v2 20/21] fuse: use passthrough getattr in setattr suid/sgid handling Joanne Koong
2026-05-16  1:20   ` Joanne Koong
2026-05-16  0:40 ` [PATCH v2 21/21] docs: fuse: document extended passthrough (FUSE_PASSTHROUGH_INO) Joanne Koong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260516004004.1455526-20-joannelkoong@gmail.com \
    --to=joannelkoong@gmail.com \
    --cc=amir73il@gmail.com \
    --cc=fuse-devel@lists.linux.dev \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox