public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs: remove compressed_bio::compressed_len
@ 2026-02-20  3:41 Qu Wenruo
  2026-02-20  3:41 ` [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio Qu Wenruo
  2026-02-20  3:41 ` [PATCH 2/2] btrfs: reduce the size of compressed_bio Qu Wenruo
  0 siblings, 2 replies; 8+ messages in thread
From: Qu Wenruo @ 2026-02-20  3:41 UTC (permalink / raw)
  To: linux-btrfs

That member is removed in the 2nd patch, the 1st patch is a minor
cleanup to provide a common helper to calculate the bio size.

Please check the commit message of each patch for details.

Qu Wenruo (2):
  btrfs: introduce a common helper to calculate the size of a bio
  btrfs: reduce the size of compressed_bio

 fs/btrfs/compression.c |  2 --
 fs/btrfs/compression.h |  3 ---
 fs/btrfs/lzo.c         |  7 ++++---
 fs/btrfs/misc.h        | 15 +++++++++++----
 fs/btrfs/raid56.c      |  9 ++-------
 fs/btrfs/scrub.c       | 22 ++++------------------
 fs/btrfs/zlib.c        |  2 +-
 fs/btrfs/zstd.c        |  2 +-
 8 files changed, 23 insertions(+), 39 deletions(-)

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio
  2026-02-20  3:41 [PATCH 0/2] btrfs: remove compressed_bio::compressed_len Qu Wenruo
