Re: [PATCH v2 05/10] ceph: convert ceph_submit_write() to folios

Tal Zussman <[email protected]>
Newsgroups org.kernel.vger.ceph-devel,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kvack.linux-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);
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.