Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a25220d authored by David Howells's avatar David Howells Committed by Al Viro
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
cc: Nadia Yvette Chambers <nyc@holomorphy.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c3d98ea0
Loading
Loading
Loading
Loading
+56 −14
Original line number Diff line number Diff line
@@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations;
static const struct inode_operations hugetlbfs_inode_operations;

struct hugetlbfs_config {
	kuid_t   uid;
	kgid_t   gid;
	umode_t mode;
	struct hstate		*hstate;
	long			max_hpages;
	long			nr_inodes;
	struct hstate *hstate;
	long			min_hpages;
	kuid_t			uid;
	kgid_t			gid;
	umode_t			mode;
};

struct hugetlbfs_inode_info {
@@ -851,6 +851,46 @@ static int hugetlbfs_migrate_page(struct address_space *mapping,
	return MIGRATEPAGE_SUCCESS;
}

/*
 * 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)
{
	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
@@ -1008,19 +1048,19 @@ static const struct super_operations hugetlbfs_ops = {
	.evict_inode	= hugetlbfs_evict_inode,
	.statfs		= hugetlbfs_statfs,
	.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
 * 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).
 */
static long long
static long
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)
		return -1;
@@ -1042,7 +1082,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
	substring_t args[MAX_OPT_ARGS];
	int option;
	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)
		return 0;
@@ -1156,8 +1196,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
	struct hugetlbfs_config config;
	struct hugetlbfs_sb_info *sbinfo;

	save_mount_options(sb, data);

	config.max_hpages = -1; /* No limit on size by default */
	config.nr_inodes = -1; /* No limit on number of inodes by default */
	config.uid = current_fsuid();
@@ -1178,6 +1216,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
	sbinfo->max_inodes = config.nr_inodes;
	sbinfo->free_inodes = config.nr_inodes;
	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
	 * specified.  Any needed reservations (for minimim size) are taken
+3 −0
Original line number Diff line number Diff line
@@ -262,6 +262,9 @@ struct hugetlbfs_sb_info {
	spinlock_t	stat_lock;
	struct hstate *hstate;
	struct hugepage_subpool *spool;
	kuid_t	uid;
	kgid_t	gid;
	umode_t mode;
};

static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)