@ 2026-02-20  3:41 ` Qu Wenruo
  2026-02-24 14:15   ` David Sterba
  2026-02-20  3:41 ` [PATCH 2/2] btrfs: reduce the size of compressed_bio Qu Wenruo
  1 sibling, 1 reply; 8+ messages in thread
From: Qu Wenruo @ 2026-02-20  3:41 UTC (permalink / raw)
  To: linux-btrfs

We have several call sites doing the same work to calculate the size of
a bio:

	struct bio_vec *bvec;
	u32 bio_size = 0;
	int i;

	bio_for_each_bvec_all(bvec, bio, i)
		bio_size += bvec->bv_len;

We can use a common helper instead of open-coding it everywhere.

This also allows us to constify the @bio_size variables used in all the
call sites.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/misc.h   | 15 +++++++++++----
 fs/btrfs/raid56.c |  9 ++-------
 fs/btrfs/scrub.c  | 22 ++++------------------
 3 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h
index 12c5a9d6564f..189c25cc5eff 100644
--- a/fs/btrfs/misc.h
+++ b/fs/btrfs/misc.h
@@ -52,15 +52,22 @@ static inline phys_addr_t bio_iter_phys(struct bio *bio, struct bvec_iter *iter)
 	     (paddr = bio_iter_phys((bio), (iter)), 1);			\
 	     bio_advance_iter_single((bio), (iter), (blocksize)))
 
-/* Initialize a bvec_iter to the size of the specified bio. */
-static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
+/* Can only be called on a non-cloned bio. */
+static inline u32 bio_get_size(struct bio *bio)
 {
 	struct bio_vec *bvec;
-	u32 bio_size = 0;
+	u32 ret = 0;
 	int i;
 
 	bio_for_each_bvec_all(bvec, bio, i)
-		bio_size += bvec->bv_len;
+		ret += bvec->bv_len;
+	return ret;
+}
+
+/* Initialize a bvec_iter to the size of the specified bio. */
+static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
+{
+	const u32 bio_size = bio_get_size(bio);
 
 	return (struct bvec_iter) {
 		.bi_sector = 0,
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 230dd93dad6e..da2f57cbf07c 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1651,12 +1651,7 @@ static int get_bio_sector_nr(struct btrfs_raid_bio *rbio, struct bio *bio)
 static void rbio_update_error_bitmap(struct btrfs_raid_bio *rbio, struct bio *bio)
 {
 	int total_sector_nr = get_bio_sector_nr(rbio, bio);
-	u32 bio_size = 0;
-	struct bio_vec *bvec;
-	int i;
-
-	bio_for_each_bvec_all(bvec, bio, i)
-		bio_size += bvec->bv_len;
+	const u32 bio_size = bio_get_size(bio);
 
 	/*
 	 * Since we can have multiple bios touching the error_bitmap, we cannot
@@ -1664,7 +1659,7 @@ static void rbio_update_error_bitmap(struct btrfs_raid_bio *rbio, struct bio *bi
 	 *
 	 * Instead use set_bit() for each bit, as set_bit() itself is atomic.
 	 */
-	for (i = total_sector_nr; i < total_sector_nr +
+	for (int i = total_sector_nr; i < total_sector_nr +
 	     (bio_size >> rbio->bioc->fs_info->sectorsize_bits); i++)
 		set_bit(i, rbio->error_bitmap);
 }
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 2a64e2d50ced..9be663526672 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -892,16 +892,11 @@ static void scrub_repair_read_endio(struct btrfs_bio *bbio)
 {
 	struct scrub_stripe *stripe = bbio->private;
 	struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
-	struct bio_vec *bvec;
 	int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
-	u32 bio_size = 0;
-	int i;
+	const u32 bio_size = bio_get_size(&bbio->bio);
 
 	ASSERT(sector_nr < stripe->nr_sectors);
 
-	bio_for_each_bvec_all(bvec, &bbio->bio, i)
-		bio_size += bvec->bv_len;
-
 	if (bbio->bio.bi_status) {
 		scrub_bitmap_set_io_error(stripe, sector_nr,
 					  bio_size >> fs_info->sectorsize_bits);
@@ -1250,15 +1245,11 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
 static void scrub_read_endio(struct btrfs_bio *bbio)
 {
 	struct scrub_stripe *stripe = bbio->private;
-	struct bio_vec *bvec;
 	int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
 	int num_sectors;
-	u32 bio_size = 0;
-	int i;
+	const u32 bio_size = bio_get_size(&bbio->bio);
 
 	ASSERT(sector_nr < stripe->nr_sectors);
-	bio_for_each_bvec_all(bvec, &bbio->bio, i)
-		bio_size += bvec->bv_len;
 	num_sectors = bio_size >> stripe->bg->fs_info->sectorsize_bits;
 
 	if (bbio->bio.bi_status) {
@@ -1279,13 +1270,8 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
 {
 	struct scrub_stripe *stripe = bbio->private;
 	struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
-	struct bio_vec *bvec;
 	int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
-	u32 bio_size = 0;
-	int i;
-
-	bio_for_each_bvec_all(bvec, &bbio->bio, i)
-		bio_size += bvec->bv_len;
+	const u32 bio_size = bio_get_size(&bbio->bio);
 
 	if (bbio->bio.bi_status) {
 		unsigned long flags;
@@ -1294,7 +1280,7 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
 		bitmap_set(&stripe->write_error_bitmap, sector_nr,
 			   bio_size >> fs_info->sectorsize_bits);
 		spin_unlock_irqrestore(&stripe->write_error_lock, flags);
-		for (i = 0; i < (bio_size >> fs_info->sectorsize_bits); i++)
+		for (int i = 0; i < (bio_size >> fs_info->sectorsize_bits); i++)
 			btrfs_dev_stat_inc_and_print(stripe->dev,
 						     BTRFS_DEV_STAT_WRITE_ERRS);
 	}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] btrfs: reduce the size of compressed_bio
  2026-02-20  3:41 [PATCH 0/2] btrfs: remove compressed_bio::compressed_len Qu Wenruo
  2026-02-20  3:41 ` [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio Qu Wenruo
@ 2026-02-20  3:41 ` Qu Wenruo
  2026-02-24 14:35   ` David Sterba
  1 sibling, 1 reply; 8+ messages in thread
From: Qu Wenruo @ 2026-02-20  3:41 UTC (permalink / raw)
  To: linux-btrfs

The member compressed_bio::compressed_len can be replaced by the bio
size, as we always submit the full compressed data without any partial
read/write.

Furthermore we already have enough ASSERT()s making sure the bio size
matches the ordered extent or the extent map.

This saves 8 bytes from compressed_bio:

Before:

struct compressed_bio {
        u64                        start;                /*     0     8 */
        unsigned int               len;                  /*     8     4 */
        unsigned int               compressed_len;       /*    12     4 */
        u8                         compress_type;        /*    16     1 */
        bool                       writeback;            /*    17     1 */

        /* XXX 6 bytes hole, try to pack */

        struct btrfs_bio *         orig_bbio;            /*    24     8 */
        struct btrfs_bio           bbio __attribute__((__aligned__(8))); /*    32   304 */

        /* XXX last struct has 1 bit hole */

        /* size: 336, cachelines: 6, members: 7 */
        /* sum members: 330, holes: 1, sum holes: 6 */
        /* member types with bit holes: 1, total: 1 */
        /* forced alignments: 1 */
        /* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));

After:

 struct compressed_bio {
        u64                        start;                /*     0     8 */
        unsigned int               len;                  /*     8     4 */
        u8                         compress_type;        /*    12     1 */
        bool                       writeback;            /*    13     1 */

        /* XXX 2 bytes hole, try to pack */

        struct btrfs_bio *         orig_bbio;            /*    16     8 */
        struct btrfs_bio           bbio __attribute__((__aligned__(8))); /*    24   304 */

        /* XXX last struct has 1 bit hole */

        /* size: 328, cachelines: 6, members: 6 */
        /* sum members: 326, holes: 1, sum holes: 2 */
        /* member types with bit holes: 1, total: 1 */
        /* forced alignments: 1 */
        /* last cacheline: 8 bytes */
} __attribute__((__aligned__(8)));

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/compression.c | 2 --
 fs/btrfs/compression.h | 3 ---
 fs/btrfs/lzo.c         | 7 ++++---
 fs/btrfs/zlib.c        | 2 +-
 fs/btrfs/zstd.c        | 2 +-
 5 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 64600b6458cb..3a33c8fa96c8 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -330,7 +330,6 @@ void btrfs_submit_compressed_write(struct btrfs_ordered_extent *ordered,
 	cb->start = ordered->file_offset;
 	cb->len = ordered->num_bytes;
 	ASSERT(cb->bbio.bio.bi_iter.bi_size == ordered->disk_num_bytes);
-	cb->compressed_len = ordered->disk_num_bytes;
 	cb->bbio.bio.bi_iter.bi_sector = ordered->disk_bytenr >> SECTOR_SHIFT;
 	cb->bbio.ordered = ordered;
 
@@ -560,7 +559,6 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
 	em_start = em->start;
 
 	cb->len = bbio->bio.bi_iter.bi_size;
-	cb->compressed_len = compressed_len;
 	cb->compress_type = btrfs_extent_map_compression(em);
 	cb->orig_bbio = bbio;
 	cb->bbio.csum_search_commit_root = bbio->csum_search_commit_root;
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
index 65b8bc4bbe0b..84600b284e1e 100644
--- a/fs/btrfs/compression.h
+++ b/fs/btrfs/compression.h
@@ -48,9 +48,6 @@ struct compressed_bio {
 	/* Number of bytes in the inode we're working on */
 	unsigned int len;
 
-	/* Number of bytes on disk */
-	unsigned int compressed_len;
-
 	/* The compression algorithm for this bio */
 	u8 compress_type;
 
diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
index 971c2ea98e18..fdcce71c2326 100644
--- a/fs/btrfs/lzo.c
+++ b/fs/btrfs/lzo.c
@@ -431,6 +431,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
 	struct workspace *workspace = list_entry(ws, struct workspace, list);
 	struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;
 	const u32 sectorsize = fs_info->sectorsize;
+	const u32 compressed_len = bio_get_size(&cb->bbio.bio);
 	struct folio_iter fi;
 	char *kaddr;
 	int ret;
@@ -460,14 +461,14 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
 	 * and all sectors should be used.
 	 * If this happens, it means the compressed extent is corrupted.
 	 */
-	if (unlikely(len_in > min_t(size_t, BTRFS_MAX_COMPRESSED, cb->compressed_len) ||
-		     round_up(len_in, sectorsize) < cb->compressed_len)) {
+	if (unlikely(len_in > min_t(size_t, BTRFS_MAX_COMPRESSED, compressed_len) ||
+		     round_up(len_in, sectorsize) < compressed_len)) {
 		struct btrfs_inode *inode = cb->bbio.inode;
 
 		btrfs_err(fs_info,
 "lzo header invalid, root %llu inode %llu offset %llu lzo len %u compressed len %u",
 			  btrfs_root_id(inode->root), btrfs_ino(inode),
-			  cb->start, len_in, cb->compressed_len);
+			  cb->start, len_in, compressed_len);
 		return -EUCLEAN;
 	}
 
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index 0a8fcee16428..49676ad87815 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -349,7 +349,7 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
 	int wbits = MAX_WBITS;
 	char *data_in;
 	size_t total_out = 0;
-	size_t srclen = cb->compressed_len;
+	const size_t srclen = bio_get_size(&cb->bbio.bio);
 	unsigned long buf_start;
 
 	bio_first_folio(&fi, &cb->bbio.bio, 0);
diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
index c002d18666b7..3abb2b98caca 100644
--- a/fs/btrfs/zstd.c
+++ b/fs/btrfs/zstd.c
@@ -587,7 +587,7 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
 	struct btrfs_fs_info *fs_info = cb_to_fs_info(cb);
 	struct workspace *workspace = list_entry(ws, struct workspace, list);
 	struct folio_iter fi;
-	size_t srclen = cb->compressed_len;
+	size_t srclen = bio_get_size(&cb->bbio.bio);
 	zstd_dstream *stream;
 	int ret = 0;
 	const u32 blocksize = fs_info->sectorsize;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio
  2026-02-20  3:41 ` [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio Qu Wenruo
@ 2026-02-24 14:15   ` David Sterba
  2026-02-24 21:02     ` Qu Wenruo
  2026-02-24 22:21     ` Qu Wenruo
  0 siblings, 2 replies; 8+ messages in thread
From: David Sterba @ 2026-02-24 14:15 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Fri, Feb 20, 2026 at 02:11:50PM +1030, Qu Wenruo wrote:
> We have several call sites doing the same work to calculate the size of
> a bio:
> 
> 	struct bio_vec *bvec;
> 	u32 bio_size = 0;
> 	int i;
> 
> 	bio_for_each_bvec_all(bvec, bio, i)
> 		bio_size += bvec->bv_len;
> 
> We can use a common helper instead of open-coding it everywhere.
> 
> This also allows us to constify the @bio_size variables used in all the
> call sites.
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  fs/btrfs/misc.h   | 15 +++++++++++----
>  fs/btrfs/raid56.c |  9 ++-------
>  fs/btrfs/scrub.c  | 22 ++++------------------
>  3 files changed, 17 insertions(+), 29 deletions(-)
> 
> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h
> index 12c5a9d6564f..189c25cc5eff 100644
> --- a/fs/btrfs/misc.h
> +++ b/fs/btrfs/misc.h
> @@ -52,15 +52,22 @@ static inline phys_addr_t bio_iter_phys(struct bio *bio, struct bvec_iter *iter)
>  	     (paddr = bio_iter_phys((bio), (iter)), 1);			\
>  	     bio_advance_iter_single((bio), (iter), (blocksize)))
>  
> -/* Initialize a bvec_iter to the size of the specified bio. */
> -static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
> +/* Can only be called on a non-cloned bio. */

Please also add an ASSERT for that.

> +static inline u32 bio_get_size(struct bio *bio)

				  const ...

>  {
>  	struct bio_vec *bvec;
> -	u32 bio_size = 0;
> +	u32 ret = 0;
>  	int i;
>  
>  	bio_for_each_bvec_all(bvec, bio, i)
> -		bio_size += bvec->bv_len;
> +		ret += bvec->bv_len;
> +	return ret;
> +}

Reviewed-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] btrfs: reduce the size of compressed_bio
  2026-02-20  3:41 ` [PATCH 2/2] btrfs: reduce the size of compressed_bio Qu Wenruo
@ 2026-02-24 14:35   ` David Sterba
  0 siblings, 0 replies; 8+ messages in thread
From: David Sterba @ 2026-02-24 14:35 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Fri, Feb 20, 2026 at 02:11:51PM +1030, Qu Wenruo wrote:
> The member compressed_bio::compressed_len can be replaced by the bio
> size, as we always submit the full compressed data without any partial
> read/write.
> 
> Furthermore we already have enough ASSERT()s making sure the bio size
> matches the ordered extent or the extent map.
> 
> This saves 8 bytes from compressed_bio:
> 
> Before:
> 
>  struct compressed_bio {
>         u64                        start;                /*     0     8 */
>         unsigned int               len;                  /*     8     4 */
>         u8                         compress_type;        /*    12     1 */
>         bool                       writeback;            /*    13     1 */
> 
>         /* XXX 2 bytes hole, try to pack */
> 
>         struct btrfs_bio *         orig_bbio;            /*    16     8 */
>         struct btrfs_bio           bbio __attribute__((__aligned__(8))); /*    24   304 */
> 
>         /* XXX last struct has 1 bit hole */
> 
>         /* size: 328, cachelines: 6, members: 6 */
>         /* sum members: 326, holes: 1, sum holes: 2 */
>         /* member types with bit holes: 1, total: 1 */
>         /* forced alignments: 1 */
>         /* last cacheline: 8 bytes */
> } __attribute__((__aligned__(8)));

Nice and I think we can't do much better here. Two bytes left for flags
if needed.

Reviewed-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio
  2026-02-24 14:15   ` David Sterba
@ 2026-02-24 21:02     ` Qu Wenruo
  2026-02-25  0:59       ` David Sterba
  2026-02-24 22:21     ` Qu Wenruo
  1 sibling, 1 reply; 8+ messages in thread
From: Qu Wenruo @ 2026-02-24 21:02 UTC (permalink / raw)
  To: dsterba, Qu Wenruo; +Cc: linux-btrfs



在 2026/2/25 00:45, David Sterba 写道:
> On Fri, Feb 20, 2026 at 02:11:50PM +1030, Qu Wenruo wrote:
>> We have several call sites doing the same work to calculate the size of
>> a bio:
>>
>> 	struct bio_vec *bvec;
>> 	u32 bio_size = 0;
>> 	int i;
>>
>> 	bio_for_each_bvec_all(bvec, bio, i)
>> 		bio_size += bvec->bv_len;
>>
>> We can use a common helper instead of open-coding it everywhere.
>>
>> This also allows us to constify the @bio_size variables used in all the
>> call sites.
>>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   fs/btrfs/misc.h   | 15 +++++++++++----
>>   fs/btrfs/raid56.c |  9 ++-------
>>   fs/btrfs/scrub.c  | 22 ++++------------------
>>   3 files changed, 17 insertions(+), 29 deletions(-)
>>
>> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h
>> index 12c5a9d6564f..189c25cc5eff 100644
>> --- a/fs/btrfs/misc.h
>> +++ b/fs/btrfs/misc.h
>> @@ -52,15 +52,22 @@ static inline phys_addr_t bio_iter_phys(struct bio *bio, struct bvec_iter *iter)
>>   	     (paddr = bio_iter_phys((bio), (iter)), 1);			\
>>   	     bio_advance_iter_single((bio), (iter), (blocksize)))
>>   
>> -/* Initialize a bvec_iter to the size of the specified bio. */
>> -static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
>> +/* Can only be called on a non-cloned bio. */
> 
> Please also add an ASSERT for that.

