diff options
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r-- | fs/hugetlbfs/inode.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8349a899912e..c5bc355d8243 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -42,8 +42,8 @@ static const struct inode_operations hugetlbfs_dir_inode_operations; | |||
42 | static const struct inode_operations hugetlbfs_inode_operations; | 42 | static const struct inode_operations hugetlbfs_inode_operations; |
43 | 43 | ||
44 | struct hugetlbfs_config { | 44 | struct hugetlbfs_config { |
45 | uid_t uid; | 45 | kuid_t uid; |
46 | gid_t gid; | 46 | kgid_t gid; |
47 | umode_t mode; | 47 | umode_t mode; |
48 | long nr_blocks; | 48 | long nr_blocks; |
49 | long nr_inodes; | 49 | long nr_inodes; |
@@ -110,7 +110,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
110 | * way when do_mmap_pgoff unwinds (may be important on powerpc | 110 | * way when do_mmap_pgoff unwinds (may be important on powerpc |
111 | * and ia64). | 111 | * and ia64). |
112 | */ | 112 | */ |
113 | vma->vm_flags |= VM_HUGETLB | VM_RESERVED; | 113 | vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP; |
114 | vma->vm_ops = &hugetlb_vm_ops; | 114 | vma->vm_ops = &hugetlb_vm_ops; |
115 | 115 | ||
116 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) | 116 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) |
@@ -397,17 +397,16 @@ static void hugetlbfs_evict_inode(struct inode *inode) | |||
397 | } | 397 | } |
398 | 398 | ||
399 | static inline void | 399 | static inline void |
400 | hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff) | 400 | hugetlb_vmtruncate_list(struct rb_root *root, pgoff_t pgoff) |
401 | { | 401 | { |
402 | struct vm_area_struct *vma; | 402 | struct vm_area_struct *vma; |
403 | struct prio_tree_iter iter; | ||
404 | 403 | ||
405 | vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) { | 404 | vma_interval_tree_foreach(vma, root, pgoff, ULONG_MAX) { |
406 | unsigned long v_offset; | 405 | unsigned long v_offset; |
407 | 406 | ||
408 | /* | 407 | /* |
409 | * Can the expression below overflow on 32-bit arches? | 408 | * Can the expression below overflow on 32-bit arches? |
410 | * No, because the prio_tree returns us only those vmas | 409 | * No, because the interval tree returns us only those vmas |
411 | * which overlap the truncated area starting at pgoff, | 410 | * which overlap the truncated area starting at pgoff, |
412 | * and no vma on a 32-bit arch can span beyond the 4GB. | 411 | * and no vma on a 32-bit arch can span beyond the 4GB. |
413 | */ | 412 | */ |
@@ -432,7 +431,7 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) | |||
432 | 431 | ||
433 | i_size_write(inode, offset); | 432 | i_size_write(inode, offset); |
434 | mutex_lock(&mapping->i_mmap_mutex); | 433 | mutex_lock(&mapping->i_mmap_mutex); |
435 | if (!prio_tree_empty(&mapping->i_mmap)) | 434 | if (!RB_EMPTY_ROOT(&mapping->i_mmap)) |
436 | hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); | 435 | hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); |
437 | mutex_unlock(&mapping->i_mmap_mutex); | 436 | mutex_unlock(&mapping->i_mmap_mutex); |
438 | truncate_hugepages(inode, offset); | 437 | truncate_hugepages(inode, offset); |
@@ -785,13 +784,17 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) | |||
785 | case Opt_uid: | 784 | case Opt_uid: |
786 | if (match_int(&args[0], &option)) | 785 | if (match_int(&args[0], &option)) |
787 | goto bad_val; | 786 | goto bad_val; |
788 | pconfig->uid = option; | 787 | pconfig->uid = make_kuid(current_user_ns(), option); |
788 | if (!uid_valid(pconfig->uid)) | ||
789 | goto bad_val; | ||
789 | break; | 790 | break; |
790 | 791 | ||
791 | case Opt_gid: | 792 | case Opt_gid: |
792 | if (match_int(&args[0], &option)) | 793 | if (match_int(&args[0], &option)) |
793 | goto bad_val; | 794 | goto bad_val; |
794 | pconfig->gid = option; | 795 | pconfig->gid = make_kgid(current_user_ns(), option); |
796 | if (!gid_valid(pconfig->gid)) | ||
797 | goto bad_val; | ||
795 | break; | 798 | break; |
796 | 799 | ||
797 | case Opt_mode: | 800 | case Opt_mode: |
@@ -924,7 +927,9 @@ static struct vfsmount *hugetlbfs_vfsmount; | |||
924 | 927 | ||
925 | static int can_do_hugetlb_shm(void) | 928 | static int can_do_hugetlb_shm(void) |
926 | { | 929 | { |
927 | return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); | 930 | kgid_t shm_group; |
931 | shm_group = make_kgid(&init_user_ns, sysctl_hugetlb_shm_group); | ||
932 | return capable(CAP_IPC_LOCK) || in_group_p(shm_group); | ||
928 | } | 933 | } |
929 | 934 | ||
930 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, | 935 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, |
@@ -1042,6 +1047,11 @@ static int __init init_hugetlbfs_fs(void) | |||
1042 | 1047 | ||
1043 | static void __exit exit_hugetlbfs_fs(void) | 1048 | static void __exit exit_hugetlbfs_fs(void) |
1044 | { | 1049 | { |
1050 | /* | ||
1051 | * Make sure all delayed rcu free inodes are flushed before we | ||
1052 | * destroy cache. | ||
1053 | */ | ||
1054 | rcu_barrier(); | ||
1045 | kmem_cache_destroy(hugetlbfs_inode_cachep); | 1055 | kmem_cache_destroy(hugetlbfs_inode_cachep); |
1046 | kern_unmount(hugetlbfs_vfsmount); | 1056 | kern_unmount(hugetlbfs_vfsmount); |
1047 | unregister_filesystem(&hugetlbfs_fs_type); | 1057 | unregister_filesystem(&hugetlbfs_fs_type); |