All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alessio Balsini <balsini@android.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Akilesh Kailash <akailash@google.com>,
	Amir Goldstein <amir73il@gmail.com>,
	Antonio SJ Musumeci <trapexit@spawn.link>,
	David Anderson <dvander@google.com>,
	Giuseppe Scrivano <gscrivan@redhat.com>,
	Jann Horn <jannh@google.com>, Jens Axboe <axboe@kernel.dk>,
	Martijn Coenen <maco@android.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Paul Lawrence <paullawrence@google.com>,
	Peng Tao <bergwolf@gmail.com>,
	Stefano Duo <duostefano93@gmail.com>,
	Zimuzo Ezeozue <zezeozue@google.com>, wuyan <wu-yan@tcl.com>,
	fuse-devel@lists.sourceforge.net, kernel-team@android.com,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH RESEND V12 4/8] fuse: Passthrough initialization and release
Date: Mon, 25 Jan 2021 15:30:53 +0000	[thread overview]
Message-ID: <20210125153057.3623715-5-balsini@android.com> (raw)
In-Reply-To: <20210125153057.3623715-1-balsini@android.com>

Implement the FUSE passthrough ioctl that associates the lower
(passthrough) file system file with the fuse_file.

The file descriptor passed to the ioctl by the FUSE daemon is used to
access the relative file pointer, that will be copied to the fuse_file
data structure to consolidate the link between the FUSE and lower file
system.

To enable the passthrough mode, user space triggers the
FUSE_DEV_IOC_PASSTHROUGH_OPEN ioctl and, if the call succeeds, receives
back an identifier that will be used at open/create response time in the
fuse_open_out field to associate the FUSE file to the lower file system
file.
The value returned by the ioctl to user space can be:
- > 0: success, the identifier can be used as part of an open/create
reply.
- <= 0: an error occurred.
The value 0 represents an error to preserve backward compatibility: the
fuse_open_out field that is used to pass the passthrough_fh back to the
kernel uses the same bits that were previously as struct padding, and is
commonly zero-initialized (e.g., in the libfuse implementation).
Removing 0 from the correct values fixes the ambiguity between the case
in which 0 corresponds to a real passthrough_fh, a missing
implementation of FUSE passthrough or a request for a normal FUSE file,
simplifying the user space implementation.

For the passthrough mode to be successfully activated, the lower file
system file must implement both read_iter and write_iter file
operations. This extra check avoids special pseudo files to be targeted
for this feature.
Passthrough comes with another limitation: no further file system
stacking is allowed for those FUSE file systems using passthrough.

Signed-off-by: Alessio Balsini <balsini@android.com>
---
 fs/fuse/inode.c       |  5 +++
 fs/fuse/passthrough.c | 87 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index a1104d5abb70..7ebc398fbacb 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1133,6 +1133,11 @@ EXPORT_SYMBOL_GPL(fuse_send_init);
 
 static int free_fuse_passthrough(int id, void *p, void *data)
 {
+	struct fuse_passthrough *passthrough = (struct fuse_passthrough *)p;
+
+	fuse_passthrough_release(passthrough);
+	kfree(p);
+
 	return 0;
 }
 
diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c
index 594060c654f8..cf993e83803e 100644
--- a/fs/fuse/passthrough.c
+++ b/fs/fuse/passthrough.c
@@ -3,19 +3,102 @@
 #include "fuse_i.h"
 
 #include <linux/fuse.h>
