diff options
author | David Howells <dhowells@redhat.com> | 2017-07-05 11:24:18 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-06 03:31:46 -0400 |
commit | 4a25220d4e43bb2461823dbc7eb1502a34087958 (patch) | |
tree | fb8a04864c63aecacb7957a924f3c9dadab757e9 | |
parent | c3d98ea08291ca26144780f601e1fd39e4f20f7e (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.c | 70 | ||||
-rw-r--r-- | include/linux/hugetlb.h | 3 |
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; | |||
46 | static const struct inode_operations hugetlbfs_inode_operations; | 46 | static const struct inode_operations hugetlbfs_inode_operations; |
47 | 47 | ||
48 | struct hugetlbfs_config { | 48 | struct 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 | ||
58 | struct hugetlbfs_inode_info { | 58 | struct 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 | */ | ||
857 | static 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 | |||
854 | static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 894 | static 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 | ||
1014 | enum { NO_SIZE, SIZE_STD, SIZE_PERCENT }; | 1054 | enum 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 | */ |
1021 | static long long | 1061 | static long |
1022 | hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt, | 1062 | hugetlbfs_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 | ||
267 | static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) | 270 | static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) |