hugetlb_add_to_page_cache() is partly a wrapper of the generic __filemap_add_folio() that takes in PAGE_SIZE granularity index, hence make it consistent by taking PAGE_SIZE granularity index as well. Signed-off-by: Jane Chu --- fs/hugetlbfs/inode.c | 13 ++++++++----- mm/hugetlb.c | 18 +++++++++--------- mm/memfd.c | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 6c883478f7e7..0b49a79efb08 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -599,7 +599,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, struct mm_struct *mm = current->mm; loff_t hpage_size = huge_page_size(h); unsigned long hpage_shift = huge_page_shift(h); - pgoff_t start, index, end; + pgoff_t start, idx, end; int error; u32 hash; @@ -639,7 +639,9 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, vm_flags_init(&pseudo_vma, VM_HUGETLB | VM_MAYSHARE | VM_SHARED); pseudo_vma.vm_file = file; - for (index = start; index < end; index++) { + for (idx = start; idx < end; idx++) { + pgoff_t index = idx << huge_page_order(h); + /* * This is supposed to be the vaddr where the page is being * faulted in, but we have no vaddr here. @@ -659,14 +661,14 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, } /* addr is the offset within the file (zero based) */ - addr = index * hpage_size; + addr = idx * hpage_size; /* mutex taken here, fault path and hole punch */ - hash = hugetlb_fault_mutex_hash(mapping, index << huge_page_order(h)); + hash = hugetlb_fault_mutex_hash(mapping, index); mutex_lock(&hugetlb_fault_mutex_table[hash]); /* See if already present in mapping to avoid alloc/free */ - folio = filemap_get_folio(mapping, index << huge_page_order(h)); + folio = filemap_get_folio(mapping, index); if (!IS_ERR(folio)) { folio_put(folio); mutex_unlock(&hugetlb_fault_mutex_table[hash]); @@ -690,6 +692,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, folio_zero_user(folio, addr); __folio_mark_uptodate(folio); error = hugetlb_add_to_page_cache(folio, mapping, index); + if (unlikely(error)) { restore_reserve_on_error(h, &pseudo_vma, addr, folio); folio_put(folio); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 5484e78fe72e..b41e7b8df094 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5621,15 +5621,14 @@ bool hugetlbfs_pagecache_present(struct hstate *h, } int hugetlb_add_to_page_cache(struct folio *folio, struct address_space *mapping, - pgoff_t idx) + pgoff_t index) { struct inode *inode = mapping->host; struct hstate *h = hstate_inode(inode); int err; - idx <<= huge_page_order(h); __folio_set_locked(folio); - err = __filemap_add_folio(mapping, folio, idx, GFP_KERNEL, NULL); + err = __filemap_add_folio(mapping, folio, index, GFP_KERNEL, NULL); if (unlikely(err)) { __folio_clear_locked(folio); @@ -5696,7 +5695,6 @@ static vm_fault_t hugetlb_no_page(struct address_space *mapping, struct folio *folio; unsigned long size; pte_t new_pte; - pgoff_t idx = vmf->pgoff >> huge_page_order(h); /* * Currently, we are forced to kill the process in the event the @@ -5779,7 +5777,8 @@ static vm_fault_t hugetlb_no_page(struct address_space *mapping, new_folio = true; if (vma->vm_flags & VM_MAYSHARE) { - int err = hugetlb_add_to_page_cache(folio, mapping, idx); + int err = hugetlb_add_to_page_cache(folio, mapping, vmf->pgoff); + if (err) { /* * err can't be -EEXIST which implies someone @@ -6170,7 +6169,8 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, bool wp_enabled = (flags & MFILL_ATOMIC_WP); struct hstate *h = hstate_vma(dst_vma); struct address_space *mapping = dst_vma->vm_file->f_mapping; - pgoff_t idx = vma_hugecache_offset(h, dst_vma, dst_addr); + pgoff_t index = linear_page_index(dst_vma, dst_addr); + unsigned long size = huge_page_size(h); int vm_shared = dst_vma->vm_flags & VM_SHARED; pte_t _dst_pte; @@ -6201,7 +6201,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, if (is_continue) { ret = -EFAULT; - folio = filemap_lock_folio(mapping, idx << huge_page_order(h)); + folio = filemap_lock_folio(mapping, index); if (IS_ERR(folio)) goto out; folio_in_pagecache = true; @@ -6297,7 +6297,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, /* Add shared, newly allocated pages to the page cache. */ if (vm_shared && !is_continue) { ret = -EFAULT; - if (idx >= (i_size_read(mapping->host) >> huge_page_shift(h))) + if (index >= (i_size_read(mapping->host) >> PAGE_SHIFT)) goto out_release_nounlock; /* @@ -6306,7 +6306,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, * hugetlb_fault_mutex_table that here must be hold by * the caller. */ - ret = hugetlb_add_to_page_cache(folio, mapping, idx); + ret = hugetlb_add_to_page_cache(folio, mapping, index); if (ret) goto out_release_nounlock; folio_in_pagecache = true; diff --git a/mm/memfd.c b/mm/memfd.c index b0ec0b12b98d..0b5e8f111b39 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -122,7 +122,7 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t index) err = hugetlb_add_to_page_cache(folio, memfd->f_mapping, - idx); + index); mutex_unlock(&hugetlb_fault_mutex_table[hash]); -- 2.43.5