diff options
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r-- | fs/hugetlbfs/inode.c | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index dde861387a40..28d2753be094 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -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; - 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 { @@ -200,7 +200,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, addr = ALIGN(addr, huge_page_size(h)); vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vma->vm_start)) + (!vma || addr + len <= vm_start_gap(vma))) return addr; } @@ -851,6 +851,56 @@ static int hugetlbfs_migrate_page(struct address_space *mapping, return MIGRATEPAGE_SUCCESS; } +static int hugetlbfs_error_remove_page(struct address_space *mapping, + struct page *page) +{ + struct inode *inode = mapping->host; + + remove_huge_page(page); + hugetlb_fix_reserve_counts(inode); + 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) { struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb); @@ -966,6 +1016,7 @@ static const struct address_space_operations hugetlbfs_aops = { .write_end = hugetlbfs_write_end, .set_page_dirty = hugetlbfs_set_page_dirty, .migratepage = hugetlbfs_migrate_page, + .error_remove_page = hugetlbfs_error_remove_page, }; @@ -1008,19 +1059,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 +1093,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 +1207,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 +1227,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 |