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 [thread overview]
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 other threads:[~2020-10-26 12:51 UTC|newest]
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
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.