mac80211_hwsim: Make sure beacon_timer gets deleted
[safe/jmp/linux-2.6] / fs / hugetlbfs / inode.c
index 516c581..61edc70 100644 (file)
@@ -53,15 +53,17 @@ int sysctl_hugetlb_shm_group;
 enum {
        Opt_size, Opt_nr_inodes,
        Opt_mode, Opt_uid, Opt_gid,
+       Opt_pagesize,
        Opt_err,
 };
 
-static match_table_t tokens = {
+static const 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_pagesize,  "pagesize=%s"},
        {Opt_err,       NULL},
 };
 
@@ -703,7 +705,7 @@ static const struct address_space_operations hugetlbfs_aops = {
 };
 
 
-static void init_once(struct kmem_cache *cachep, void *foo)
+static void init_once(void *foo)
 {
        struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
 
@@ -750,6 +752,8 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
        char *p, *rest;
        substring_t args[MAX_OPT_ARGS];
        int option;
+       unsigned long long size = 0;
+       enum { NO_SIZE, SIZE_STD, SIZE_PERCENT } setsize = NO_SIZE;
 
        if (!options)
                return 0;
@@ -780,17 +784,13 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
                        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);
-                       }
-                       pconfig->nr_blocks = (size >> HPAGE_SHIFT);
+                       setsize = SIZE_STD;
+                       if (*rest == '%')
+                               setsize = SIZE_PERCENT;
                        break;
                }
 
@@ -801,6 +801,19 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
                        pconfig->nr_inodes = memparse(args[0].from, &rest);
                        break;
 
+               case Opt_pagesize: {
+                       unsigned long ps;
+                       ps = memparse(args[0].from, &rest);
+                       pconfig->hstate = size_to_hstate(ps);
+                       if (!pconfig->hstate) {
+                               printk(KERN_ERR
+                               "hugetlbfs: Unsupported page size %lu MB\n",
+                                       ps >> 20);
+                               return -EINVAL;
+                       }
+                       break;
+               }
+
                default:
                        printk(KERN_ERR "hugetlbfs: Bad mount option: \"%s\"\n",
                                 p);
@@ -808,6 +821,18 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
                        break;
                }
        }
+
+       /* Do size after hstate is set up */
+       if (setsize > NO_SIZE) {
+               struct hstate *h = pconfig->hstate;
+               if (setsize == SIZE_PERCENT) {
+                       size <<= huge_page_shift(h);
+                       size *= h->max_huge_pages;
+                       do_div(size, 100);
+               }
+               pconfig->nr_blocks = (size >> huge_page_shift(h));
+       }
+
        return 0;
 
 bad_val:
@@ -832,6 +857,7 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
        config.uid = current->fsuid;
        config.gid = current->fsgid;
        config.mode = 0755;
+       config.hstate = &default_hstate;
        ret = hugetlbfs_parse_options(data, &config);
        if (ret)
                return ret;
@@ -840,14 +866,15 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
        if (!sbinfo)
                return -ENOMEM;
        sb->s_fs_info = sbinfo;
+       sbinfo->hstate = config.hstate;
        spin_lock_init(&sbinfo->stat_lock);
        sbinfo->max_blocks = config.nr_blocks;
        sbinfo->free_blocks = config.nr_blocks;
        sbinfo->max_inodes = config.nr_inodes;
        sbinfo->free_inodes = config.nr_inodes;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
-       sb->s_blocksize = HPAGE_SIZE;
-       sb->s_blocksize_bits = HPAGE_SHIFT;
+       sb->s_blocksize = huge_page_size(config.hstate);
+       sb->s_blocksize_bits = huge_page_shift(config.hstate);
        sb->s_magic = HUGETLBFS_MAGIC;
        sb->s_op = &hugetlbfs_ops;
        sb->s_time_gran = 1;