diff options
Diffstat (limited to 'fs/hugetlbfs/inode.c')
| -rw-r--r-- | fs/hugetlbfs/inode.c | 94 | 
1 files changed, 47 insertions, 47 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 790d2727141a..9062da6da567 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -132,7 +132,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)  	 * way when do_mmap unwinds (may be important on powerpc  	 * and ia64).  	 */ -	vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; +	vm_flags_set(vma, VM_HUGETLB | VM_DONTEXPAND);  	vma->vm_ops = &hugetlb_vm_ops;  	ret = seal_check_future_write(info->seals, vma); @@ -388,9 +388,7 @@ static bool hugetlb_vma_maps_page(struct vm_area_struct *vma,  {  	pte_t *ptep, pte; -	ptep = huge_pte_offset(vma->vm_mm, addr, -			huge_page_size(hstate_vma(vma))); - +	ptep = hugetlb_walk(vma, addr, huge_page_size(hstate_vma(vma)));  	if (!ptep)  		return false; @@ -412,10 +410,12 @@ static bool hugetlb_vma_maps_page(struct vm_area_struct *vma,   */  static unsigned long vma_offset_start(struct vm_area_struct *vma, pgoff_t start)  { +	unsigned long offset = 0; +  	if (vma->vm_pgoff < start) -		return (start - vma->vm_pgoff) << PAGE_SHIFT; -	else -		return 0; +		offset = (start - vma->vm_pgoff) << PAGE_SHIFT; + +	return vma->vm_start + offset;  }  static unsigned long vma_offset_end(struct vm_area_struct *vma, pgoff_t end) @@ -457,7 +457,7 @@ retry:  		v_start = vma_offset_start(vma, start);  		v_end = vma_offset_end(vma, end); -		if (!hugetlb_vma_maps_page(vma, vma->vm_start + v_start, page)) +		if (!hugetlb_vma_maps_page(vma, v_start, page))  			continue;  		if (!hugetlb_vma_trylock_write(vma)) { @@ -473,8 +473,8 @@ retry:  			break;  		} -		unmap_hugepage_range(vma, vma->vm_start + v_start, v_end, -				NULL, ZAP_FLAG_DROP_MARKER); +		unmap_hugepage_range(vma, v_start, v_end, NULL, +				     ZAP_FLAG_DROP_MARKER);  		hugetlb_vma_unlock_write(vma);  	} @@ -507,10 +507,9 @@ retry:  		 */  		v_start = vma_offset_start(vma, start);  		v_end = vma_offset_end(vma, end); -		if (hugetlb_vma_maps_page(vma, vma->vm_start + v_start, page)) -			unmap_hugepage_range(vma, vma->vm_start + v_start, -						v_end, NULL, -						ZAP_FLAG_DROP_MARKER); +		if (hugetlb_vma_maps_page(vma, v_start, page)) +			unmap_hugepage_range(vma, v_start, v_end, NULL, +					     ZAP_FLAG_DROP_MARKER);  		kref_put(&vma_lock->refs, hugetlb_vma_lock_release);  		hugetlb_vma_unlock_write(vma); @@ -540,8 +539,7 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,  		v_start = vma_offset_start(vma, start);  		v_end = vma_offset_end(vma, end); -		unmap_hugepage_range(vma, vma->vm_start + v_start, v_end, -				     NULL, zap_flags); +		unmap_hugepage_range(vma, v_start, v_end, NULL, zap_flags);  		/*  		 * Note that vma lock only exists for shared/non-private @@ -813,7 +811,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,  	 * as input to create an allocation policy.  	 */  	vma_init(&pseudo_vma, mm); -	pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED); +	vm_flags_init(&pseudo_vma, VM_HUGETLB | VM_MAYSHARE | VM_SHARED);  	pseudo_vma.vm_file = file;  	for (index = start; index < end; index++) { @@ -821,8 +819,9 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,  		 * This is supposed to be the vaddr where the page is being  		 * faulted in, but we have no vaddr here.  		 */ -		struct page *page; +		struct folio *folio;  		unsigned long addr; +		bool present;  		cond_resched(); @@ -846,48 +845,49 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,  		mutex_lock(&hugetlb_fault_mutex_table[hash]);  		/* See if already present in mapping to avoid alloc/free */ -		page = find_get_page(mapping, index); -		if (page) { -			put_page(page); +		rcu_read_lock(); +		present = page_cache_next_miss(mapping, index, 1) != index; +		rcu_read_unlock(); +		if (present) {  			mutex_unlock(&hugetlb_fault_mutex_table[hash]);  			hugetlb_drop_vma_policy(&pseudo_vma);  			continue;  		}  		/* -		 * Allocate page without setting the avoid_reserve argument. +		 * Allocate folio without setting the avoid_reserve argument.  		 * There certainly are no reserves associated with the  		 * pseudo_vma.  However, there could be shared mappings with  		 * reserves for the file at the inode level.  If we fallocate -		 * pages in these areas, we need to consume the reserves +		 * folios in these areas, we need to consume the reserves  		 * to keep reservation accounting consistent.  		 */ -		page = alloc_huge_page(&pseudo_vma, addr, 0); +		folio = alloc_hugetlb_folio(&pseudo_vma, addr, 0);  		hugetlb_drop_vma_policy(&pseudo_vma); -		if (IS_ERR(page)) { +		if (IS_ERR(folio)) {  			mutex_unlock(&hugetlb_fault_mutex_table[hash]); -			error = PTR_ERR(page); +			error = PTR_ERR(folio);  			goto out;  		} -		clear_huge_page(page, addr, pages_per_huge_page(h)); -		__SetPageUptodate(page); -		error = hugetlb_add_to_page_cache(page, mapping, index); +		clear_huge_page(&folio->page, addr, pages_per_huge_page(h)); +		__folio_mark_uptodate(folio); +		error = hugetlb_add_to_page_cache(folio, mapping, index);  		if (unlikely(error)) { -			restore_reserve_on_error(h, &pseudo_vma, addr, page); -			put_page(page); +			restore_reserve_on_error(h, &pseudo_vma, addr, folio); +			folio_put(folio);  			mutex_unlock(&hugetlb_fault_mutex_table[hash]);  			goto out;  		}  		mutex_unlock(&hugetlb_fault_mutex_table[hash]); -		SetHPageMigratable(page); +		folio_set_hugetlb_migratable(folio);  		/* -		 * unlock_page because locked by hugetlb_add_to_page_cache() -		 * put_page() due to reference from alloc_huge_page() +		 * folio_unlock because locked by hugetlb_add_to_page_cache() +		 * folio_put() due to reference from alloc_hugetlb_folio()  		 */ -		unlock_page(page); -		put_page(page); +		folio_unlock(folio); +		folio_put(folio);  	}  	if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > inode->i_size) @@ -898,7 +898,7 @@ out:  	return error;  } -static int hugetlbfs_setattr(struct user_namespace *mnt_userns, +static int hugetlbfs_setattr(struct mnt_idmap *idmap,  			     struct dentry *dentry, struct iattr *attr)  {  	struct inode *inode = d_inode(dentry); @@ -907,7 +907,7 @@ static int hugetlbfs_setattr(struct user_namespace *mnt_userns,  	unsigned int ia_valid = attr->ia_valid;  	struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); -	error = setattr_prepare(&init_user_ns, dentry, attr); +	error = setattr_prepare(&nop_mnt_idmap, dentry, attr);  	if (error)  		return error; @@ -924,7 +924,7 @@ static int hugetlbfs_setattr(struct user_namespace *mnt_userns,  		hugetlb_vmtruncate(inode, newsize);  	} -	setattr_copy(&init_user_ns, inode, attr); +	setattr_copy(&nop_mnt_idmap, inode, attr);  	mark_inode_dirty(inode);  	return 0;  } @@ -980,7 +980,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,  		struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode);  		inode->i_ino = get_next_ino(); -		inode_init_owner(&init_user_ns, inode, dir, mode); +		inode_init_owner(&nop_mnt_idmap, inode, dir, mode);  		lockdep_set_class(&inode->i_mapping->i_mmap_rwsem,  				&hugetlbfs_i_mmap_rwsem_key);  		inode->i_mapping->a_ops = &hugetlbfs_aops; @@ -1019,7 +1019,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,  /*   * File creation. Allocate an inode, and we're done..   */ -static int hugetlbfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, +static int hugetlbfs_mknod(struct mnt_idmap *idmap, struct inode *dir,  			   struct dentry *dentry, umode_t mode, dev_t dev)  {  	struct inode *inode; @@ -1033,24 +1033,24 @@ static int hugetlbfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,  	return 0;  } -static int hugetlbfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, +static int hugetlbfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,  			   struct dentry *dentry, umode_t mode)  { -	int retval = hugetlbfs_mknod(&init_user_ns, dir, dentry, +	int retval = hugetlbfs_mknod(&nop_mnt_idmap, dir, dentry,  				     mode | S_IFDIR, 0);  	if (!retval)  		inc_nlink(dir);  	return retval;  } -static int hugetlbfs_create(struct user_namespace *mnt_userns, +static int hugetlbfs_create(struct mnt_idmap *idmap,  			    struct inode *dir, struct dentry *dentry,  			    umode_t mode, bool excl)  { -	return hugetlbfs_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0); +	return hugetlbfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFREG, 0);  } -static int hugetlbfs_tmpfile(struct user_namespace *mnt_userns, +static int hugetlbfs_tmpfile(struct mnt_idmap *idmap,  			     struct inode *dir, struct file *file,  			     umode_t mode)  { @@ -1064,7 +1064,7 @@ static int hugetlbfs_tmpfile(struct user_namespace *mnt_userns,  	return finish_open_simple(file, 0);  } -static int hugetlbfs_symlink(struct user_namespace *mnt_userns, +static int hugetlbfs_symlink(struct mnt_idmap *idmap,  			     struct inode *dir, struct dentry *dentry,  			     const char *symname)  {  |