diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-19 20:06:57 +0300 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-19 20:06:57 +0300 | 
| commit | bc7d9aee3f3ce0c0633c20ea55b81efb3ca7984d (patch) | |
| tree | 24e17a197a1b84d3576a69cd8955fbf8b8a9dc76 /fs/ramfs/inode.c | |
| parent | cfb82e1df8b7c76991ea12958855897c2fb4debc (diff) | |
| parent | 74983ac20aeafc88d9ceed64a8bf2a9024c488d5 (diff) | |
| download | linux-bc7d9aee3f3ce0c0633c20ea55b81efb3ca7984d.tar.xz | |
Merge branch 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc mount API conversions from Al Viro:
 "Conversions to new API for shmem and friends and for mount_mtd()-using
  filesystems.
  As for the rest of the mount API conversions in -next, some of them
  belong in the individual trees (e.g. binderfs one should definitely go
  through android folks, after getting redone on top of their changes).
  I'm going to drop those and send the rest (trivial ones + stuff ACKed
  by maintainers) in a separate series - by that point they are
  independent from each other.
  Some stuff has already migrated into individual trees (NFS conversion,
  for example, or FUSE stuff, etc.); those presumably will go through
  the regular merges from corresponding trees."
* 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  vfs: Make fs_parse() handle fs_param_is_fd-type params better
  vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API
  shmem_parse_one(): switch to use of fs_parse()
  shmem_parse_options(): take handling a single option into a helper
  shmem_parse_options(): don't bother with mpol in separate variable
  shmem_parse_options(): use a separate structure to keep the results
  make shmem_fill_super() static
  make ramfs_fill_super() static
  devtmpfs: don't mix {ramfs,shmem}_fill_super() with mount_single()
  vfs: Convert squashfs to use the new mount API
  mtd: Kill mount_mtd()
  vfs: Convert jffs2 to use the new mount API
  vfs: Convert cramfs to use the new mount API
  vfs: Convert romfs to use the new mount API
  vfs: Add a single-or-reconfig keying to vfs_get_super()
Diffstat (limited to 'fs/ramfs/inode.c')
| -rw-r--r-- | fs/ramfs/inode.c | 99 | 
1 files changed, 58 insertions, 41 deletions
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 733c6b4193dc..d82636e8eb65 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -36,6 +36,8 @@  #include <linux/magic.h>  #include <linux/slab.h>  #include <linux/uaccess.h> +#include <linux/fs_context.h> +#include <linux/fs_parser.h>  #include "internal.h"  struct ramfs_mount_opts { @@ -175,62 +177,52 @@ static const struct super_operations ramfs_ops = {  	.show_options	= ramfs_show_options,  }; -enum { +enum ramfs_param {  	Opt_mode, -	Opt_err  }; -static const match_table_t tokens = { -	{Opt_mode, "mode=%o"}, -	{Opt_err, NULL} +static const struct fs_parameter_spec ramfs_param_specs[] = { +	fsparam_u32oct("mode",	Opt_mode), +	{}  }; -static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) +const struct fs_parameter_description ramfs_fs_parameters = { +	.name		= "ramfs", +	.specs		= ramfs_param_specs, +}; + +static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)  { -	substring_t args[MAX_OPT_ARGS]; -	int option; -	int token; -	char *p; - -	opts->mode = RAMFS_DEFAULT_MODE; - -	while ((p = strsep(&data, ",")) != NULL) { -		if (!*p) -			continue; - -		token = match_token(p, tokens, args); -		switch (token) { -		case Opt_mode: -			if (match_octal(&args[0], &option)) -				return -EINVAL; -			opts->mode = option & S_IALLUGO; -			break; +	struct fs_parse_result result; +	struct ramfs_fs_info *fsi = fc->s_fs_info; +	int opt; + +	opt = fs_parse(fc, &ramfs_fs_parameters, param, &result); +	if (opt < 0) {  		/*  		 * We might like to report bad mount options here;  		 * but traditionally ramfs has ignored all mount options,  		 * and as it is used as a !CONFIG_SHMEM simple substitute  		 * for tmpfs, better continue to ignore other mount options.  		 */ -		} +		if (opt == -ENOPARAM) +			opt = 0; +		return opt; +	} + +	switch (opt) { +	case Opt_mode: +		fsi->mount_opts.mode = result.uint_32 & S_IALLUGO; +		break;  	}  	return 0;  } -int ramfs_fill_super(struct super_block *sb, void *data, int silent) +static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc)  { -	struct ramfs_fs_info *fsi; +	struct ramfs_fs_info *fsi = sb->s_fs_info;  	struct inode *inode; -	int err; - -	fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); -	sb->s_fs_info = fsi; -	if (!fsi) -		return -ENOMEM; - -	err = ramfs_parse_options(data, &fsi->mount_opts); -	if (err) -		return err;  	sb->s_maxbytes		= MAX_LFS_FILESIZE;  	sb->s_blocksize		= PAGE_SIZE; @@ -247,10 +239,34 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent)  	return 0;  } -struct dentry *ramfs_mount(struct file_system_type *fs_type, -	int flags, const char *dev_name, void *data) +static int ramfs_get_tree(struct fs_context *fc)  { -	return mount_nodev(fs_type, flags, data, ramfs_fill_super); +	return get_tree_nodev(fc, ramfs_fill_super); +} + +static void ramfs_free_fc(struct fs_context *fc) +{ +	kfree(fc->s_fs_info); +} + +static const struct fs_context_operations ramfs_context_ops = { +	.free		= ramfs_free_fc, +	.parse_param	= ramfs_parse_param, +	.get_tree	= ramfs_get_tree, +}; + +int ramfs_init_fs_context(struct fs_context *fc) +{ +	struct ramfs_fs_info *fsi; + +	fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); +	if (!fsi) +		return -ENOMEM; + +	fsi->mount_opts.mode = RAMFS_DEFAULT_MODE; +	fc->s_fs_info = fsi; +	fc->ops = &ramfs_context_ops; +	return 0;  }  static void ramfs_kill_sb(struct super_block *sb) @@ -261,7 +277,8 @@ static void ramfs_kill_sb(struct super_block *sb)  static struct file_system_type ramfs_fs_type = {  	.name		= "ramfs", -	.mount		= ramfs_mount, +	.init_fs_context = ramfs_init_fs_context, +	.parameters	= &ramfs_fs_parameters,  	.kill_sb	= ramfs_kill_sb,  	.fs_flags	= FS_USERNS_MOUNT,  };  | 
