diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-24 12:33:34 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-24 12:33:34 -0700 | 
| commit | 0b36c9eed232760fbf51921818f48b3699f1f1ca (patch) | |
| tree | 1392ebcd076e87f7c80cd93e29db7acbee542071 /arch/s390/hypfs | |
| parent | 722e6f500ac72d0d43955710738a24fd957607a4 (diff) | |
| parent | 1f52aa08d12f8d359e71b4bfd73ca9d5d668e4da (diff) | |
| download | linux-0b36c9eed232760fbf51921818f48b3699f1f1ca.tar.bz2 | |
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
Diffstat (limited to 'arch/s390/hypfs')
| -rw-r--r-- | arch/s390/hypfs/inode.c | 137 | 
1 files changed, 75 insertions, 62 deletions
| diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index a4418fc425b8..70139d0791b6 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -12,17 +12,17 @@  #include <linux/types.h>  #include <linux/errno.h>  #include <linux/fs.h> +#include <linux/fs_context.h> +#include <linux/fs_parser.h>  #include <linux/namei.h>  #include <linux/vfs.h>  #include <linux/slab.h>  #include <linux/pagemap.h>  #include <linux/time.h> -#include <linux/parser.h>  #include <linux/sysfs.h>  #include <linux/init.h>  #include <linux/kobject.h>  #include <linux/seq_file.h> -#include <linux/mount.h>  #include <linux/uio.h>  #include <asm/ebcdic.h>  #include "hypfs.h" @@ -207,52 +207,44 @@ static int hypfs_release(struct inode *inode, struct file *filp)  	return 0;  } -enum { opt_uid, opt_gid, opt_err }; +enum { Opt_uid, Opt_gid, }; -static const match_table_t hypfs_tokens = { -	{opt_uid, "uid=%u"}, -	{opt_gid, "gid=%u"}, -	{opt_err, NULL} +static const struct fs_parameter_spec hypfs_param_specs[] = { +	fsparam_u32("gid", Opt_gid), +	fsparam_u32("uid", Opt_uid), +	{}  }; -static int hypfs_parse_options(char *options, struct super_block *sb) +static const struct fs_parameter_description hypfs_fs_parameters = { +	.name		= "hypfs", +	.specs		= hypfs_param_specs, +}; + +static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)  { -	char *str; -	substring_t args[MAX_OPT_ARGS]; +	struct hypfs_sb_info *hypfs_info = fc->s_fs_info; +	struct fs_parse_result result;  	kuid_t uid;  	kgid_t gid; - -	if (!options) -		return 0; -	while ((str = strsep(&options, ",")) != NULL) { -		int token, option; -		struct hypfs_sb_info *hypfs_info = sb->s_fs_info; - -		if (!*str) -			continue; -		token = match_token(str, hypfs_tokens, args); -		switch (token) { -		case opt_uid: -			if (match_int(&args[0], &option)) -				return -EINVAL; -			uid = make_kuid(current_user_ns(), option); -			if (!uid_valid(uid)) -				return -EINVAL; -			hypfs_info->uid = uid; -			break; -		case opt_gid: -			if (match_int(&args[0], &option)) -				return -EINVAL; -			gid = make_kgid(current_user_ns(), option); -			if (!gid_valid(gid)) -				return -EINVAL; -			hypfs_info->gid = gid; -			break; -		case opt_err: -		default: -			pr_err("%s is not a valid mount option\n", str); -			return -EINVAL; -		} +	int opt; + +	opt = fs_parse(fc, &hypfs_fs_parameters, param, &result); +	if (opt < 0) +		return opt; + +	switch (opt) { +	case Opt_uid: +		uid = make_kuid(current_user_ns(), result.uint_32); +		if (!uid_valid(uid)) +			return invalf(fc, "Unknown uid"); +		hypfs_info->uid = uid; +		break; +	case Opt_gid: +		gid = make_kgid(current_user_ns(), result.uint_32); +		if (!gid_valid(gid)) +			return invalf(fc, "Unknown gid"); +		hypfs_info->gid = gid; +		break;  	}  	return 0;  } @@ -266,26 +258,18 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root)  	return 0;  } -static int hypfs_fill_super(struct super_block *sb, void *data, int silent) +static int hypfs_fill_super(struct super_block *sb, struct fs_context *fc)  { +	struct hypfs_sb_info *sbi = sb->s_fs_info;  	struct inode *root_inode; -	struct dentry *root_dentry; -	int rc = 0; -	struct hypfs_sb_info *sbi; +	struct dentry *root_dentry, *update_file; +	int rc; -	sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); -	if (!sbi) -		return -ENOMEM; -	mutex_init(&sbi->lock); -	sbi->uid = current_uid(); -	sbi->gid = current_gid(); -	sb->s_fs_info = sbi;  	sb->s_blocksize = PAGE_SIZE;  	sb->s_blocksize_bits = PAGE_SHIFT;  	sb->s_magic = HYPFS_MAGIC;  	sb->s_op = &hypfs_s_ops; -	if (hypfs_parse_options(data, sb)) -		return -EINVAL; +  	root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);  	if (!root_inode)  		return -ENOMEM; @@ -300,18 +284,46 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)  		rc = hypfs_diag_create_files(root_dentry);  	if (rc)  		return rc; -	sbi->update_file = hypfs_create_update_file(root_dentry); -	if (IS_ERR(sbi->update_file)) -		return PTR_ERR(sbi->update_file); +	update_file = hypfs_create_update_file(root_dentry); +	if (IS_ERR(update_file)) +		return PTR_ERR(update_file); +	sbi->update_file = update_file;  	hypfs_update_update(sb);  	pr_info("Hypervisor filesystem mounted\n");  	return 0;  } -static struct dentry *hypfs_mount(struct file_system_type *fst, int flags, -			const char *devname, void *data) +static int hypfs_get_tree(struct fs_context *fc) +{ +	return get_tree_single(fc, hypfs_fill_super); +} + +static void hypfs_free_fc(struct fs_context *fc)  { -	return mount_single(fst, flags, data, hypfs_fill_super); +	kfree(fc->s_fs_info); +} + +static const struct fs_context_operations hypfs_context_ops = { +	.free		= hypfs_free_fc, +	.parse_param	= hypfs_parse_param, +	.get_tree	= hypfs_get_tree, +}; + +static int hypfs_init_fs_context(struct fs_context *fc) +{ +	struct hypfs_sb_info *sbi; + +	sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); +	if (!sbi) +		return -ENOMEM; + +	mutex_init(&sbi->lock); +	sbi->uid = current_uid(); +	sbi->gid = current_gid(); + +	fc->s_fs_info = sbi; +	fc->ops = &hypfs_context_ops; +	return 0;  }  static void hypfs_kill_super(struct super_block *sb) @@ -442,7 +454,8 @@ static const struct file_operations hypfs_file_ops = {  static struct file_system_type hypfs_type = {  	.owner		= THIS_MODULE,  	.name		= "s390_hypfs", -	.mount		= hypfs_mount, +	.init_fs_context = hypfs_init_fs_context, +	.parameters	= &hypfs_fs_parameters,  	.kill_sb	= hypfs_kill_super  }; |