aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-07-05 11:24:18 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-07-06 03:31:46 -0400
commit4a25220d4e43bb2461823dbc7eb1502a34087958 (patch)
treefb8a04864c63aecacb7957a924f3c9dadab757e9
parentc3d98ea08291ca26144780f601e1fd39e4f20f7e (diff)
hugetlbfs: Implement show_options
Implement the show_options superblock op for hugetlbfs as part of a bid to get rid of s_options and generic_show_options() to make it easier to implement a context-based mount where the mount options can be passed individually over a file descriptor. Note that the uid and gid should possibly be displayed relative to the viewer's user namespace. Signed-off-by: David Howells <dhowells@redhat.com> cc: Nadia Yvette Chambers <nyc@holomorphy.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/hugetlbfs/inode.c70
-rw-r--r--include/linux/hugetlb.h3
2 files changed, 59 insertions, 14 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index d44f5456eb9b..99b3b9836575 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations;
46static const struct inode_operations hugetlbfs_inode_operations; 46static const struct inode_operations hugetlbfs_inode_operations;
47 47
48struct hugetlbfs_config { 48struct hugetlbfs_config {
49 kuid_t uid; 49 struct hstate *hstate;
50 kgid_t gid; 50 long max_hpages;
51 umode_t mode; 51 long nr_inodes;
52 long max_hpages; 52 long min_hpages;
53 long nr_inodes; 53 kuid_t uid;
54 struct hstate *hstate; 54 kgid_t gid;
55 long min_hpages; 55 umode_t mode;
56}; 56};
57 57
58struct hugetlbfs_inode_info { 58struct hugetlbfs_inode_info {
@@ -851,6 +851,46 @@ static int hugetlbfs_migrate_page(struct address_space *mapping,
851 return MIGRATEPAGE_SUCCESS; 851 return MIGRATEPAGE_SUCCESS;
852} 852}
853 853
854/*
855 * Display the mount options in /proc/mounts.
856 */
857static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root)
858{
859 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb);
860 struct hugepage_subpool *spool = sbinfo->spool;
861 unsigned long hpage_size = huge_page_size(sbinfo->hstate);
862 unsigned hpage_shift = huge_page_shift(sbinfo->hstate);
863 char mod;
864
865 if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
866 seq_printf(m, ",uid=%u",
867 from_kuid_munged(&init_user_ns, sbinfo->uid));
868 if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
869 seq_printf(m, ",gid=%u",
870 from_kgid_munged(&init_user_ns, sbinfo->gid));
871 if (sbinfo->mode != 0755)
872 seq_printf(m, ",mode=%o", sbinfo->mode);
873 if (sbinfo->max_inodes != -1)
874 seq_printf(m, ",nr_inodes=%lu", sbinfo->max_inodes);
875
876 hpage_size /= 1024;
877 mod = 'K';
878 if (hpage_size >= 1024) {
879 hpage_size /= 1024;
880 mod = 'M';
881 }
882 seq_printf(m, ",pagesize=%lu%c", hpage_size, mod);
883 if (spool) {
884 if (spool->max_hpages != -1)
885 seq_printf(m, ",size=%llu",
886 (unsigned long long)spool->max_hpages << hpage_shift);
887 if (spool->min_hpages != -1)
888 seq_printf(m, ",min_size=%llu",
889 (unsigned long long)spool->min_hpages << hpage_shift);
890 }
891 return 0;
892}
893
854static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) 894static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
855{ 895{
856 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb); 896 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
@@ -1008,19 +1048,19 @@ static const struct super_operations hugetlbfs_ops = {
1008 .evict_inode = hugetlbfs_evict_inode, 1048 .evict_inode = hugetlbfs_evict_inode,
1009 .statfs = hugetlbfs_statfs, 1049 .statfs = hugetlbfs_statfs,
1010 .put_super = hugetlbfs_put_super, 1050 .put_super = hugetlbfs_put_super,
1011 .show_options = generic_show_options, 1051 .show_options = hugetlbfs_show_options,
1012}; 1052};
1013 1053
1014enum { NO_SIZE, SIZE_STD, SIZE_PERCENT }; 1054enum hugetlbfs_size_type { NO_SIZE, SIZE_STD, SIZE_PERCENT };
1015 1055
1016/* 1056/*
1017 * Convert size option passed from command line to number of huge pages 1057 * Convert size option passed from command line to number of huge pages
1018 * in the pool specified by hstate. Size option could be in bytes 1058 * in the pool specified by hstate. Size option could be in bytes
1019 * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT). 1059 * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
1020 */ 1060 */
1021static long long 1061static long
1022hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt, 1062hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
1023 int val_type) 1063 enum hugetlbfs_size_type val_type)
1024{ 1064{
1025 if (val_type == NO_SIZE) 1065 if (val_type == NO_SIZE)
1026 return -1; 1066 return -1;
@@ -1042,7 +1082,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
1042 substring_t args[MAX_OPT_ARGS]; 1082 substring_t args[MAX_OPT_ARGS];
1043 int option; 1083 int option;
1044 unsigned long long max_size_opt = 0, min_size_opt = 0; 1084 unsigned long long max_size_opt = 0, min_size_opt = 0;
1045 int max_val_type = NO_SIZE, min_val_type = NO_SIZE; 1085 enum hugetlbfs_size_type max_val_type = NO_SIZE, min_val_type = NO_SIZE;
1046 1086
1047 if (!options) 1087 if (!options)
1048 return 0; 1088 return 0;
@@ -1156,8 +1196,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
1156 struct hugetlbfs_config config; 1196 struct hugetlbfs_config config;
1157 struct hugetlbfs_sb_info *sbinfo; 1197 struct hugetlbfs_sb_info *sbinfo;
1158 1198
1159 save_mount_options(sb, data);
1160
1161 config.max_hpages = -1; /* No limit on size by default */ 1199 config.max_hpages = -1; /* No limit on size by default */
1162 config.nr_inodes = -1; /* No limit on number of inodes by default */ 1200 config.nr_inodes = -1; /* No limit on number of inodes by default */
1163 config.uid = current_fsuid(); 1201 config.uid = current_fsuid();
@@ -1178,6 +1216,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
1178 sbinfo->max_inodes = config.nr_inodes; 1216 sbinfo->max_inodes = config.nr_inodes;
1179 sbinfo->free_inodes = config.nr_inodes; 1217 sbinfo->free_inodes = config.nr_inodes;
1180 sbinfo->spool = NULL; 1218 sbinfo->spool = NULL;
1219 sbinfo->uid = config.uid;
1220 sbinfo->gid = config.gid;
1221 sbinfo->mode = config.mode;
1222
1181 /* 1223 /*
1182 * Allocate and initialize subpool if maximum or minimum size is 1224 * Allocate and initialize subpool if maximum or minimum size is
1183 * specified. Any needed reservations (for minimim size) are taken 1225 * specified. Any needed reservations (for minimim size) are taken
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index b857fc8cc2ec..3b6eeaad2f77 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -262,6 +262,9 @@ struct hugetlbfs_sb_info {
262 spinlock_t stat_lock; 262 spinlock_t stat_lock;
263 struct hstate *hstate; 263 struct hstate *hstate;
264 struct hugepage_subpool *spool; 264 struct hugepage_subpool *spool;
265 kuid_t uid;
266 kgid_t gid;
267 umode_t mode;
265}; 268};
266 269
267static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) 270static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)