diff mbox series

[v14,07/12] fuse: pass optional backing_id in struct fuse_open_out

Message ID 20231016160902.2316986-8-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show
Series FUSE passthrough for file io | expand

Commit Message

Amir Goldstein Oct. 16, 2023, 4:08 p.m. UTC
propagae fuse_open_out arguments up to fuse_finish_open() with optional
backing_id member.

This will be used for setting up passthrough to backing file on open
reply with FOPEN_PASSTHROUGH flag and on zero backing_id.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/fuse/cuse.c            |  3 ++-
 fs/fuse/dir.c             |  2 +-
 fs/fuse/file.c            | 23 +++++++++++++----------
 fs/fuse/fuse_i.h          |  8 +++++---
 fs/fuse/ioctl.c           |  3 ++-
 include/uapi/linux/fuse.h |  2 +-
 6 files changed, 24 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 91e89e68177e..050e97976e1f 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -115,6 +115,7 @@  static int cuse_open(struct inode *inode, struct file *file)
 {
 	dev_t devt = inode->i_cdev->dev;
 	struct cuse_conn *cc = NULL, *pos;
+	struct fuse_open_out outarg;
 	int rc;
 
 	/* look up and get the connection */
@@ -135,7 +136,7 @@  static int cuse_open(struct inode *inode, struct file *file)
 	 * Generic permission check is already done against the chrdev
 	 * file, proceed to open.
 	 */
-	rc = fuse_do_open(&cc->fm, 0, file, 0);
+	rc = fuse_do_open(&cc->fm, 0, file, 0, &outarg);
 	if (rc)
 		fuse_conn_put(&cc->fc);
 	return rc;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index d707e6987da9..f2adcb30852d 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -698,7 +698,7 @@  static int fuse_create_open(struct inode *dir, struct dentry *entry,
 		fuse_sync_release(fi, ff, flags);
 	} else {
 		file->private_data = ff;
-		fuse_finish_open(inode, file);
+		fuse_finish_open(inode, file, &outopen);
 		if (fm->fc->atomic_o_trunc && trunc)
 			truncate_pagecache(inode, 0);
 		else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 1cdb6327511e..b0a6189f7662 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -126,7 +126,8 @@  static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir)
 }
 
 struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
-				 unsigned int open_flags, bool isdir)
+				 unsigned int open_flags, bool isdir,
+				 struct fuse_open_out *outargp)
 {
 	struct fuse_conn *fc = fm->fc;
 	struct fuse_file *ff;
@@ -140,13 +141,12 @@  struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
 	/* Default for no-open */
 	ff->open_flags = FOPEN_KEEP_CACHE | (isdir ? FOPEN_CACHE_DIR : 0);
 	if (isdir ? !fc->no_opendir : !fc->no_open) {
-		struct fuse_open_out outarg;
 		int err;
 
-		err = fuse_send_open(fm, nodeid, open_flags, opcode, &outarg);
+		err = fuse_send_open(fm, nodeid, open_flags, opcode, outargp);
 		if (!err) {
-			ff->fh = outarg.fh;
-			ff->open_flags = outarg.open_flags;
+			ff->fh = outargp->fh;
+			ff->open_flags = outargp->open_flags;
 
 		} else if (err != -ENOSYS) {
 			fuse_file_free(ff);
@@ -168,9 +168,10 @@  struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
 }
 
 int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
-		 bool isdir)
+		 bool isdir, struct fuse_open_out *outargp)
 {
-	struct fuse_file *ff = fuse_file_open(fm, nodeid, file->f_flags, isdir);
+	struct fuse_file *ff = fuse_file_open(fm, nodeid, file->f_flags, isdir,
+					      outargp);
 
 	if (!IS_ERR(ff))
 		file->private_data = ff;
@@ -194,7 +195,8 @@  static void fuse_link_write_file(struct file *file)
 	spin_unlock(&fi->lock);
 }
 
-void fuse_finish_open(struct inode *inode, struct file *file)
+void fuse_finish_open(struct inode *inode, struct file *file,
+		      struct fuse_open_out *outargp)
 {
 	struct fuse_file *ff = file->private_data;
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -222,6 +224,7 @@  int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
 {
 	struct fuse_mount *fm = get_fuse_mount(inode);
 	struct fuse_conn *fc = fm->fc;
+	struct fuse_open_out outarg;
 	int err;
 	bool is_wb_truncate = (file->f_flags & O_TRUNC) &&
 			  fc->atomic_o_trunc &&
@@ -249,9 +252,9 @@  int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
 	if (is_wb_truncate || dax_truncate)
 		fuse_set_nowrite(inode);
 
-	err = fuse_do_open(fm, get_node_id(inode), file, isdir);
+	err = fuse_do_open(fm, get_node_id(inode), file, isdir, &outarg);
 	if (!err)
-		fuse_finish_open(inode, file);
+		fuse_finish_open(inode, file, &outarg);
 
 	if (is_wb_truncate || dax_truncate)
 		fuse_release_nowrite(inode);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 5be51358542e..233344773d29 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -1038,7 +1038,8 @@  int fuse_open_common(struct inode *inode, struct file *file, bool isdir);
 
 struct fuse_file *fuse_file_alloc(struct fuse_mount *fm);
 void fuse_file_free(struct fuse_file *ff);
-void fuse_finish_open(struct inode *inode, struct file *file);
+void fuse_finish_open(struct inode *inode, struct file *file,
+		      struct fuse_open_out *outargp);
 
 void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff,
 		       unsigned int flags);
@@ -1259,7 +1260,7 @@  int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
 			     u64 child_nodeid, struct qstr *name, u32 flags);
 
 int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
-		 bool isdir);
+		 bool isdir, struct fuse_open_out *outargp);
 
 /**
  * fuse_direct_io() flags
@@ -1351,7 +1352,8 @@  int fuse_fileattr_set(struct mnt_idmap *idmap,
 /* file.c */
 
 struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
-				 unsigned int open_flags, bool isdir);
+				 unsigned int open_flags, bool isdir,
+				 struct fuse_open_out *outargp);
 void fuse_file_release(struct inode *inode, struct fuse_file *ff,
 		       unsigned int open_flags, fl_owner_t id, bool isdir);
 
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c
index 726640fa439e..3aeef75c4df3 100644
--- a/fs/fuse/ioctl.c
+++ b/fs/fuse/ioctl.c
@@ -423,6 +423,7 @@  static struct fuse_file *fuse_priv_ioctl_prepare(struct inode *inode)
 {
 	struct fuse_mount *fm = get_fuse_mount(inode);
 	bool isdir = S_ISDIR(inode->i_mode);
+	struct fuse_open_out outarg;
 
 	if (!fuse_allow_current_process(fm->fc))
 		return ERR_PTR(-EACCES);
@@ -433,7 +434,7 @@  static struct fuse_file *fuse_priv_ioctl_prepare(struct inode *inode)
 	if (!S_ISREG(inode->i_mode) && !isdir)
 		return ERR_PTR(-ENOTTY);
 
-	return fuse_file_open(fm, get_node_id(inode), O_RDONLY, isdir);
+	return fuse_file_open(fm, get_node_id(inode), O_RDONLY, isdir, &outarg);
 }
 
 static void fuse_priv_ioctl_cleanup(struct inode *inode, struct fuse_file *ff)
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index acb42a76f7ff..0e273f372df4 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -766,7 +766,7 @@  struct fuse_create_in {
 struct fuse_open_out {
 	uint64_t	fh;
 	uint32_t	open_flags;
-	uint32_t	padding;
+	int32_t		backing_id;
 };
 
 struct fuse_release_in {