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>, Stefano Duo <duostefano93@gmail.com>, Zimuzo Ezeozue <zezeozue@google.com>, fuse-devel@lists.sourceforge.net, kernel-team@android.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V10 2/5] fuse: Passthrough initialization and release Date: Mon, 26 Oct 2020 12:50:13 +0000 Message-ID: <20201026125016.1905945-3-balsini@android.com> (raw) In-Reply-To: <20201026125016.1905945-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, userspace 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 userspace can be: - > 0: success, the identifier can be used as part of an open/create reply. - < 0: an error occurred. The value 0 has been left unused for 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, zero-initialized in the common libfuse implementation. Removing the 0 value fixes the ambiguity between the case in which 0 corresponds to a real passthrough_fh or a missing implementation, simplifying the userspace implementation. 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 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 | 80 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6738dd5ff5d2..1e94c54d1455 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1034,6 +1034,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..a135c955cc33 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -3,19 +3,95 @@ #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 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"); + return -EBADF; + } + + passthrough = kmalloc(sizeof(struct fuse_passthrough), GFP_KERNEL); + if (!passthrough) + return -ENOMEM; + + 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) { + fuse_passthrough_release(passthrough); + kfree(passthrough); + } + + return res; } int fuse_passthrough_setup(struct fuse_conn *fc, struct fuse_file *ff, struct fuse_open_out *openarg) { - return -EINVAL; + struct inode *passthrough_inode; + struct super_block *passthrough_sb; + 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; + + 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"); + fuse_passthrough_release(passthrough); + kfree(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.29.0.rc1.297.gfa9743e501-goog
next prev parent reply index Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-26 12:50 [PATCH V10 0/5] fuse: Add support for passthrough read/write Alessio Balsini 2020-10-26 12:50 ` [PATCH V10 1/5] fuse: Definitions and ioctl() for passthrough Alessio Balsini 2020-10-26 12:50 ` Alessio Balsini [this message] 2020-11-26 13:33 ` [PATCH V10 2/5] fuse: Passthrough initialization and release Peng Tao 2020-11-27 13:41 ` Alessio Balsini 2020-11-28 1:57 ` Peng Tao 2020-12-16 16:46 ` Alessio Balsini [not found] ` <3bf58b6f-c7eb-7baa-384d-ae0830d8bceb@tcl.com> 2020-12-16 16:55 ` Alessio Balsini 2020-10-26 12:50 ` [PATCH V10 3/5] fuse: Introduce synchronous read and write for passthrough Alessio Balsini 2020-10-26 12:50 ` [PATCH V10 4/5] fuse: Handle asynchronous read and write in passthrough Alessio Balsini 2020-10-26 12:50 ` [PATCH V10 5/5] fuse: Use daemon creds in passthrough mode Alessio Balsini 2020-11-28 2:10 ` [PATCH V10 0/5] fuse: Add support for passthrough read/write Peng Tao 2020-11-30 11:08 ` 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=20201026125016.1905945-3-balsini@android.com \ --to=balsini@android.com \ --cc=akailash@google.com \ --cc=amir73il@gmail.com \ --cc=axboe@kernel.dk \ --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=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
Linux-Fsdevel Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-fsdevel/0 linux-fsdevel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-fsdevel linux-fsdevel/ https://lore.kernel.org/linux-fsdevel \ linux-fsdevel@vger.kernel.org public-inbox-index linux-fsdevel Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-fsdevel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git