From c4bc2dd32c63a70ed948ed9927ea2c46f7c5b454 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Fri, 20 Feb 2026 14:11:50 +1030 Subject: [PATCH] btrfs: introduce a common helper to calculate the size of a bio 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 Reviewed-by: David Sterba Signed-off-by: David Sterba --- 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 40433a86fe49..694be6d0562a 100644 --- a/fs/btrfs/misc.h +++ b/fs/btrfs/misc.h @@ -53,15 +53,22 @@ static inline phys_addr_t bio_iter_phys(const struct bio *bio, (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 02105d68accb..aacf5e4eb765 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -1653,12 +1653,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 @@ -1666,7 +1661,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 bc94bbc00772..0234971894fa 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -891,16 +891,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); @@ -1249,15 +1244,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) { @@ -1278,13 +1269,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; @@ -1293,7 +1279,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); }