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, while adding four explicit ones via page_folio(). 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 --- fs/ceph/addr.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 28f0b16da2b0..a3324da08123 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -553,6 +553,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] */ @@ -580,6 +585,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) { } @@ -1448,14 +1457,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, @@ -1479,21 +1488,21 @@ int ceph_submit_write(struct address_space *mapping, 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++) { fscrypt_finalize_bounce_page(&ceph_wbc->pages[i]); - page = ceph_wbc->pages[i]; + folio = page_folio(ceph_wbc->pages[i]); if (atomic_long_dec_return(&fsc->writeback_count) < CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb)) fsc->write_congested = false; - redirty_page_for_writepage(wbc, page); - unlock_page(page); - put_page(page); + folio_redirty_for_writepage(wbc, folio); + folio_unlock(folio); + folio_put(folio); } if (ceph_wbc->from_pool) { @@ -1519,8 +1528,8 @@ int ceph_submit_write(struct address_space *mapping, 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 @@ -1553,12 +1562,12 @@ int ceph_submit_write(struct address_space *mapping, 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); @@ -1569,7 +1578,7 @@ int ceph_submit_write(struct address_space *mapping, /* 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); -- 2.39.5