diff options
author | Steven Truelove <steven.truelove@utoronto.ca> | 2012-03-21 19:34:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 20:54:59 -0400 |
commit | 40716e29243de46720e5773797791466c28904ec (patch) | |
tree | 19616ad05cbead73d0643b002a7ced8baa292ee2 /fs | |
parent | 21a3c273f88c9cbbaf7e14505df0131d95c8f262 (diff) |
hugetlbfs: fix alignment of huge page requests
When calling shmget() with SHM_HUGETLB, shmget aligns the request size to
PAGE_SIZE, but this is not sufficient.
Modify hugetlb_file_setup() to align requests to the huge page size, and
to accept an address argument so that all alignment checks can be
performed in hugetlb_file_setup(), rather than in its callers. Change
newseg() and mmap_pgoff() to match the new prototype and eliminate a now
redundant alignment check.
[akpm@linux-foundation.org: fix build]
Signed-off-by: Steven Truelove <steven.truelove@utoronto.ca>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hugetlbfs/inode.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 79408159a001..631329f3de63 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -935,8 +935,8 @@ static int can_do_hugetlb_shm(void) | |||
935 | return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); | 935 | return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); |
936 | } | 936 | } |
937 | 937 | ||
938 | struct file *hugetlb_file_setup(const char *name, size_t size, | 938 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, |
939 | vm_flags_t acctflag, | 939 | size_t size, vm_flags_t acctflag, |
940 | struct user_struct **user, int creat_flags) | 940 | struct user_struct **user, int creat_flags) |
941 | { | 941 | { |
942 | int error = -ENOMEM; | 942 | int error = -ENOMEM; |
@@ -945,6 +945,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size, | |||
945 | struct path path; | 945 | struct path path; |
946 | struct dentry *root; | 946 | struct dentry *root; |
947 | struct qstr quick_string; | 947 | struct qstr quick_string; |
948 | struct hstate *hstate; | ||
949 | unsigned long num_pages; | ||
948 | 950 | ||
949 | *user = NULL; | 951 | *user = NULL; |
950 | if (!hugetlbfs_vfsmount) | 952 | if (!hugetlbfs_vfsmount) |
@@ -978,10 +980,12 @@ struct file *hugetlb_file_setup(const char *name, size_t size, | |||
978 | if (!inode) | 980 | if (!inode) |
979 | goto out_dentry; | 981 | goto out_dentry; |
980 | 982 | ||
983 | hstate = hstate_inode(inode); | ||
984 | size += addr & ~huge_page_mask(hstate); | ||
985 | num_pages = ALIGN(size, huge_page_size(hstate)) >> | ||
986 | huge_page_shift(hstate); | ||
981 | error = -ENOMEM; | 987 | error = -ENOMEM; |
982 | if (hugetlb_reserve_pages(inode, 0, | 988 | if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag)) |
983 | size >> huge_page_shift(hstate_inode(inode)), NULL, | ||
984 | acctflag)) | ||
985 | goto out_inode; | 989 | goto out_inode; |
986 | 990 | ||
987 | d_instantiate(path.dentry, inode); | 991 | d_instantiate(path.dentry, inode); |