[PATCH 2/6] ceph: use a folio in the inline read branch of ceph_filemap_fault()

From: Tal Zussman

Date: Tue Aug 25 2026 - 17:50:29 EST


Convert find_or_create_page() to __filemap_get_folio(), keeping the
existing GFP constraint. Saves three calls to compound_head().

The __ceph_do_getattr() locked page plumbing is converted separately,
so pass &folio->page for now.

Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
---
fs/ceph/addr.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index c05bdf5d7273..988ead716991 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -2054,29 +2054,30 @@ static vm_fault_t ceph_filemap_fault(struct vm_fault *vmf)
ret = VM_FAULT_SIGBUS;
} else {
struct address_space *mapping = inode->i_mapping;
- struct page *page;
+ struct folio *folio;

filemap_invalidate_lock_shared(mapping);
- page = find_or_create_page(mapping, 0,
+ folio = __filemap_get_folio(mapping, 0,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
mapping_gfp_constraint(mapping, ~__GFP_FS));
- if (!page) {
+ if (IS_ERR(folio)) {
ret = VM_FAULT_OOM;
goto out_inline;
}
- err = __ceph_do_getattr(inode, page,
+ err = __ceph_do_getattr(inode, &folio->page,
CEPH_STAT_CAP_INLINE_DATA, true);
if (err < 0 || off >= i_size_read(inode)) {
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
ret = vmf_error(err);
goto out_inline;
}
- if (err < PAGE_SIZE)
- zero_user_segment(page, err, PAGE_SIZE);
+ if (err < folio_size(folio))
+ folio_zero_segment(folio, err, folio_size(folio));
else
- flush_dcache_page(page);
- SetPageUptodate(page);
- vmf->page = page;
+ flush_dcache_folio(folio);
+ folio_mark_uptodate(folio);
+ vmf->page = folio_page(folio, 0);
ret = VM_FAULT_MAJOR | VM_FAULT_LOCKED;
out_inline:
filemap_invalidate_unlock_shared(mapping);

--
2.39.5