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:
Linus Torvalds
2019-09-24 12:33:34 -07:00
8 changed files with 748 additions and 758 deletions

View File

@@ -10,6 +10,8 @@
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/fsnotify.h>
#include <linux/backing-dev.h>
#include <linux/init.h>
@@ -20,7 +22,6 @@
#include <linux/pagemap.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/parser.h>
#include <asm/prom.h>
#include <asm/spu.h>
@@ -30,7 +31,7 @@
#include "spufs.h"
struct spufs_sb_info {
int debug;
bool debug;
};
static struct kmem_cache *spufs_inode_cache;
@@ -574,16 +575,27 @@ long spufs_create(struct path *path, struct dentry *dentry,
}
/* File system initialization */
enum {
Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err,
struct spufs_fs_context {
kuid_t uid;
kgid_t gid;
umode_t mode;
};
static const match_table_t spufs_tokens = {
{ Opt_uid, "uid=%d" },
{ Opt_gid, "gid=%d" },
{ Opt_mode, "mode=%o" },
{ Opt_debug, "debug" },
{ Opt_err, NULL },
enum {
Opt_uid, Opt_gid, Opt_mode, Opt_debug,
};
static const struct fs_parameter_spec spufs_param_specs[] = {
fsparam_u32 ("gid", Opt_gid),
fsparam_u32oct ("mode", Opt_mode),
fsparam_u32 ("uid", Opt_uid),
fsparam_flag ("debug", Opt_debug),
{}
};
static const struct fs_parameter_description spufs_fs_parameters = {
.name = "spufs",
.specs = spufs_param_specs,
};
static int spufs_show_options(struct seq_file *m, struct dentry *root)
@@ -604,47 +616,41 @@ static int spufs_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
static int
spufs_parse_options(struct super_block *sb, char *options, struct inode *root)
static int spufs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
char *p;
substring_t args[MAX_OPT_ARGS];
struct spufs_fs_context *ctx = fc->fs_private;
struct spufs_sb_info *sbi = fc->s_fs_info;
struct fs_parse_result result;
kuid_t uid;
kgid_t gid;
int opt;
while ((p = strsep(&options, ",")) != NULL) {
int token, option;
opt = fs_parse(fc, &spufs_fs_parameters, param, &result);
if (opt < 0)
return opt;
if (!*p)
continue;
token = match_token(p, spufs_tokens, args);
switch (token) {
case Opt_uid:
if (match_int(&args[0], &option))
return 0;
root->i_uid = make_kuid(current_user_ns(), option);
if (!uid_valid(root->i_uid))
return 0;
break;
case Opt_gid:
if (match_int(&args[0], &option))
return 0;
root->i_gid = make_kgid(current_user_ns(), option);
if (!gid_valid(root->i_gid))
return 0;
break;
case Opt_mode:
if (match_octal(&args[0], &option))
return 0;
root->i_mode = option | S_IFDIR;
break;
case Opt_debug:
spufs_get_sb_info(sb)->debug = 1;
break;
default:
return 0;
}
switch (opt) {
case Opt_uid:
uid = make_kuid(current_user_ns(), result.uint_32);
if (!uid_valid(uid))
return invalf(fc, "Unknown uid");
ctx->uid = uid;
break;
case Opt_gid:
gid = make_kgid(current_user_ns(), result.uint_32);
if (!gid_valid(gid))
return invalf(fc, "Unknown gid");
ctx->gid = gid;
break;
case Opt_mode:
ctx->mode = result.uint_32 & S_IALLUGO;
break;
case Opt_debug:
sbi->debug = true;
break;
}
return 1;
return 0;
}
static void spufs_exit_isolated_loader(void)
@@ -678,79 +684,98 @@ spufs_init_isolated_loader(void)
printk(KERN_INFO "spufs: SPU isolation mode enabled\n");
}
static int
spufs_create_root(struct super_block *sb, void *data)
static int spufs_create_root(struct super_block *sb, struct fs_context *fc)
{
struct spufs_fs_context *ctx = fc->fs_private;
struct inode *inode;
int ret;
ret = -ENODEV;
if (!spu_management_ops)
goto out;
return -ENODEV;
ret = -ENOMEM;
inode = spufs_new_inode(sb, S_IFDIR | 0775);
inode = spufs_new_inode(sb, S_IFDIR | ctx->mode);
if (!inode)
goto out;
return -ENOMEM;
inode->i_uid = ctx->uid;
inode->i_gid = ctx->gid;
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
SPUFS_I(inode)->i_ctx = NULL;
inc_nlink(inode);
ret = -EINVAL;
if (!spufs_parse_options(sb, data, inode))
goto out_iput;
ret = -ENOMEM;
sb->s_root = d_make_root(inode);
if (!sb->s_root)
goto out;
return -ENOMEM;
return 0;
out_iput:
iput(inode);
out:
return ret;
}
static int
spufs_fill_super(struct super_block *sb, void *data, int silent)
static const struct super_operations spufs_ops = {
.alloc_inode = spufs_alloc_inode,
.free_inode = spufs_free_inode,
.statfs = simple_statfs,
.evict_inode = spufs_evict_inode,
.show_options = spufs_show_options,
};
static int spufs_fill_super(struct super_block *sb, struct fs_context *fc)
{
struct spufs_sb_info *info;
static const struct super_operations s_ops = {
.alloc_inode = spufs_alloc_inode,
.free_inode = spufs_free_inode,
.statfs = simple_statfs,
.evict_inode = spufs_evict_inode,
.show_options = spufs_show_options,
};
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize = PAGE_SIZE;
sb->s_blocksize_bits = PAGE_SHIFT;
sb->s_magic = SPUFS_MAGIC;
sb->s_op = &s_ops;
sb->s_fs_info = info;
sb->s_op = &spufs_ops;
return spufs_create_root(sb, data);
return spufs_create_root(sb, fc);
}
static struct dentry *
spufs_mount(struct file_system_type *fstype, int flags,
const char *name, void *data)
static int spufs_get_tree(struct fs_context *fc)
{
return mount_single(fstype, flags, data, spufs_fill_super);
return get_tree_single(fc, spufs_fill_super);
}
static void spufs_free_fc(struct fs_context *fc)
{
kfree(fc->s_fs_info);
}
static const struct fs_context_operations spufs_context_ops = {
.free = spufs_free_fc,
.parse_param = spufs_parse_param,
.get_tree = spufs_get_tree,
};
static int spufs_init_fs_context(struct fs_context *fc)
{
struct spufs_fs_context *ctx;
struct spufs_sb_info *sbi;
ctx = kzalloc(sizeof(struct spufs_fs_context), GFP_KERNEL);
if (!ctx)
goto nomem;
sbi = kzalloc(sizeof(struct spufs_sb_info), GFP_KERNEL);
if (!sbi)
goto nomem_ctx;
ctx->uid = current_uid();
ctx->gid = current_gid();
ctx->mode = 0755;
fc->s_fs_info = sbi;
fc->ops = &spufs_context_ops;
return 0;
nomem_ctx:
kfree(ctx);
nomem:
return -ENOMEM;
}
static struct file_system_type spufs_type = {
.owner = THIS_MODULE,
.name = "spufs",
.mount = spufs_mount,
.init_fs_context = spufs_init_fs_context,
.parameters = &spufs_fs_parameters,
.kill_sb = kill_litter_super,
};
MODULE_ALIAS_FS("spufs");