From 6068b68c82e70c8ea43a57e45559a10def75c3b0 Mon Sep 17 00:00:00 2001 From: Tal Zussman Date: Wed, 2 Sep 2026 12:35:09 -0400 Subject: [PATCH] ceph: use a folio in the READ_INLINE path of ceph_read_iter() The inline data is read into a scratch buffer that never enters the page cache, so allocate it with folio_alloc() instead of __page_cache_alloc(). This drops the cpuset page spreading that __page_cache_alloc() applies on NUMA systems, which only makes sense for page cache pages. The temporary buffer here is better off node local. The mismatched __free_page()/__free_pages() pair both become folio_put(). The __ceph_do_getattr() locked page plumbing will be converted in a later patch, so pass &folio->page for now. Signed-off-by: Tal Zussman Reviewed-by: Alex Markuze Signed-off-by: Ilya Dryomov --- fs/ceph/file.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index d5606456dbd5..f0e77a1ab4d1 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -2247,21 +2247,22 @@ again: if (retry_op > HAVE_RETRIED && ret >= 0) { int statret; - struct page *page = NULL; + struct folio *folio = NULL; loff_t i_size; int mask = CEPH_STAT_CAP_SIZE; if (retry_op == READ_INLINE) { - page = __page_cache_alloc(GFP_KERNEL); - if (!page) + folio = folio_alloc(GFP_KERNEL, 0); + if (!folio) return -ENOMEM; mask = CEPH_STAT_CAP_INLINE_DATA; } - statret = __ceph_do_getattr(inode, page, mask, !!page); + statret = __ceph_do_getattr(inode, folio ? &folio->page : NULL, + mask, !!folio); if (statret < 0) { - if (page) - __free_page(page); + if (folio) + folio_put(folio); if (statret == -ENODATA) { BUG_ON(retry_op != READ_INLINE); goto again; @@ -2278,8 +2279,8 @@ again: iocb->ki_pos + len); end = min_t(loff_t, end, PAGE_SIZE); if (statret < end) - zero_user_segment(page, statret, end); - ret = copy_page_to_iter(page, + folio_zero_segment(folio, statret, end); + ret = copy_folio_to_iter(folio, iocb->ki_pos & ~PAGE_MASK, end - iocb->ki_pos, to); iocb->ki_pos += ret; @@ -2292,7 +2293,7 @@ again: iocb->ki_pos += ret; read += ret; } - __free_pages(page, 0); + folio_put(folio); return read; }