Merge branch 'work.mount3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more mount API conversions from Al Viro: "Assorted conversions of options parsing to new API. gfs2 is probably the most serious one here; the rest is trivial stuff. Other things in what used to be #work.mount are going to wait for the next cycle (and preferably go via git trees of the filesystems involved)" * 'work.mount3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: gfs2: Convert gfs2 to fs_context vfs: Convert spufs to use the new mount API vfs: Convert hypfs to use the new mount API hypfs: Fix error number left in struct pointer member vfs: Convert functionfs to use the new mount API vfs: Convert bpf to use the new mount API
This commit is contained in:
@@ -14,8 +14,9 @@
|
||||
#include <linux/mount.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs_context.h>
|
||||
#include <linux/fs_parser.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/bpf_trace.h>
|
||||
@@ -583,58 +584,52 @@ static const struct super_operations bpf_super_ops = {
|
||||
|
||||
enum {
|
||||
OPT_MODE,
|
||||
OPT_ERR,
|
||||
};
|
||||
|
||||
static const match_table_t bpf_mount_tokens = {
|
||||
{ OPT_MODE, "mode=%o" },
|
||||
{ OPT_ERR, NULL },
|
||||
static const struct fs_parameter_spec bpf_param_specs[] = {
|
||||
fsparam_u32oct ("mode", OPT_MODE),
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct fs_parameter_description bpf_fs_parameters = {
|
||||
.name = "bpf",
|
||||
.specs = bpf_param_specs,
|
||||
};
|
||||
|
||||
struct bpf_mount_opts {
|
||||
umode_t mode;
|
||||
};
|
||||
|
||||
static int bpf_parse_options(char *data, struct bpf_mount_opts *opts)
|
||||
static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||
{
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
int option, token;
|
||||
char *ptr;
|
||||
struct bpf_mount_opts *opts = fc->fs_private;
|
||||
struct fs_parse_result result;
|
||||
int opt;
|
||||
|
||||
opts->mode = S_IRWXUGO;
|
||||
|
||||
while ((ptr = strsep(&data, ",")) != NULL) {
|
||||
if (!*ptr)
|
||||
continue;
|
||||
|
||||
token = match_token(ptr, bpf_mount_tokens, args);
|
||||
switch (token) {
|
||||
case OPT_MODE:
|
||||
if (match_octal(&args[0], &option))
|
||||
return -EINVAL;
|
||||
opts->mode = option & S_IALLUGO;
|
||||
break;
|
||||
opt = fs_parse(fc, &bpf_fs_parameters, param, &result);
|
||||
if (opt < 0)
|
||||
/* We might like to report bad mount options here, but
|
||||
* traditionally we've ignored all mount options, so we'd
|
||||
* better continue to ignore non-existing options for bpf.
|
||||
*/
|
||||
}
|
||||
return opt == -ENOPARAM ? 0 : opt;
|
||||
|
||||
switch (opt) {
|
||||
case OPT_MODE:
|
||||
opts->mode = result.uint_32 & S_IALLUGO;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bpf_fill_super(struct super_block *sb, void *data, int silent)
|
||||
static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
{
|
||||
static const struct tree_descr bpf_rfiles[] = { { "" } };
|
||||
struct bpf_mount_opts opts;
|
||||
struct bpf_mount_opts *opts = fc->fs_private;
|
||||
struct inode *inode;
|
||||
int ret;
|
||||
|
||||
ret = bpf_parse_options(data, &opts);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -644,21 +639,50 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent)
|
||||
inode = sb->s_root->d_inode;
|
||||
inode->i_op = &bpf_dir_iops;
|
||||
inode->i_mode &= ~S_IALLUGO;
|
||||
inode->i_mode |= S_ISVTX | opts.mode;
|
||||
inode->i_mode |= S_ISVTX | opts->mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dentry *bpf_mount(struct file_system_type *type, int flags,
|
||||
const char *dev_name, void *data)
|
||||
static int bpf_get_tree(struct fs_context *fc)
|
||||
{
|
||||
return mount_nodev(type, flags, data, bpf_fill_super);
|
||||
return get_tree_nodev(fc, bpf_fill_super);
|
||||
}
|
||||
|
||||
static void bpf_free_fc(struct fs_context *fc)
|
||||
{
|
||||
kfree(fc->fs_private);
|
||||
}
|
||||
|
||||
static const struct fs_context_operations bpf_context_ops = {
|
||||
.free = bpf_free_fc,
|
||||
.parse_param = bpf_parse_param,
|
||||
.get_tree = bpf_get_tree,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up the filesystem mount context.
|
||||
*/
|
||||
static int bpf_init_fs_context(struct fs_context *fc)
|
||||
{
|
||||
struct bpf_mount_opts *opts;
|
||||
|
||||
opts = kzalloc(sizeof(struct bpf_mount_opts), GFP_KERNEL);
|
||||
if (!opts)
|
||||
return -ENOMEM;
|
||||
|
||||
opts->mode = S_IRWXUGO;
|
||||
|
||||
fc->fs_private = opts;
|
||||
fc->ops = &bpf_context_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_system_type bpf_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bpf",
|
||||
.mount = bpf_mount,
|
||||
.init_fs_context = bpf_init_fs_context,
|
||||
.parameters = &bpf_fs_parameters,
|
||||
.kill_sb = kill_litter_super,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user