Commit e73a75fa authored by Randy Dunlap's avatar Randy Dunlap Committed by Linus Torvalds

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: default avatarRandy Dunlap <randy.dunlap@oracle.com>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Adam Litke <agl@us.ibm.com>
Acked-by: default avatarWilliam Lee Irwin III <wli@holomorphy.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 52161845
...@@ -77,8 +77,9 @@ If the user applications are going to request hugepages using mmap system ...@@ -77,8 +77,9 @@ If the user applications are going to request hugepages using mmap system
call, then it is required that system administrator mount a file system of call, then it is required that system administrator mount a file system of
type hugetlbfs: type hugetlbfs:
mount none /mnt/huge -t hugetlbfs <uid=value> <gid=value> <mode=value> mount -t hugetlbfs \
<size=value> <nr_inodes=value> -o uid=<value>,gid=<value>,mode=<value>,size=<value>,nr_inodes=<value> \
none /mnt/huge
This command mounts a (pseudo) filesystem of type hugetlbfs on the directory This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
/mnt/huge. Any files created on /mnt/huge uses hugepages. The uid and gid /mnt/huge. Any files created on /mnt/huge uses hugepages. The uid and gid
...@@ -88,11 +89,10 @@ mode of root of file system to value & 0777. This value is given in octal. ...@@ -88,11 +89,10 @@ mode of root of file system to value & 0777. This value is given in octal.
By default the value 0755 is picked. The size option sets the maximum value of By default the value 0755 is picked. The size option sets the maximum value of
memory (huge pages) allowed for that filesystem (/mnt/huge). The size is memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
rounded down to HPAGE_SIZE. The option nr_inodes sets the maximum number of rounded down to HPAGE_SIZE. The option nr_inodes sets the maximum number of
inodes that /mnt/huge can use. If the size or nr_inodes options are not inodes that /mnt/huge can use. If the size or nr_inodes option is not
provided on command line then no limits are set. For size and nr_inodes provided on command line then no limits are set. For size and nr_inodes
options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
example, size=2K has the same meaning as size=2048. An example is given at example, size=2K has the same meaning as size=2048.
the end of this document.
read and write system calls are not supported on files that reside on hugetlb read and write system calls are not supported on files that reside on hugetlb
file systems. file systems.
......
...@@ -13,15 +13,18 @@ ...@@ -13,15 +13,18 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/kernel.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/pagevec.h> #include <linux/pagevec.h>
#include <linux/parser.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -47,6 +50,21 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = { ...@@ -47,6 +50,21 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = {
int sysctl_hugetlb_shm_group; 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) static void huge_pagevec_release(struct pagevec *pvec)
{ {
int i; int i;
...@@ -594,46 +612,70 @@ static const struct super_operations hugetlbfs_ops = { ...@@ -594,46 +612,70 @@ static const struct super_operations hugetlbfs_ops = {
static int static int
hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) 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) if (!options)
return 0; return 0;
while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
value = strchr(opt, '='); while ((p = strsep(&options, ",")) != NULL) {
if (!value || !*value) int token;
return -EINVAL;
else token = match_token(p, tokens, args);
*value++ = '\0'; switch (token) {
case Opt_uid:
if (!strcmp(opt, "uid")) if (match_int(&args[0], &option))
pconfig->uid = simple_strtoul(value, &value, 0); goto bad_val;
else if (!strcmp(opt, "gid")) pconfig->uid = option;
pconfig->gid = simple_strtoul(value, &value, 0); break;
else if (!strcmp(opt, "mode"))
pconfig->mode = simple_strtoul(value,&value,0) & 0777U; case Opt_gid:
else if (!strcmp(opt, "size")) { if (match_int(&args[0], &option))
unsigned long long size = memparse(value, &rest); 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 == '%') { if (*rest == '%') {
size <<= HPAGE_SHIFT; size <<= HPAGE_SHIFT;
size *= max_huge_pages; size *= max_huge_pages;
do_div(size, 100); do_div(size, 100);
rest++;
} }
pconfig->nr_blocks = (size >> HPAGE_SHIFT); pconfig->nr_blocks = (size >> HPAGE_SHIFT);
value = rest; break;
} else if (!strcmp(opt,"nr_inodes")) { }
pconfig->nr_inodes = memparse(value, &rest);
value = rest;
} else
return -EINVAL;
if (*value) case Opt_nr_inodes:
return -EINVAL; /* 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; return 0;
bad_val:
printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n",
args[0].from, p);
return 1;
} }
static int static int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment