diff options
Diffstat (limited to 'fs/hugetlbfs/inode.c')
| -rw-r--r-- | fs/hugetlbfs/inode.c | 24 | 
1 files changed, 10 insertions, 14 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 523464e6284..a3f868ae3fd 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -909,11 +909,8 @@ static int can_do_hugetlb_shm(void)  static int get_hstate_idx(int page_size_log)  { -	struct hstate *h; +	struct hstate *h = hstate_sizelog(page_size_log); -	if (!page_size_log) -		return default_hstate_idx; -	h = size_to_hstate(1 << page_size_log);  	if (!h)  		return -1;  	return h - hstates; @@ -929,9 +926,12 @@ static struct dentry_operations anon_ops = {  	.d_dname = hugetlb_dname  }; -struct file *hugetlb_file_setup(const char *name, unsigned long addr, -				size_t size, vm_flags_t acctflag, -				struct user_struct **user, +/* + * Note that size should be aligned to proper hugepage size in caller side, + * otherwise hugetlb_reserve_pages reserves one less hugepages than intended. + */ +struct file *hugetlb_file_setup(const char *name, size_t size, +				vm_flags_t acctflag, struct user_struct **user,  				int creat_flags, int page_size_log)  {  	struct file *file = ERR_PTR(-ENOMEM); @@ -939,8 +939,6 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr,  	struct path path;  	struct super_block *sb;  	struct qstr quick_string; -	struct hstate *hstate; -	unsigned long num_pages;  	int hstate_idx;  	hstate_idx = get_hstate_idx(page_size_log); @@ -980,12 +978,10 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr,  	if (!inode)  		goto out_dentry; -	hstate = hstate_inode(inode); -	size += addr & ~huge_page_mask(hstate); -	num_pages = ALIGN(size, huge_page_size(hstate)) >> -			huge_page_shift(hstate);  	file = ERR_PTR(-ENOMEM); -	if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag)) +	if (hugetlb_reserve_pages(inode, 0, +			size >> huge_page_shift(hstate_inode(inode)), NULL, +			acctflag))  		goto out_inode;  	d_instantiate(path.dentry, inode);  |