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 15/21] fuse: add passthrough support for create+open
Date: Fri, 15 May 2026 17:39:58 -0700	[thread overview]
Message-ID: <20260516004004.1455526-16-joannelkoong@gmail.com> (raw)
In-Reply-To: <20260516004004.1455526-1-joannelkoong@gmail.com>

Use the extended fuse_entry2_out reply for FUSE_CREATE and FUSE_TMPFILE
when FUSE_PASSTHROUGH_INO is enabled. If the server returns a backing
id, the newly created inode is associated with the backing file for
passthrough operations before the dentry is instantiated.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
 fs/fuse/dir.c | 43 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a11f9e4c1999..4c7e3e1604af 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -934,9 +934,12 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 	struct fuse_create_in inarg;
 	struct fuse_open_out *outopenp;
 	struct fuse_entry_out outentry;
+	struct fuse_entry2_out outentry2;
+	struct fuse_statx *sx = NULL;
 	struct fuse_inode *fi;
 	struct fuse_file *ff;
 	int epoch, err;
+	int backing_id;
 	bool trunc = flags & O_TRUNC;
 
 	/* Userspace expects S_IFREG in create mode */
@@ -957,7 +960,6 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 
 	flags &= ~O_NOCTTY;
 	memset(&inarg, 0, sizeof(inarg));
-	memset(&outentry, 0, sizeof(outentry));
 	inarg.flags = flags;
 	inarg.mode = mode;
 	inarg.umask = current_umask();
@@ -975,8 +977,15 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 	args.in_args[1].size = entry->d_name.len + 1;
 	args.in_args[1].value = entry->d_name.name;
 	args.out_numargs = 2;
-	args.out_args[0].size = sizeof(outentry);
-	args.out_args[0].value = &outentry;
+	if (fuse_use_entry2(fm->fc)) {
+		memset(&outentry2, 0, sizeof(outentry2));
+		args.out_args[0].size = sizeof(outentry2);
+		args.out_args[0].value = &outentry2;
+	} else {
+		memset(&outentry, 0, sizeof(outentry));
+		args.out_args[0].size = sizeof(outentry);
+		args.out_args[0].value = &outentry;
+	}
 	/* Store outarg for fuse_finish_open() */
 	outopenp = &ff->args->open_outarg;
 	args.out_args[1].size = sizeof(*outopenp);
@@ -991,6 +1000,8 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 	if (err)
 		goto out_free_ff;
 
+	backing_id = fuse_process_entry2(fm->fc, &outentry2, &outentry, &sx);
+
 	err = -EIO;
 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
 	    fuse_invalid_attr(&outentry.attr))
@@ -999,16 +1010,26 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 	ff->fh = outopenp->fh;
 	ff->nodeid = outentry.nodeid;
 	ff->open_flags = outopenp->open_flags;
+
+	if (backing_id < 0) {
+		err = backing_id;
+		goto out_queue_forget;
+	}
+
 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
-			  &outentry.attr, NULL, ATTR_TIMEOUT(&outentry), 0, 0);
+			  &outentry.attr, sx, ATTR_TIMEOUT(&outentry), 0, 0);
 	if (!inode) {
-		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
-		fuse_sync_release(NULL, ff, flags, false);
-		fuse_chan_queue_forget(fm->fc->chan, forget, outentry.nodeid, 1);
 		err = -ENOMEM;
-		goto out_err;
+		goto out_queue_forget;
 	}
 	kfree(forget);
+	if (backing_id) {
+		err = fuse_inode_set_passthrough(inode, backing_id);
+		if (err) {
+			iput(inode);
+			goto out_sync_release;
+		}
+	}
 	d_instantiate(entry, inode);
 	entry->d_time = epoch;
 	fuse_change_entry_timeout(entry, &outentry);
@@ -1035,6 +1056,12 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
 	kfree(forget);
 out_err:
 	return err;
+out_queue_forget:
+	fuse_chan_queue_forget(fm->fc->chan, forget, outentry.nodeid, 1);
+out_sync_release:
+	flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+	fuse_sync_release(NULL, ff, flags, false);
+	return err;
 }
 
 static int fuse_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
-- 
2.52.0


  parent reply	other threads:[~2026-05-16  0:52 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 ` Joanne Koong [this message]
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 ` [PATCH v2 19/21] fuse: add passthrough setattr Joanne Koong
2026-05-16  1:04   ` 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-16-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