diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2019-09-08 19:20:12 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2019-09-12 21:00:32 -0400 |
commit | e04dc423ae2c0fc862fef6b43ed9083226375e98 (patch) | |
tree | 2b3f2970c88abdff73aa43fc0d13b69fe97bd4d4 /mm | |
parent | f6490b7fbb8216e15c0b52409b5fd9d035fe3530 (diff) | |
download | linux-e04dc423ae2c0fc862fef6b43ed9083226375e98.tar.bz2 |
shmem_parse_options(): take handling a single option into a helper
mechanical move.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/shmem.c | 148 |
1 files changed, 79 insertions, 69 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 8bca06c12b9a..b392a8263329 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3363,12 +3363,88 @@ static const struct export_operations shmem_export_ops = { .fh_to_dentry = shmem_fh_to_dentry, }; -static int shmem_parse_options(char *options, struct shmem_options *ctx) +static int shmem_parse_one(struct shmem_options *ctx, char *opt, char *value) { - char *this_char, *value, *rest; + char *rest; uid_t uid; gid_t gid; + if (!strcmp(opt, "size")) { + unsigned long long size; + size = memparse(value,&rest); + if (*rest == '%') { + size <<= PAGE_SHIFT; + size *= totalram_pages(); + do_div(size, 100); + rest++; + } + if (*rest) + goto bad_val; + ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE); + ctx->seen |= SHMEM_SEEN_BLOCKS; + } else if (!strcmp(opt, "nr_blocks")) { + ctx->blocks = memparse(value, &rest); + if (*rest) + goto bad_val; + ctx->seen |= SHMEM_SEEN_BLOCKS; + } else if (!strcmp(opt, "nr_inodes")) { + ctx->inodes = memparse(value, &rest); + if (*rest) + goto bad_val; + ctx->seen |= SHMEM_SEEN_INODES; + } else if (!strcmp(opt, "mode")) { + ctx->mode = simple_strtoul(value, &rest, 8) & 07777; + if (*rest) + goto bad_val; + } else if (!strcmp(opt, "uid")) { + uid = simple_strtoul(value, &rest, 0); + if (*rest) + goto bad_val; + ctx->uid = make_kuid(current_user_ns(), uid); + if (!uid_valid(ctx->uid)) + goto bad_val; + } else if (!strcmp(opt, "gid")) { + gid = simple_strtoul(value, &rest, 0); + if (*rest) + goto bad_val; + ctx->gid = make_kgid(current_user_ns(), gid); + if (!gid_valid(ctx->gid)) + goto bad_val; +#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE + } else if (!strcmp(opt, "huge")) { + int huge; + huge = shmem_parse_huge(value); + if (huge < 0) + goto bad_val; + if (!has_transparent_hugepage() && + huge != SHMEM_HUGE_NEVER) + goto bad_val; + ctx->huge = huge; + ctx->seen |= SHMEM_SEEN_HUGE; +#endif +#ifdef CONFIG_NUMA + } else if (!strcmp(opt, "mpol")) { + mpol_put(ctx->mpol); + ctx->mpol = NULL; + if (mpol_parse_str(value, &ctx->mpol)) + goto bad_val; +#endif + } else { + pr_err("tmpfs: Bad mount option %s\n", opt); + return -EINVAL; + } + return 0; + +bad_val: + pr_err("tmpfs: Bad value '%s' for mount option '%s'\n", + value, opt); + return -EINVAL; +} + +static int shmem_parse_options(char *options, struct shmem_options *ctx) +{ + char *this_char, *value; + while (options != NULL) { this_char = options; for (;;) { @@ -3395,77 +3471,11 @@ static int shmem_parse_options(char *options, struct shmem_options *ctx) this_char); goto error; } - - if (!strcmp(this_char,"size")) { - unsigned long long size; - size = memparse(value,&rest); - if (*rest == '%') { - size <<= PAGE_SHIFT; - size *= totalram_pages(); - do_div(size, 100); - rest++; - } - if (*rest) - goto bad_val; - ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE); - ctx->seen |= SHMEM_SEEN_BLOCKS; - } else if (!strcmp(this_char,"nr_blocks")) { - ctx->blocks = memparse(value, &rest); - if (*rest) - goto bad_val; - ctx->seen |= SHMEM_SEEN_BLOCKS; - } else if (!strcmp(this_char,"nr_inodes")) { - ctx->inodes = memparse(value, &rest); - if (*rest) - goto bad_val; - ctx->seen |= SHMEM_SEEN_INODES; - } else if (!strcmp(this_char,"mode")) { - ctx->mode = simple_strtoul(value, &rest, 8) & 07777; - if (*rest) - goto bad_val; - } else if (!strcmp(this_char,"uid")) { - uid = simple_strtoul(value, &rest, 0); - if (*rest) - goto bad_val; - ctx->uid = make_kuid(current_user_ns(), uid); - if (!uid_valid(ctx->uid)) - goto bad_val; - } else if (!strcmp(this_char,"gid")) { - gid = simple_strtoul(value, &rest, 0); - if (*rest) - goto bad_val; - ctx->gid = make_kgid(current_user_ns(), gid); - if (!gid_valid(ctx->gid)) - goto bad_val; -#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE - } else if (!strcmp(this_char, "huge")) { - int huge; - huge = shmem_parse_huge(value); - if (huge < 0) - goto bad_val; - if (!has_transparent_hugepage() && - huge != SHMEM_HUGE_NEVER) - goto bad_val; - ctx->huge = huge; - ctx->seen |= SHMEM_SEEN_HUGE; -#endif -#ifdef CONFIG_NUMA - } else if (!strcmp(this_char,"mpol")) { - mpol_put(ctx->mpol); - ctx->mpol = NULL; - if (mpol_parse_str(value, &ctx->mpol)) - goto bad_val; -#endif - } else { - pr_err("tmpfs: Bad mount option %s\n", this_char); + if (shmem_parse_one(ctx, this_char, value) < 0) goto error; - } } return 0; -bad_val: - pr_err("tmpfs: Bad value '%s' for mount option '%s'\n", - value, this_char); error: mpol_put(ctx->mpol); ctx->mpol = NULL; |