From e73a75fa7f062b52d015f1c961685dcaac57f710 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 15 Jul 2007 23:40:52 -0700 Subject: hugetlbfs: use lib/parser, fix docs Use lib/parser.c to parse hugetlbfs mount options. Correct docs in hugetlbpage.txt. old size of hugetlbfs_fill_super: 675 bytes new size of hugetlbfs_fill_super: 686 bytes (hugetlbfs_parse_options() is inlined) Signed-off-by: Randy Dunlap Cc: Hugh Dickins Cc: David Gibson Cc: Adam Litke Acked-by: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 96 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 27 deletions(-) (limited to 'fs') diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index e6b46b3..711b801 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -13,15 +13,18 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -47,6 +50,21 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = { int sysctl_hugetlb_shm_group; +enum { + Opt_size, Opt_nr_inodes, + Opt_mode, Opt_uid, Opt_gid, + Opt_err, +}; + +static match_table_t tokens = { + {Opt_size, "size=%s"}, + {Opt_nr_inodes, "nr_inodes=%s"}, + {Opt_mode, "mode=%o"}, + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_err, NULL}, +}; + static void huge_pagevec_release(struct pagevec *pvec) { int i; @@ -594,46 +612,70 @@ static const struct super_operations hugetlbfs_ops = { static int hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) { - char *opt, *value, *rest; + char *p, *rest; + substring_t args[MAX_OPT_ARGS]; + int option; if (!options) return 0; - while ((opt = strsep(&options, ",")) != NULL) { - if (!*opt) - continue; - value = strchr(opt, '='); - if (!value || !*value) - return -EINVAL; - else - *value++ = '\0'; - - if (!strcmp(opt, "uid")) - pconfig->uid = simple_strtoul(value, &value, 0); - else if (!strcmp(opt, "gid")) - pconfig->gid = simple_strtoul(value, &value, 0); - else if (!strcmp(opt, "mode")) - pconfig->mode = simple_strtoul(value,&value,0) & 0777U; - else if (!strcmp(opt, "size")) { - unsigned long long size = memparse(value, &rest); + while ((p = strsep(&options, ",")) != NULL) { + int token; + + token = match_token(p, tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + goto bad_val; + pconfig->uid = option; + break; + + case Opt_gid: + if (match_int(&args[0], &option)) + goto bad_val; + pconfig->gid = option; + break; + + case Opt_mode: + if (match_octal(&args[0], &option)) + goto bad_val; + pconfig->mode = option & 0777U; + break; + + case Opt_size: { + unsigned long long size; + /* memparse() will accept a K/M/G without a digit */ + if (!isdigit(*args[0].from)) + goto bad_val; + size = memparse(args[0].from, &rest); if (*rest == '%') { size <<= HPAGE_SHIFT; size *= max_huge_pages; do_div(size, 100); - rest++; } pconfig->nr_blocks = (size >> HPAGE_SHIFT); - value = rest; - } else if (!strcmp(opt,"nr_inodes")) { - pconfig->nr_inodes = memparse(value, &rest); - value = rest; - } else - return -EINVAL; + break; + } - if (*value) - return -EINVAL; + case Opt_nr_inodes: + /* memparse() will accept a K/M/G without a digit */ + if (!isdigit(*args[0].from)) + goto bad_val; + pconfig->nr_inodes = memparse(args[0].from, &rest); + break; + + default: + printk(KERN_ERR "hugetlbfs: Bad mount option: %s\n", p); + return 1; + break; + } } return 0; + +bad_val: + printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n", + args[0].from, p); + return 1; } static int -- cgit v1.1