+#include <linux/idr.h>
 
 int fuse_passthrough_open(struct fuse_dev *fud,
 			  struct fuse_passthrough_out *pto)
 {
-	return -EINVAL;
+	int res;
+	struct file *passthrough_filp;
+	struct fuse_conn *fc = fud->fc;
+	struct inode *passthrough_inode;
+	struct super_block *passthrough_sb;
+	struct fuse_passthrough *passthrough;
+
+	if (!fc->passthrough)
+		return -EPERM;
+
+	/* This field is reserved for future implementation */
+	if (pto->len != 0)
+		return -EINVAL;
+
+	passthrough_filp = fget(pto->fd);
+	if (!passthrough_filp) {
+		pr_err("FUSE: invalid file descriptor for passthrough.\n");
+		return -EBADF;
+	}
+
+	if (!passthrough_filp->f_op->read_iter ||
+	    !passthrough_filp->f_op->write_iter) {
+		pr_err("FUSE: passthrough file misses file operations.\n");
+		res = -EBADF;
+		goto err_free_file;
+	}
+
+	passthrough_inode = file_inode(passthrough_filp);
+	passthrough_sb = passthrough_inode->i_sb;
+	if (passthrough_sb->s_stack_depth >= FILESYSTEM_MAX_STACK_DEPTH) {
+		pr_err("FUSE: fs stacking depth exceeded for passthrough\n");
+		res = -EINVAL;
+		goto err_free_file;
+	}
+
+	passthrough = kmalloc(sizeof(struct fuse_passthrough), GFP_KERNEL);
+	if (!passthrough) {
+		res = -ENOMEM;
+		goto err_free_file;
+	}
+
+	passthrough->filp = passthrough_filp;
+
+	idr_preload(GFP_KERNEL);
+	spin_lock(&fc->passthrough_req_lock);
+	res = idr_alloc(&fc->passthrough_req, passthrough, 1, 0, GFP_ATOMIC);
+	spin_unlock(&fc->passthrough_req_lock);
+	idr_preload_end();
+
+	if (res > 0)
+		return res;
+
+	fuse_passthrough_release(passthrough);
+	kfree(passthrough);
+
+err_free_file:
+	fput(passthrough_filp);
+
+	return res;
 }
 
 int fuse_passthrough_setup(struct fuse_conn *fc, struct fuse_file *ff,
 			   struct fuse_open_out *openarg)
 {
-	return -EINVAL;
+	struct fuse_passthrough *passthrough;
+	int passthrough_fh = openarg->passthrough_fh;
+
+	if (!fc->passthrough)
+		return -EPERM;
+
+	/* Default case, passthrough is not requested */
+	if (passthrough_fh <= 0)
+		return -EINVAL;
+
+	spin_lock(&fc->passthrough_req_lock);
+	passthrough = idr_remove(&fc->passthrough_req, passthrough_fh);
+	spin_unlock(&fc->passthrough_req_lock);
+
+	if (!passthrough)
+		return -EINVAL;
+
+	ff->passthrough = *passthrough;
+	kfree(passthrough);
+
+	return 0;
 }
 
 void fuse_passthrough_release(struct fuse_passthrough *passthrough)
 {
+	if (passthrough->filp) {
+		fput(passthrough->filp);
+		passthrough->filp = NULL;
+	}
 }
