Skip to content

Commit d2935de

Browse files
dhowellsAl Viro
authored andcommitted
vfs: Convert bpf to use the new mount API
Convert the bpf filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.txt for more information. Signed-off-by: David Howells <dhowells@redhat.com> cc: Alexei Starovoitov <ast@kernel.org> cc: Daniel Borkmann <daniel@iogearbox.net> cc: Martin KaFai Lau <kafai@fb.com> cc: Song Liu <songliubraving@fb.com> cc: Yonghong Song <yhs@fb.com> cc: netdev@vger.kernel.org cc: bpf@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 74983ac commit d2935de

File tree

1 file changed

+58
-34
lines changed

1 file changed

+58
-34
lines changed

kernel/bpf/inode.c

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#include <linux/mount.h>
1515
#include <linux/namei.h>
1616
#include <linux/fs.h>
17+
#include <linux/fs_context.h>
18+
#include <linux/fs_parser.h>
1719
#include <linux/kdev_t.h>
18-
#include <linux/parser.h>
1920
#include <linux/filter.h>
2021
#include <linux/bpf.h>
2122
#include <linux/bpf_trace.h>
@@ -583,58 +584,52 @@ static const struct super_operations bpf_super_ops = {
583584

584585
enum {
585586
OPT_MODE,
586-
OPT_ERR,
587587
};
588588

589-
static const match_table_t bpf_mount_tokens = {
590-
{ OPT_MODE, "mode=%o" },
591-
{ OPT_ERR, NULL },
589+
static const struct fs_parameter_spec bpf_param_specs[] = {
590+
fsparam_u32oct ("mode", OPT_MODE),
591+
{}
592+
};
593+
594+
static const struct fs_parameter_description bpf_fs_parameters = {
595+
.name = "bpf",
596+
.specs = bpf_param_specs,
592597
};
593598

594599
struct bpf_mount_opts {
595600
umode_t mode;
596601
};
597602

598-
static int bpf_parse_options(char *data, struct bpf_mount_opts *opts)
603+
static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
599604
{
600-
substring_t args[MAX_OPT_ARGS];
601-
int option, token;
602-
char *ptr;
605+
struct bpf_mount_opts *opts = fc->fs_private;
606+
struct fs_parse_result result;
607+
int opt;
603608

604-
opts->mode = S_IRWXUGO;
605-
606-
while ((ptr = strsep(&data, ",")) != NULL) {
607-
if (!*ptr)
608-
continue;
609-
610-
token = match_token(ptr, bpf_mount_tokens, args);
611-
switch (token) {
612-
case OPT_MODE:
613-
if (match_octal(&args[0], &option))
614-
return -EINVAL;
615-
opts->mode = option & S_IALLUGO;
616-
break;
609+
opt = fs_parse(fc, &bpf_fs_parameters, param, &result);
610+
if (opt < 0)
617611
/* We might like to report bad mount options here, but
618612
* traditionally we've ignored all mount options, so we'd
619613
* better continue to ignore non-existing options for bpf.
620614
*/
621-
}
615+
return opt == -ENOPARAM ? 0 : opt;
616+
617+
switch (opt) {
618+
case OPT_MODE:
619+
opts->mode = result.uint_32 & S_IALLUGO;
620+
break;
622621
}
623622

624623
return 0;
625624
}
626625

627-
static int bpf_fill_super(struct super_block *sb, void *data, int silent)
626+
static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
628627
{
629628
static const struct tree_descr bpf_rfiles[] = { { "" } };
630-
struct bpf_mount_opts opts;
629+
struct bpf_mount_opts *opts = fc->fs_private;
631630
struct inode *inode;
632631
int ret;
633632

634-
ret = bpf_parse_options(data, &opts);
635-
if (ret)
636-
return ret;
637-
638633
ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles);
639634
if (ret)
640635
return ret;
@@ -644,21 +639,50 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent)
644639
inode = sb->s_root->d_inode;
645640
inode->i_op = &bpf_dir_iops;
646641
inode->i_mode &= ~S_IALLUGO;
647-
inode->i_mode |= S_ISVTX | opts.mode;
642+
inode->i_mode |= S_ISVTX | opts->mode;
648643

649644
return 0;
650645
}
651646

652-
static struct dentry *bpf_mount(struct file_system_type *type, int flags,
653-
const char *dev_name, void *data)
647+
static int bpf_get_tree(struct fs_context *fc)
648+
{
649+
return get_tree_nodev(fc, bpf_fill_super);
650+
}
651+
652+
static void bpf_free_fc(struct fs_context *fc)
654653
{
655-
return mount_nodev(type, flags, data, bpf_fill_super);
654+
kfree(fc->fs_private);
655+
}
656+
657+
static const struct fs_context_operations bpf_context_ops = {
658+
.free = bpf_free_fc,
659+
.parse_param = bpf_parse_param,
660+
.get_tree = bpf_get_tree,
661+
};
662+
663+
/*
664+
* Set up the filesystem mount context.
665+
*/
666+
static int bpf_init_fs_context(struct fs_context *fc)
667+
{
668+
struct bpf_mount_opts *opts;
669+
670+
opts = kzalloc(sizeof(struct bpf_mount_opts), GFP_KERNEL);
671+
if (!opts)
672+
return -ENOMEM;
673+
674+
opts->mode = S_IRWXUGO;
675+
676+
fc->fs_private = opts;
677+
fc->ops = &bpf_context_ops;
678+
return 0;
656679
}
657680

658681
static struct file_system_type bpf_fs_type = {
659682
.owner = THIS_MODULE,
660683
.name = "bpf",
661-
.mount = bpf_mount,
684+
.init_fs_context = bpf_init_fs_context,
685+
.parameters = &bpf_fs_parameters,
662686
.kill_sb = kill_litter_super,
663687
};
664688

0 commit comments

Comments
 (0)