public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Qu Wenruo <wqu@suse.com>
Cc: linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v3 8/9] btrfs: prepare btrfs_end_repair_bio() for larger data folios
Date: Thu, 3 Apr 2025 21:56:51 +0200	[thread overview]
Message-ID: <20250403195651.GU32661@twin.jikos.cz> (raw)
In-Reply-To: <8203647f525da730826857afe87cd673f1e42074.1742195085.git.wqu@suse.com>

On Mon, Mar 17, 2025 at 05:40:53PM +1030, Qu Wenruo wrote:
> The function btrfs_end_repair_bio() has an ASSERT() making sure the
> folio is page sized.
> 
> The reason is mostly related to the fact that later we pass a folio and
> its offset into btrfs_repair_io_failure().
> If we have larger folios passed in, later calculation of the folio and
> its offset can go wrong, as we have extra offset to the bv_page.
> 
> Change the behavior by:
> 
> - Doing a proper folio grab
>   Instead of just page_folio(bv_page), we should get the real page (as the
>   bv_offset can be larger than page size), then call page_folio().
> 
> - Do extra folio offset calculation
>   We can have the following cases of a bio_vec (this bv is moved
>   forward by btrfs read verification):
> 
>   bv_page             bv_offset
>   |                   |
>   | | | | | | | | | | | | | | | | |
>   |<-  folio_a  ->|<-  folio_b  ->|
> 
>   | | = a page.
> 
> In above case, the real folio should be folio_b, and offset inside that
> folio should be:
> 
>   bv_offset - ((&folio_b->page - &folio_a->page) << PAGE_SHIFT).
> 
> With these changes, now btrfs_end_repair_bio() is able to handle larger
> folios properly.
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  fs/btrfs/bio.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
> index 8c2eee1f1878..292c79e0855f 100644
> --- a/fs/btrfs/bio.c
> +++ b/fs/btrfs/bio.c
> @@ -156,6 +156,25 @@ static void btrfs_repair_done(struct btrfs_failed_bio *fbio)
>  	}
>  }
>  
> +static struct folio *bio_vec_get_folio(const struct bio_vec *bv)
> +{
> +	return page_folio(bv->bv_page + (bv->bv_offset >> PAGE_SHIFT));
> +}
> +
> +static unsigned long bio_vec_get_folio_offset(const struct bio_vec *bv)
> +{
> +	struct folio *folio = bio_vec_get_folio(bv);
> +
> +	/*
> +	 * There can be multiple physically contiguous folios queued
> +	 * into the bio_vec.
> +	 * Thus the first page of our folio should be at or beyond
> +	 * the first page of the bio_vec.
> +	 */
> +	ASSERT(&folio->page >= bv->bv_page);
> +	return bv->bv_offset - ((&folio->page - bv->bv_page) << PAGE_SHIFT);

This looks like it should be a generic helper, the expression looks
quite magic.

  reply	other threads:[~2025-04-03 19:56 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-17  7:10 [PATCH v3 0/9] btrfs: remove ASSERT()s for folio_order() and folio_test_large() Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 1/9] btrfs: send: remove the again label inside put_file_data() Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 2/9] btrfs: send: prepare put_file_data() for larger data folios Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 3/9] btrfs: prepare btrfs_page_mkwrite() " Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 4/9] btrfs: prepare prepare_one_folio() " Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 5/9] btrfs: prepare end_bbio_data_write() " Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 6/9] btrfs: subpage: prepare " Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 7/9] btrfs: zlib: prepare copy_data_into_buffer() " Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 8/9] btrfs: prepare btrfs_end_repair_bio() " Qu Wenruo
2025-04-03 19:56   ` David Sterba [this message]
2025-04-06 23:19   ` Qu Wenruo
2025-04-07  6:18   ` Christoph Hellwig
2025-04-07  7:11     ` Qu Wenruo
2025-03-17  7:10 ` [PATCH v3 9/9] btrfs: enable larger data folios support for defrag Qu Wenruo
2025-03-17 13:55 ` [PATCH v3 0/9] btrfs: remove ASSERT()s for folio_order() and folio_test_large() David Sterba
2025-03-17 15:13   ` David Sterba
2025-03-31  4:47     ` Qu Wenruo
2025-04-03 19:54       ` David Sterba
2025-04-03 21:45         ` Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250403195651.GU32661@twin.jikos.cz \
    --to=dsterba@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=wqu@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox