When using fuse-bpf in pure passthrough mode, we don't explicitly need a userspace daemon. This allows simple testing of the backing operations. Signed-off-by: Daniel Rosenberg <drosen@xxxxxxxxxx> Signed-off-by: Paul Lawrence <paullawrence@xxxxxxxxxx> --- fs/fuse/fuse_i.h | 4 ++++ fs/fuse/inode.c | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 99c9231ec98b..402d80d35958 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -564,6 +564,7 @@ struct fuse_fs_context { bool no_control:1; bool no_force_umount:1; bool legacy_opts_show:1; + bool no_daemon:1; enum fuse_dax_mode dax_mode; unsigned int max_read; unsigned int blksize; @@ -842,6 +843,9 @@ struct fuse_conn { /* Is tmpfile not implemented by fs? */ unsigned int no_tmpfile:1; + /** BPF Only, no Daemon running */ + unsigned int no_daemon:1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1e7d45977144..4820edcc242a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -749,6 +749,7 @@ enum { OPT_MAX_READ, OPT_BLKSIZE, OPT_ROOT_DIR, + OPT_NO_DAEMON, OPT_ERR }; @@ -764,6 +765,7 @@ static const struct fs_parameter_spec fuse_fs_parameters[] = { fsparam_u32 ("blksize", OPT_BLKSIZE), fsparam_string ("subtype", OPT_SUBTYPE), fsparam_u32 ("root_dir", OPT_ROOT_DIR), + fsparam_flag ("no_daemon", OPT_NO_DAEMON), {} }; @@ -853,6 +855,11 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) return invalfc(fsc, "Unable to open root directory"); break; + case OPT_NO_DAEMON: + ctx->no_daemon = true; + ctx->fd_present = true; + break; + default: return -EINVAL; } @@ -1411,7 +1418,7 @@ void fuse_send_init(struct fuse_mount *fm) ia->args.nocreds = true; ia->args.end = process_init_reply; - if (fuse_simple_background(fm, &ia->args, GFP_KERNEL) != 0) + if (unlikely(fm->fc->no_daemon) || fuse_simple_background(fm, &ia->args, GFP_KERNEL) != 0) process_init_reply(fm, &ia->args, -ENOTCONN); } EXPORT_SYMBOL_GPL(fuse_send_init); @@ -1693,6 +1700,7 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) fc->destroy = ctx->destroy; fc->no_control = ctx->no_control; fc->no_force_umount = ctx->no_force_umount; + fc->no_daemon = ctx->no_daemon; err = -ENOMEM; root = fuse_get_root_inode(sb, ctx->rootmode, ctx->root_dir); @@ -1739,7 +1747,7 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) struct fuse_fs_context *ctx = fsc->fs_private; int err; - if (!ctx->file || !ctx->rootmode_present || + if (!!ctx->file == ctx->no_daemon || !ctx->rootmode_present || !ctx->user_id_present || !ctx->group_id_present) return -EINVAL; @@ -1747,10 +1755,12 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) * Require mount to happen from the same user namespace which * opened /dev/fuse to prevent potential attacks. */ - if ((ctx->file->f_op != &fuse_dev_operations) || - (ctx->file->f_cred->user_ns != sb->s_user_ns)) - return -EINVAL; - ctx->fudptr = &ctx->file->private_data; + if (ctx->file) { + if ((ctx->file->f_op != &fuse_dev_operations) || + (ctx->file->f_cred->user_ns != sb->s_user_ns)) + return -EINVAL; + ctx->fudptr = &ctx->file->private_data; + } err = fuse_fill_super_common(sb, ctx); if (err) @@ -1800,6 +1810,9 @@ static int fuse_get_tree(struct fs_context *fsc) fsc->s_fs_info = fm; + if (ctx->no_daemon) + return get_tree_nodev(fsc, fuse_fill_super); + if (ctx->fd_present) ctx->file = fget(ctx->fd); -- 2.38.1.584.g0f3c55d4c2-goog