From 00da1176cce72d2bdde8da8eb78d1e892fd2f400 Mon Sep 17 00:00:00 2001 From: Tal Zussman Date: Wed, 2 Sep 2026 12:11:30 -0400 Subject: [PATCH] ceph: convert ceph_submit_write() to folios Convert the request assembly loop and error path in ceph_submit_write() to folios. This drops ceph's uses of the set_page_writeback(), redirty_page_for_writepage(), and unlock_page() compatibility wrappers in the writeback submission path. Add ceph_folio_start_fscache(), a folio counterpart of ceph_set_page_fscache(). The remaining caller of the latter in write_folio_nounlock() will be converted separately. In total, this removes eight calls to compound_head() hidden in the page-based APIs and one explicit page_folio() call in ceph_undo_wrbuffer_claim()'s caller, while adding four explicit page_folio() calls. Note that get_writepages_data_length() must still be passed the possibly-bounce folio, not the unwrapped pagecache folio, as it checks fscrypt_is_bounce_folio() to round encrypted lengths up to the fscrypt block size. No functional change. Signed-off-by: Tal Zussman Reviewed-by: Alex Markuze Signed-off-by: Ilya Dryomov --- fs/ceph/addr.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 942f7330a8f2..6b0da1551fac 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -569,6 +569,11 @@ const struct netfs_request_ops ceph_netfs_ops = { }; #ifdef CONFIG_CEPH_FSCACHE +static void ceph_folio_start_fscache(struct folio *folio) +{ + folio_start_private_2(folio); /* [DEPRECATED] */ +} + static void ceph_set_page_fscache(struct page *page) { folio_start_private_2(page_folio(page)); /* [DEPRECATED] */ @@ -596,6 +601,10 @@ static void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, b ceph_fscache_write_terminated, inode, true, caching); } #else +static inline void ceph_folio_start_fscache(struct folio *folio) +{ +} + static inline void ceph_set_page_fscache(struct page *page) { } @@ -1478,14 +1487,14 @@ int ceph_submit_write(struct address_space *mapping, struct ceph_client *cl = fsc->client; struct ceph_vino vino = ceph_vino(inode); struct ceph_osd_request *req = NULL; - struct page *page = NULL; + struct folio *folio = NULL; bool caching = ceph_is_cache_enabled(inode); u64 offset; u64 len; unsigned i; new_request: - offset = ceph_fscrypt_page_offset(ceph_wbc->pages[0]); + offset = ceph_fscrypt_folio_offset(page_folio(ceph_wbc->pages[0])); len = ceph_wbc->wsize; req = ceph_osdc_new_request(&fsc->client->osdc, @@ -1509,14 +1518,14 @@ new_request: BUG_ON(IS_ERR(req)); } - page = ceph_wbc->pages[ceph_wbc->locked_pages - 1]; - BUG_ON(len < ceph_fscrypt_page_offset(page) + thp_size(page) - offset); + folio = page_folio(ceph_wbc->pages[ceph_wbc->locked_pages - 1]); + BUG_ON(len < ceph_fscrypt_folio_offset(folio) + folio_size(folio) - offset); if (!ceph_inc_osd_stopping_blocker(fsc->mdsc)) { for (i = 0; i < ceph_wbc->locked_pages; i++) { - page = ceph_wbc->pages[i]; - if (fscrypt_is_bounce_page(page)) { - page = fscrypt_pagecache_page(page); + folio = page_folio(ceph_wbc->pages[i]); + if (fscrypt_is_bounce_folio(folio)) { + folio = fscrypt_pagecache_folio(folio); fscrypt_free_bounce_page(ceph_wbc->pages[i]); } @@ -1524,10 +1533,10 @@ new_request: CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb)) fsc->write_congested = false; - ceph_undo_wrbuffer_claim(inode, page_folio(page)); - redirty_page_for_writepage(wbc, page); - unlock_page(page); - put_page(page); + ceph_undo_wrbuffer_claim(inode, folio); + folio_redirty_for_writepage(wbc, folio); + folio_unlock(folio); + folio_put(folio); } if (ceph_wbc->from_pool) { @@ -1553,8 +1562,8 @@ new_request: for (i = 0; i < ceph_wbc->locked_pages; i++) { u64 cur_offset; - page = ceph_fscrypt_pagecache_page(ceph_wbc->pages[i]); - cur_offset = page_offset(page); + folio = ceph_fscrypt_pagecache_folio(page_folio(ceph_wbc->pages[i])); + cur_offset = folio_pos(folio); /* * Discontinuity in page range? Ceph can handle that by just passing @@ -1587,12 +1596,12 @@ new_request: ceph_wbc->op_idx++; } - set_page_writeback(page); + folio_start_writeback(folio); if (caching) - ceph_set_page_fscache(page); + ceph_folio_start_fscache(folio); - len += thp_size(page); + len += folio_size(folio); } ceph_fscache_write_to_cache(inode, offset, len, caching); @@ -1603,7 +1612,7 @@ new_request: /* writepages_finish() clears writeback pages * according to the data length, so make sure * data length covers all locked pages */ - u64 min_len = len + 1 - thp_size(page); + u64 min_len = len + 1 - folio_size(folio); len = get_writepages_data_length(inode, page_folio(ceph_wbc->pages[i - 1]), offset);