|
@@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations;
|
|
static const struct inode_operations hugetlbfs_inode_operations;
|
|
static const struct inode_operations hugetlbfs_inode_operations;
|
|
|
|
|
|
struct hugetlbfs_config {
|
|
struct hugetlbfs_config {
|
|
- kuid_t uid;
|
|
|
|
- kgid_t gid;
|
|
|
|
- umode_t mode;
|
|
|
|
- long max_hpages;
|
|
|
|
- long nr_inodes;
|
|
|
|
- struct hstate *hstate;
|
|
|
|
- long min_hpages;
|
|
|
|
|
|
+ struct hstate *hstate;
|
|
|
|
+ long max_hpages;
|
|
|
|
+ long nr_inodes;
|
|
|
|
+ long min_hpages;
|
|
|
|
+ kuid_t uid;
|
|
|
|
+ kgid_t gid;
|
|
|
|
+ umode_t mode;
|
|
};
|
|
};
|
|
|
|
|
|
struct hugetlbfs_inode_info {
|
|
struct hugetlbfs_inode_info {
|
|
@@ -861,6 +861,46 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Display the mount options in /proc/mounts.
|
|
|
|
+ */
|
|
|
|
+static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root)
|
|
|
|
+{
|
|
|
|
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb);
|
|
|
|
+ struct hugepage_subpool *spool = sbinfo->spool;
|
|
|
|
+ unsigned long hpage_size = huge_page_size(sbinfo->hstate);
|
|
|
|
+ unsigned hpage_shift = huge_page_shift(sbinfo->hstate);
|
|
|
|
+ char mod;
|
|
|
|
+
|
|
|
|
+ if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
|
|
|
|
+ seq_printf(m, ",uid=%u",
|
|
|
|
+ from_kuid_munged(&init_user_ns, sbinfo->uid));
|
|
|
|
+ if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
|
|
|
|
+ seq_printf(m, ",gid=%u",
|
|
|
|
+ from_kgid_munged(&init_user_ns, sbinfo->gid));
|
|
|
|
+ if (sbinfo->mode != 0755)
|
|
|
|
+ seq_printf(m, ",mode=%o", sbinfo->mode);
|
|
|
|
+ if (sbinfo->max_inodes != -1)
|
|
|
|
+ seq_printf(m, ",nr_inodes=%lu", sbinfo->max_inodes);
|
|
|
|
+
|
|
|
|
+ hpage_size /= 1024;
|
|
|
|
+ mod = 'K';
|
|
|
|
+ if (hpage_size >= 1024) {
|
|
|
|
+ hpage_size /= 1024;
|
|
|
|
+ mod = 'M';
|
|
|
|
+ }
|
|
|
|
+ seq_printf(m, ",pagesize=%lu%c", hpage_size, mod);
|
|
|
|
+ if (spool) {
|
|
|
|
+ if (spool->max_hpages != -1)
|
|
|
|
+ seq_printf(m, ",size=%llu",
|
|
|
|
+ (unsigned long long)spool->max_hpages << hpage_shift);
|
|
|
|
+ if (spool->min_hpages != -1)
|
|
|
|
+ seq_printf(m, ",min_size=%llu",
|
|
|
|
+ (unsigned long long)spool->min_hpages << hpage_shift);
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|
static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|
{
|
|
{
|
|
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
|
|
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
|
|
@@ -1019,19 +1059,19 @@ static const struct super_operations hugetlbfs_ops = {
|
|
.evict_inode = hugetlbfs_evict_inode,
|
|
.evict_inode = hugetlbfs_evict_inode,
|
|
.statfs = hugetlbfs_statfs,
|
|
.statfs = hugetlbfs_statfs,
|
|
.put_super = hugetlbfs_put_super,
|
|
.put_super = hugetlbfs_put_super,
|
|
- .show_options = generic_show_options,
|
|
|
|
|
|
+ .show_options = hugetlbfs_show_options,
|
|
};
|
|
};
|
|
|
|
|
|
-enum { NO_SIZE, SIZE_STD, SIZE_PERCENT };
|
|
|
|
|
|
+enum hugetlbfs_size_type { NO_SIZE, SIZE_STD, SIZE_PERCENT };
|
|
|
|
|
|
/*
|
|
/*
|
|
* Convert size option passed from command line to number of huge pages
|
|
* Convert size option passed from command line to number of huge pages
|
|
* in the pool specified by hstate. Size option could be in bytes
|
|
* in the pool specified by hstate. Size option could be in bytes
|
|
* (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
|
|
* (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
|
|
*/
|
|
*/
|
|
-static long long
|
|
|
|
|
|
+static long
|
|
hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
|
|
hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
|
|
- int val_type)
|
|
|
|
|
|
+ enum hugetlbfs_size_type val_type)
|
|
{
|
|
{
|
|
if (val_type == NO_SIZE)
|
|
if (val_type == NO_SIZE)
|
|
return -1;
|
|
return -1;
|
|
@@ -1053,7 +1093,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
|
|
substring_t args[MAX_OPT_ARGS];
|
|
substring_t args[MAX_OPT_ARGS];
|
|
int option;
|
|
int option;
|
|
unsigned long long max_size_opt = 0, min_size_opt = 0;
|
|
unsigned long long max_size_opt = 0, min_size_opt = 0;
|
|
- int max_val_type = NO_SIZE, min_val_type = NO_SIZE;
|
|
|
|
|
|
+ enum hugetlbfs_size_type max_val_type = NO_SIZE, min_val_type = NO_SIZE;
|
|
|
|
|
|
if (!options)
|
|
if (!options)
|
|
return 0;
|
|
return 0;
|
|
@@ -1167,8 +1207,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
struct hugetlbfs_config config;
|
|
struct hugetlbfs_config config;
|
|
struct hugetlbfs_sb_info *sbinfo;
|
|
struct hugetlbfs_sb_info *sbinfo;
|
|
|
|
|
|
- save_mount_options(sb, data);
|
|
|
|
-
|
|
|
|
config.max_hpages = -1; /* No limit on size by default */
|
|
config.max_hpages = -1; /* No limit on size by default */
|
|
config.nr_inodes = -1; /* No limit on number of inodes by default */
|
|
config.nr_inodes = -1; /* No limit on number of inodes by default */
|
|
config.uid = current_fsuid();
|
|
config.uid = current_fsuid();
|
|
@@ -1189,6 +1227,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
sbinfo->max_inodes = config.nr_inodes;
|
|
sbinfo->max_inodes = config.nr_inodes;
|
|
sbinfo->free_inodes = config.nr_inodes;
|
|
sbinfo->free_inodes = config.nr_inodes;
|
|
sbinfo->spool = NULL;
|
|
sbinfo->spool = NULL;
|
|
|
|
+ sbinfo->uid = config.uid;
|
|
|
|
+ sbinfo->gid = config.gid;
|
|
|
|
+ sbinfo->mode = config.mode;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Allocate and initialize subpool if maximum or minimum size is
|
|
* Allocate and initialize subpool if maximum or minimum size is
|
|
* specified. Any needed reservations (for minimim size) are taken
|
|
* specified. Any needed reservations (for minimim size) are taken
|