-- 
2.30.0.280.ga3ce27912f-goog


  parent reply	other threads:[~2021-01-26 17:00 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-25 15:30 [PATCH RESEND V12 0/8] fuse: Add support for passthrough read/write Alessio Balsini
2021-01-25 15:30 ` [PATCH RESEND V12 1/8] fs: Generic function to convert iocb to rw flags Alessio Balsini
2021-01-25 16:46   ` Alessio Balsini
2021-03-24  7:43     ` Rokudo Yan
2021-03-24 14:02       ` Alessio Balsini
2021-01-25 15:30 ` [PATCH RESEND V12 2/8] fuse: 32-bit user space ioctl compat for fuse device Alessio Balsini
     [not found]   ` <CAMAHBGzkfEd9-1u0iKXp65ReJQgUi_=4sMpmfkwEOaMp6Ux7pg@mail.gmail.com>
2021-01-27 13:40     ` Alessio Balsini
     [not found]       ` <CAMAHBGwpKW+30kNQ_Apt8A-FTmr94hBOzkT21cjEHHW+t7yUMQ@mail.gmail.com>
2021-01-28 14:15         ` Alessio Balsini
2021-02-05  9:54           ` Peng Tao
2021-03-16 18:57           ` Arnd Bergmann
2021-02-17 10:21   ` Miklos Szeredi
2021-03-01 12:26     ` Alessio Balsini
2021-03-16 18:53   ` Arnd Bergmann
2021-03-18 16:13     ` Alessio Balsini
2021-03-18 21:15       ` Arnd Bergmann
2021-03-19 15:21         ` Alessio Balsini
2021-01-25 15:30 ` [PATCH RESEND V12 3/8] fuse: Definitions and ioctl for passthrough Alessio Balsini
2021-02-17 13:41   ` Miklos Szeredi
2021-02-19  7:05     ` Peng Tao
2021-02-19  8:40       ` Miklos Szeredi
2021-03-01 17:05         ` Alessio Balsini
2022-09-08 15:36           ` Amir Goldstein
2022-09-09 19:07             ` Miklos Szeredi
2022-09-10  8:52               ` Amir Goldstein
2022-09-10 13:03                 ` Bernd Schubert
2022-09-12  9:29                 ` Miklos Szeredi
2022-09-12 12:29                   ` Amir Goldstein
2022-09-12 13:03                     ` Miklos Szeredi
2022-09-12 13:05                       ` Miklos Szeredi
2022-09-12 13:26                       ` Amir Goldstein
2022-09-12 14:22                         ` Miklos Szeredi
2022-09-12 15:39                           ` Amir Goldstein
2022-09-12 17:43                             ` Hao Luo
2022-09-12 18:28                               ` Overlayfs with writable lower layer Amir Goldstein
2022-09-13 18:26                                 ` Hao Luo
2022-09-13 18:54                                   ` Amir Goldstein
2022-09-13 20:33                                     ` Hao Luo
2022-09-14  3:46                                       ` Amir Goldstein
2022-09-14 18:00                                         ` Hao Luo
2022-09-14 19:23                                           ` Amir Goldstein
2022-09-14 19:33                                             ` Hao Luo
2022-09-15 10:54                                               ` Amir Goldstein
2023-05-12 19:37                     ` [PATCH RESEND V12 3/8] fuse: Definitions and ioctl for passthrough Amir Goldstein
2023-05-15  7:29                       ` Miklos Szeredi
2023-05-15 14:00                         ` Amir Goldstein
2023-05-15 20:16                           ` [fuse-devel] " Nikolaus Rath
2023-05-15 21:11                             ` Bernd Schubert
2023-05-15 21:45                               ` Paul Lawrence
2023-05-16  8:43                                 ` Miklos Szeredi
2023-05-16 10:16                                   ` Nikolaus Rath
2023-05-16  8:48                                 ` Amir Goldstein
2021-01-25 15:30 ` Alessio Balsini [this message]
2021-02-17 13:52   ` [PATCH RESEND V12 4/8] fuse: Passthrough initialization and release Miklos Szeredi
2021-05-05 12:21     ` Amir Goldstein
2021-05-17 11:36       ` Alessio Balsini
2021-05-17 13:21         ` Amir Goldstein
2021-01-25 15:30 ` [PATCH RESEND V12 5/8] fuse: Introduce synchronous read and write for passthrough Alessio Balsini
2021-02-17 14:00   ` Miklos Szeredi
2021-01-25 15:30 ` [PATCH RESEND V12 6/8] fuse: Handle asynchronous read and write in passthrough Alessio Balsini
2021-01-25 15:30 ` [PATCH RESEND V12 7/8] fuse: Use daemon creds in passthrough mode Alessio Balsini
2021-02-05  9:23   ` Peng Tao
2021-02-05 11:21     ` Alessio Balsini
2021-01-25 15:30 ` [PATCH RESEND V12 8/8] fuse: Introduce passthrough for mmap Alessio Balsini
2021-02-17 14:05   ` Miklos Szeredi
2021-04-01 11:24     ` Alessio Balsini
2021-11-18 18:31 ` [PATCH RESEND V12 0/8] fuse: Add support for passthrough read/write Amir Goldstein

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=20210125153057.3623715-5-balsini@android.com \
    --to=balsini@android.com \
    --cc=akailash@google.com \
    --cc=amir73il@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=bergwolf@gmail.com \
    --cc=duostefano93@gmail.com \
    --cc=dvander@google.com \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=gscrivan@redhat.com \
    --cc=jannh@google.com \
    --cc=kernel-team@android.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maco@android.com \
    --cc=miklos@szeredi.hu \
    --cc=palmer@dabbelt.com \
    --cc=paullawrence@google.com \
    --cc=trapexit@spawn.link \
    --cc=wu-yan@tcl.com \
    --cc=zezeozue@google.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.