Re: [PATCH v2 05/10] ceph: convert ceph_submit_write() to folios
Tal Zussman <[email protected]> Thu, 6 Aug 2026 21:58:11 +0300
| Newsgroups | gmane.linux.file-systems,gmane.comp.file-systems.ceph.devel,gmane.linux.kernel,gmane.linux.kernel.mm |
|---|---|
| Message-ID | <[email protected]> |
On 8/4/26 2:52 PM, Tal Zussman wrote: > Convert the request assembly loop and error paths 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 nine 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 <[email protected]> > --- > fs/ceph/addr.c | 44 ++++++++++++++++++++++++++------------------ > 1 file changed, 26 insertions(+), 18 deletions(-) > > diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c > index c81e9da42df9..a96986c503bf 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] */ > @@ -575,6 +580,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) > { > } > @@ -1436,14 +1445,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, > @@ -1467,29 +1476,28 @@ 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 < folio_batch_count(&ceph_wbc->fbatch); i++) { > - struct folio *folio = ceph_wbc->fbatch.folios[i]; > + folio = ceph_wbc->fbatch.folios[i]; > > if (!folio) > continue; This, ... > > - page = &folio->page; > - redirty_page_for_writepage(wbc, page); > - unlock_page(page); > + folio_redirty_for_writepage(wbc, folio); > + folio_unlock(folio); > } > > for (i = 0; i < ceph_wbc->locked_pages; i++) { > - page = ceph_fscrypt_pagecache_page(ceph_wbc->pages[i]); > + folio = ceph_fscrypt_pagecache_folio(page_folio(ceph_wbc->pages[i])); > > - if (!page) > + if (!folio) > continue; > ... and this check are unnecessary. ceph_fscrypt_pagecache_page() can't take or return NULL, and ceph_shift_unused_folios_left() compacts NULLs out of ceph_wbc->fbatch. Will remove both in v3. > - redirty_page_for_writepage(wbc, page); > - unlock_page(page); > + folio_redirty_for_writepage(wbc, folio); > + folio_unlock(folio); > } > > ceph_osdc_put_request(req); > @@ -1506,8 +1514,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 > @@ -1540,12 +1548,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); > @@ -1556,7 +1564,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); >