You know how I like to add ASSERT()s almost everywhere, but for this 
it's already implied.

bio_first_bvec_all() has a WARN_ON_ONCE() line for it already.

Thanks,
Qu

> 
>> +static inline u32 bio_get_size(struct bio *bio)
> 
> 				  const ...
> 
>>   {
>>   	struct bio_vec *bvec;
>> -	u32 bio_size = 0;
>> +	u32 ret = 0;
>>   	int i;
>>   
>>   	bio_for_each_bvec_all(bvec, bio, i)
>> -		bio_size += bvec->bv_len;
>> +		ret += bvec->bv_len;
>> +	return ret;
>> +}
> 
> Reviewed-by: David Sterba <dsterba@suse.com>
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio
  2026-02-24 14:15   ` David Sterba
  2026-02-24 21:02     ` Qu Wenruo
@ 2026-02-24 22:21     ` Qu Wenruo
  1 sibling, 0 replies; 8+ messages in thread
From: Qu Wenruo @ 2026-02-24 22:21 UTC (permalink / raw)
  To: dsterba; +Cc: linux-btrfs



在 2026/2/25 00:45, David Sterba 写道:
> On Fri, Feb 20, 2026 at 02:11:50PM +1030, Qu Wenruo wrote:
>> We have several call sites doing the same work to calculate the size of
>> a bio:
>>
>> 	struct bio_vec *bvec;
>> 	u32 bio_size = 0;
>> 	int i;
>>
>> 	bio_for_each_bvec_all(bvec, bio, i)
>> 		bio_size += bvec->bv_len;
>>
>> We can use a common helper instead of open-coding it everywhere.
>>
>> This also allows us to constify the @bio_size variables used in all the
>> call sites.
>>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   fs/btrfs/misc.h   | 15 +++++++++++----
>>   fs/btrfs/raid56.c |  9 ++-------
>>   fs/btrfs/scrub.c  | 22 ++++------------------
>>   3 files changed, 17 insertions(+), 29 deletions(-)
>>
>> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h
>> index 12c5a9d6564f..189c25cc5eff 100644
>> --- a/fs/btrfs/misc.h
>> +++ b/fs/btrfs/misc.h
>> @@ -52,15 +52,22 @@ static inline phys_addr_t bio_iter_phys(struct bio *bio, struct bvec_iter *iter)
>>   	     (paddr = bio_iter_phys((bio), (iter)), 1);			\
>>   	     bio_advance_iter_single((bio), (iter), (blocksize)))
>>   
>> -/* Initialize a bvec_iter to the size of the specified bio. */
>> -static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
>> +/* Can only be called on a non-cloned bio. */
> 
> Please also add an ASSERT for that.
> 
>> +static inline u32 bio_get_size(struct bio *bio)
> 
> 				  const ...

Won't work. bio_for_each_bvec_call() will cause warning, as 
bio_first_bvec_all() doesn't have const qualifier for the bio.

And if you're on GCC 15.2.1, it will require much more strict checks for 
const qualifier, to make sure all access to that pointer won't modify 
its content.

This is already causing some proxy writes to cause problems in btrfs-progs.

We need to be more cautious with const usage with newer GCC.

Thanks,
Qu

> 
>>   {
>>   	struct bio_vec *bvec;
>> -	u32 bio_size = 0;
>> +	u32 ret = 0;
>>   	int i;
>>   
>>   	bio_for_each_bvec_all(bvec, bio, i)
>> -		bio_size += bvec->bv_len;
>> +		ret += bvec->bv_len;
>> +	return ret;
>> +}
> 
> Reviewed-by: David Sterba <dsterba@suse.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio
  2026-02-24 21:02     ` Qu Wenruo
