aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r--fs/hugetlbfs/inode.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e6b46b3ac2fe..711b801fbcdf 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -13,15 +13,18 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/mount.h> 14#include <linux/mount.h>
15#include <linux/file.h> 15#include <linux/file.h>
16#include <linux/kernel.h>
16#include <linux/writeback.h> 17#include <linux/writeback.h>
17#include <linux/pagemap.h> 18#include <linux/pagemap.h>
18#include <linux/highmem.h> 19#include <linux/highmem.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/string.h> 21#include <linux/string.h>
21#include <linux/capability.h> 22#include <linux/capability.h>
23#include <linux/ctype.h>
22#include <linux/backing-dev.h> 24#include <linux/backing-dev.h>
23#include <linux/hugetlb.h> 25#include <linux/hugetlb.h>
24#include <linux/pagevec.h> 26#include <linux/pagevec.h>
27#include <linux/parser.h>
25#include <linux/mman.h> 28#include <linux/mman.h>
26#include <linux/quotaops.h> 29#include <linux/quotaops.h>
27#include <linux/slab.h> 30#include <linux/slab.h>
@@ -47,6 +50,21 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = {
47 50
48int sysctl_hugetlb_shm_group; 51int sysctl_hugetlb_shm_group;
49 52
53enum {
54 Opt_size, Opt_nr_inodes,
55 Opt_mode, Opt_uid, Opt_gid,
56 Opt_err,
57};
58
59static match_table_t tokens = {
60 {Opt_size, "size=%s"},
61 {Opt_nr_inodes, "nr_inodes=%s"},
62 {Opt_mode, "mode=%o"},
63 {Opt_uid, "uid=%u"},
64 {Opt_gid, "gid=%u"},
65 {Opt_err, NULL},
66};
67
50static void huge_pagevec_release(struct pagevec *pvec) 68static void huge_pagevec_release(struct pagevec *pvec)
51{ 69{
52 int i; 70 int i;
@@ -594,46 +612,70 @@ static const struct super_operations hugetlbfs_ops = {
594static int 612static int
595hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) 613hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
596{ 614{
597 char *opt, *value, *rest; 615 char *p, *rest;
616 substring_t args[MAX_OPT_ARGS];
617 int option;
598 618
599 if (!options) 619 if (!options)
600 return 0; 620 return 0;
601 while ((opt = strsep(&options, ",")) != NULL) {
602 if (!*opt)
603 continue;
604 621
605 value = strchr(opt, '='); 622 while ((p = strsep(&options, ",")) != NULL) {
606 if (!value || !*value) 623 int token;
607 return -EINVAL; 624
608 else 625 token = match_token(p, tokens, args);
609 *value++ = '\0'; 626 switch (token) {
610 627 case Opt_uid:
611 if (!strcmp(opt, "uid")) 628 if (match_int(&args[0], &option))
612 pconfig->uid = simple_strtoul(value, &value, 0); 629 goto bad_val;
613 else if (!strcmp(opt, "gid")) 630 pconfig->uid = option;
614 pconfig->gid = simple_strtoul(value, &value, 0); 631 break;
615 else if (!strcmp(opt, "mode")) 632
616 pconfig->mode = simple_strtoul(value,&value,0) & 0777U; 633 case Opt_gid:
617 else if (!strcmp(opt, "size")) { 634 if (match_int(&args[0], &option))
618 unsigned long long size = memparse(value, &rest); 635 goto bad_val;
636 pconfig->gid = option;
637 break;
638
639 case Opt_mode:
640 if (match_octal(&args[0], &option))
641 goto bad_val;
642 pconfig->mode = option & 0777U;
643 break;
644
645 case Opt_size: {
646 unsigned long long size;
647 /* memparse() will accept a K/M/G without a digit */
648 if (!isdigit(*args[0].from))
649 goto bad_val;
650 size = memparse(args[0].from, &rest);
619 if (*rest == '%') { 651 if (*rest == '%') {
620 size <<= HPAGE_SHIFT; 652 size <<= HPAGE_SHIFT;
621 size *= max_huge_pages; 653 size *= max_huge_pages;
622 do_div(size, 100); 654 do_div(size, 100);
623 rest++;
624 } 655 }
625 pconfig->nr_blocks = (size >> HPAGE_SHIFT); 656 pconfig->nr_blocks = (size >> HPAGE_SHIFT);
626 value = rest; 657 break;
627 } else if (!strcmp(opt,"nr_inodes")) { 658 }
628 pconfig->nr_inodes = memparse(value, &rest);
629 value = rest;
630 } else
631 return -EINVAL;
632 659
633 if (*value) 660 case Opt_nr_inodes:
634 return -EINVAL; 661 /* memparse() will accept a K/M/G without a digit */
662 if (!isdigit(*args[0].from))
663 goto bad_val;
664 pconfig->nr_inodes = memparse(args[0].from, &rest);
665 break;
666
667 default:
668 printk(KERN_ERR "hugetlbfs: Bad mount option: %s\n", p);
669 return 1;
670 break;
671 }
635 } 672 }
636 return 0; 673 return 0;
674
675bad_val:
676 printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n",
677 args[0].from, p);
678 return 1;
637} 679}
638 680
639static int 681static int