Linux-Fsdevel Archive on lore.kernel.org help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com> To: Alessio Balsini <balsini@android.com> Cc: Miklos Szeredi <miklos@szeredi.hu>, Akilesh Kailash <akailash@google.com>, David Anderson <dvander@google.com>, Eric Yan <eric.yan@oneplus.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>, Stefano Duo <stefanoduo@google.com>, Zimuzo Ezeozue <zezeozue@google.com>, fuse-devel <fuse-devel@lists.sourceforge.net>, kernel-team <kernel-team@android.com>, linux-fsdevel <linux-fsdevel@vger.kernel.org>, linux-kernel <linux-kernel@vger.kernel.org> Subject: Re: [PATCH V8 1/3] fuse: Definitions and ioctl() for passthrough Date: Sat, 12 Sep 2020 14:06:02 +0300 [thread overview] Message-ID: <CAOQ4uxiWK5dNMkrriApMVZQi6apmnMijcCw5j4fa2thHFdnFcw@mail.gmail.com> (raw) In-Reply-To: <20200911163403.79505-2-balsini@android.com> On Fri, Sep 11, 2020 at 7:34 PM Alessio Balsini <balsini@android.com> wrote: > > Introduce the new FUSE passthrough ioctl(), which allows userspace to > specify a direct connection between a FUSE file and a lower file system > file. > Such ioctl() requires userspace to specify: > - the file descriptor of one of its opened files, > - the unique identifier of the FUSE request associated with a pending > open/create operation, > both encapsulated into a fuse_passthrough_out data structure. > The ioctl() will search for the pending FUSE request matching the unique > identifier, and update the passthrough file pointer of the request with the > file pointer referenced by the passed file descriptor. > When that pending FUSE request is handled, the passthrough file pointer > is copied to the fuse_file data structure, so that the link between FUSE > and lower file system is consolidated. > > In order for the passthrough mode to be successfully activated, the lower > file system file must implement both read_ and write_iter file operations. > This extra check avoids special pseudofiles to be targets for this feature. > An additional enforced limitation is that when FUSE passthrough is enabled, > no further file system stacking is allowed. > > Signed-off-by: Alessio Balsini <balsini@android.com> > --- [...] > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c > index bba747520e9b..eb223130a917 100644 > --- a/fs/fuse/inode.c > +++ b/fs/fuse/inode.c > @@ -965,6 +965,12 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_args *args, > min_t(unsigned int, FUSE_MAX_MAX_PAGES, > max_t(unsigned int, arg->max_pages, 1)); > } > + if (arg->flags & FUSE_PASSTHROUGH) { > + fc->passthrough = 1; > + /* Prevent further stacking */ > + fc->sb->s_stack_depth = > + FILESYSTEM_MAX_STACK_DEPTH; > + } That seems a bit limiting. I suppose what you really want to avoid is loops into FUSE fd. There may be a way to do this with forbidding overlay over FUSE passthrough or the other way around. You can set fc->sb->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH - 1 here and in passthrough ioctl you can check for looping into a fuse fs with passthrough enabled on the passed fd (see below) ... > } else { > ra_pages = fc->max_read / PAGE_SIZE; > fc->no_lock = 1; > @@ -1002,7 +1008,8 @@ void fuse_send_init(struct fuse_conn *fc) > FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | > FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | > FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | > - FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA; > + FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA | > + FUSE_PASSTHROUGH; > ia->args.opcode = FUSE_INIT; > ia->args.in_numargs = 1; > ia->args.in_args[0].size = sizeof(ia->in); > diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c > new file mode 100644 > index 000000000000..86ab4eafa7bf > --- /dev/null > +++ b/fs/fuse/passthrough.c > @@ -0,0 +1,55 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include "fuse_i.h" > + > +int fuse_passthrough_setup(struct fuse_req *req, unsigned int fd) > +{ > + int ret; > + int fs_stack_depth; > + struct file *passthrough_filp; > + struct inode *passthrough_inode; > + struct super_block *passthrough_sb; > + > + /* Passthrough mode can only be enabled at file open/create time */ > + if (req->in.h.opcode != FUSE_OPEN && req->in.h.opcode != FUSE_CREATE) { > + pr_err("FUSE: invalid OPCODE for request.\n"); > + return -EINVAL; > + } > + > + passthrough_filp = fget(fd); > + if (!passthrough_filp) { > + pr_err("FUSE: invalid file descriptor for passthrough.\n"); > + return -EINVAL; > + } > + > + ret = -EINVAL; > + if (!passthrough_filp->f_op->read_iter || > + !passthrough_filp->f_op->write_iter) { > + pr_err("FUSE: passthrough file misses file operations.\n"); > + goto out; > + } > + > + passthrough_inode = file_inode(passthrough_filp); > + passthrough_sb = passthrough_inode->i_sb; > + fs_stack_depth = passthrough_sb->s_stack_depth + 1; ... for example: if (fs_stack_depth && passthrough_sb->s_type == fuse_fs_type) { pr_err("FUSE: stacked passthrough file\n"); goto out; } But maybe we want to ban passthrough to any lower FUSE at least for start. > + ret = -EEXIST; Why EEXIST? Why not EINVAL? > + if (fs_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { > + pr_err("FUSE: maximum fs stacking depth exceeded for passthrough\n"); > + goto out; > + } > + > + req->args->passthrough_filp = passthrough_filp; > + return 0; > +out: > + fput(passthrough_filp); > + return ret; > +} > + And speaking of overlayfs, I believe you may be able to test your code with fuse-overlayfs (passthrough to upper files). This is a project with real users running real workloads who may be able to provide you with valuable feedback from testing. Thanks, Amir. [1] https://github.com/containers/fuse-overlayfs
next prev parent reply other threads:[~2020-09-12 11:06 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-09-11 16:34 [PATCH V8 0/3] fuse: Add support for passthrough read/write Alessio Balsini 2020-09-11 16:34 ` [PATCH V8 1/3] fuse: Definitions and ioctl() for passthrough Alessio Balsini 2020-09-12 11:06 ` Amir Goldstein [this message] 2020-09-18 16:33 ` Alessio Balsini 2020-09-18 19:59 ` Amir Goldstein 2020-09-22 12:15 ` Alessio Balsini 2020-09-22 16:08 ` Amir Goldstein 2020-09-29 14:30 ` Alessio Balsini 2020-09-11 16:34 ` [PATCH V8 2/3] fuse: Introduce synchronous read and write " Alessio Balsini 2020-09-12 9:55 ` Amir Goldstein 2020-09-21 11:01 ` Alessio Balsini 2020-09-21 13:07 ` Amir Goldstein 2020-09-11 16:34 ` [PATCH V8 3/3] fuse: Handle AIO read and write in passthrough Alessio Balsini 2020-09-11 17:23 ` Jens Axboe 2020-09-21 15:28 ` Alessio Balsini 2020-09-11 18:46 ` [fuse-devel] [PATCH V8 0/3] fuse: Add support for passthrough read/write Antonio SJ Musumeci 2020-09-18 16:03 ` Alessio Balsini
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=CAOQ4uxiWK5dNMkrriApMVZQi6apmnMijcCw5j4fa2thHFdnFcw@mail.gmail.com \ --to=amir73il@gmail.com \ --cc=akailash@google.com \ --cc=axboe@kernel.dk \ --cc=balsini@android.com \ --cc=dvander@google.com \ --cc=eric.yan@oneplus.com \ --cc=fuse-devel@lists.sourceforge.net \ --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=stefanoduo@google.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: linkBe 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; as well as URLs for NNTP newsgroup(s).