@ 2026-02-25  0:59       ` David Sterba
  0 siblings, 0 replies; 8+ messages in thread
From: David Sterba @ 2026-02-25  0:59 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: Qu Wenruo, linux-btrfs

On Wed, Feb 25, 2026 at 07:32:48AM +1030, Qu Wenruo wrote:
> 在 2026/2/25 00:45, David Sterba 写道:
> > On Fri, Feb 20, 2026 at 02:11:50PM +1030, Qu Wenruo wrote:
> >> We have several call sites doing the same work to calculate the size of
> >> a bio:
> >>
> >> 	struct bio_vec *bvec;
> >> 	u32 bio_size = 0;
> >> 	int i;
> >>
> >> 	bio_for_each_bvec_all(bvec, bio, i)
> >> 		bio_size += bvec->bv_len;
> >>
> >> We can use a common helper instead of open-coding it everywhere.
> >>
> >> This also allows us to constify the @bio_size variables used in all the
> >> call sites.
> >>
> >> Signed-off-by: Qu Wenruo <wqu@suse.com>
> >> ---
> >>   fs/btrfs/misc.h   | 15 +++++++++++----
> >>   fs/btrfs/raid56.c |  9 ++-------
> >>   fs/btrfs/scrub.c  | 22 ++++------------------
> >>   3 files changed, 17 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h
> >> index 12c5a9d6564f..189c25cc5eff 100644
> >> --- a/fs/btrfs/misc.h
> >> +++ b/fs/btrfs/misc.h
> >> @@ -52,15 +52,22 @@ static inline phys_addr_t bio_iter_phys(struct bio *bio, struct bvec_iter *iter)
> >>   	     (paddr = bio_iter_phys((bio), (iter)), 1);			\
> >>   	     bio_advance_iter_single((bio), (iter), (blocksize)))
> >>   
> >> -/* Initialize a bvec_iter to the size of the specified bio. */
> >> -static inline struct bvec_iter init_bvec_iter_for_bio(struct bio *bio)
> >> +/* Can only be called on a non-cloned bio. */
> > 
> > Please also add an ASSERT for that.
> 
> You know how I like to add ASSERT()s almost everywhere, but for this 
> it's already implied.
> 
> bio_first_bvec_all() has a WARN_ON_ONCE() line for it already.

Ok that's good, I didn't know that.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-02-25  0:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-20  3:41 [PATCH 0/2] btrfs: remove compressed_bio::compressed_len Qu Wenruo
2026-02-20  3:41 ` [PATCH 1/2] btrfs: introduce a common helper to calculate the size of a bio Qu Wenruo
2026-02-24 14:15   ` David Sterba
2026-02-24 21:02     ` Qu Wenruo
2026-02-25  0:59       ` David Sterba
2026-02-24 22:21     ` Qu Wenruo
2026-02-20  3:41 ` [PATCH 2/2] btrfs: reduce the size of compressed_bio Qu Wenruo
2026-02-24 14:35   ` David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox