[PATCH RFC 02/11] btrfs: refactor btrfs_map_bio()

Qu Wenruo
2021-11-28T05:55:26Z

Currently in btrfs_map_bio() we call __btrfs_map_block(), then using the
returned bioc to submit real stripes.

This is fine if we're only going to handle one bio a time.

For the incoming bio split at btrfs_map_bio() time, we want to handle
several differnet bios, thus there we introduce a new helper,
submit_one_mapped_range() to handle the submission part, making it much
easier to make it work in a loop.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/volumes.c | 65 ++++++++++++++++++++++++++++------------------
1 file changed, 40 insertions(+), 25 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3dc1de376966..1d40f4fa64a3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6772,29 +6772,15 @@ static void bioc_error(struct btrfs_io_context *bioc, struct bio *bio, u64 logic
}
}

-blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
- int mirror_num)
+static int submit_one_mapped_range(struct btrfs_fs_info *fs_info, struct bio *bio,
+ struct btrfs_io_context *bioc, u64 map_length,
+ int mirror_num)
{
- struct btrfs_device *dev;
struct bio *first_bio = bio;
- u64 logical = bio->bi_iter.bi_sector << 9;
- u64 length = 0;
- u64 map_length;
- int ret;
- int dev_nr;
+ u64 logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
int total_devs;
- struct btrfs_io_context *bioc = NULL;
-
- length = bio->bi_iter.bi_size;
- map_length = length;
-
- btrfs_bio_counter_inc_blocked(fs_info);
- ret = __btrfs_map_block(fs_info, btrfs_op(bio), logical,
- &map_length, &bioc, mirror_num, 1);
- if (ret) {
- btrfs_bio_counter_dec(fs_info);
- return errno_to_blk_status(ret);
- }
+ int dev_nr;
+ int ret;

total_devs = bioc->num_stripes;
bioc->orig_bio = first_bio;
@@ -6813,18 +6799,19 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
mirror_num, 1);
}

- btrfs_bio_counter_dec(fs_info);
- return errno_to_blk_status(ret);
+ return ret;
}

- if (map_length < length) {
+ if (map_length < bio->bi_iter.bi_size) {
btrfs_crit(fs_info,
- "mapping failed logical %llu bio len %llu len %llu",
- logical, length, map_length);
+ "mapping failed logical %llu bio len %u len %llu",
+ logical, bio->bi_iter.bi_size, map_length);
BUG();
}

for (dev_nr = 0; dev_nr < total_devs; dev_nr++) {
+ struct btrfs_device *dev;
+
dev = bioc->stripes[dev_nr].dev;
if (!dev || !dev->bdev || test_bit(BTRFS_DEV_STATE_MISSING,
&dev->dev_state) ||
@@ -6841,6 +6828,34 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,

submit_stripe_bio(bioc, bio, bioc->stripes[dev_nr].physical, dev);
}
+ return 0;
+}
+
+blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
+ int mirror_num)
+{
+ u64 logical = bio->bi_iter.bi_sector << 9;
+ u64 length = 0;
+ u64 map_length;
+ int ret;
+ struct btrfs_io_context *bioc = NULL;
+
+ length = bio->bi_iter.bi_size;
+ map_length = length;
+
+ btrfs_bio_counter_inc_blocked(fs_info);
+ ret = __btrfs_map_block(fs_info, btrfs_op(bio), logical,
+ &map_length, &bioc, mirror_num, 1);
+ if (ret) {
+ btrfs_bio_counter_dec(fs_info);
+ return errno_to_blk_status(ret);
+ }
+
+ ret = submit_one_mapped_range(fs_info, bio, bioc, map_length, mirror_num);
+ if (ret < 0) {
+ btrfs_bio_counter_dec(fs_info);
+ return errno_to_blk_status(ret);
+ }
btrfs_bio_counter_dec(fs_info);
return BLK_STS_OK;
}
--
2.34.0