[RFC PATCH 09/19] mm: hugetlb: Use restore_reserve_on_error directly in filesystems

From: Ackerley Tng
Date: Tue Jun 06 2023 - 15:05:34 EST


Expose inode_resv_map() so that hugetlbfs can access its own resv_map.

Hide restore_reserve_on_error_vma(), that function is now only used
within mm/hugetlb.c.

Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
fs/hugetlbfs/inode.c | 2 +-
include/linux/hugetlb.h | 21 +++++++++++++++++++--
mm/hugetlb.c | 13 -------------
3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 44e6ee9a856d..53f6a421499d 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -868,7 +868,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
__folio_mark_uptodate(folio);
error = hugetlb_add_to_page_cache(folio, mapping, index);
if (unlikely(error)) {
- restore_reserve_on_error_vma(h, &pseudo_vma, addr, folio);
+ restore_reserve_on_error(inode_resv_map(inode), index, true, folio);
folio_put(folio);
mutex_unlock(&hugetlb_fault_mutex_table[hash]);
goto out;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 02a2766d89a4..5fe9643826d7 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -568,6 +568,20 @@ static inline struct hugepage_subpool *subpool_inode(struct inode *inode)
return HUGETLBFS_SB(inode->i_sb)->spool;
}

+static inline struct resv_map *inode_resv_map(struct inode *inode)
+{
+ /*
+ * At inode evict time, i_mapping may not point to the original
+ * address space within the inode. This original address space
+ * contains the pointer to the resv_map. So, always use the
+ * address space embedded within the inode.
+ * The VERY common case is inode->mapping == &inode->i_data but,
+ * this may not be true for device special inodes.
+ */
+ return (struct resv_map *)(&inode->i_data)->private_data;
+}
+
+
#else /* !CONFIG_HUGETLBFS */

#define is_file_hugepages(file) false
@@ -588,6 +602,11 @@ static inline struct hugepage_subpool *subpool_inode(struct inode *inode)
return NULL;
}

+static inline struct resv_map *inode_resv_map(struct inode *inode)
+{
+ return NULL;
+}
+
#endif /* !CONFIG_HUGETLBFS */

#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
@@ -762,8 +781,6 @@ int hugetlb_add_to_page_cache(struct folio *folio, struct address_space *mapping
pgoff_t idx);
void restore_reserve_on_error(struct resv_map *resv, pgoff_t resv_index,
bool may_share, struct folio *folio);
-void restore_reserve_on_error_vma(struct hstate *h, struct vm_area_struct *vma,
- unsigned long address, struct folio *folio);

/* arch callback */
int __init __alloc_bootmem_huge_page(struct hstate *h, int nid);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4675f9efeba4..540634aec181 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1091,19 +1091,6 @@ void resv_map_release(struct kref *ref)
kfree(resv_map);
}

-static inline struct resv_map *inode_resv_map(struct inode *inode)
-{
- /*
- * At inode evict time, i_mapping may not point to the original
- * address space within the inode. This original address space
- * contains the pointer to the resv_map. So, always use the
- * address space embedded within the inode.
- * The VERY common case is inode->mapping == &inode->i_data but,
- * this may not be true for device special inodes.
- */
- return (struct resv_map *)(&inode->i_data)->private_data;
-}
-
static struct resv_map *vma_resv_map(struct vm_area_struct *vma)
{
VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma);
--
2.41.0.rc0.172.g3f132b7071-goog