On 2022/3/22 23:55, Christoph Hellwig wrote:
Clear need_raid_map early instead of repeating the same conditional over and over.
I had a more comprehensive cleanup, but only for scrub: https://lore.kernel.org/linux-btrfs/cover.1646984153.git.wqu@xxxxxxxx/ All profiles are split into 3 categories: - Simple mirror Single, DUP, RAID1*. - Simple stripe RAID0 and RAID10 Inside each data stripe, it's just simple mirror then. - RAID56 And for mirror_num == 0/1 cases, inside one data stripe it's still simple mirror. Maybe we can follow the same ideas here? Thanks, Qu
Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/btrfs/volumes.c | 60 ++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1cf0914b33847..cc9e2565e4b64 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6435,6 +6435,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, map = em->map_lookup; + if (!(map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) || + (!need_full_stripe(op) && mirror_num <= 1)) + need_raid_map = 0; + *length = geom.len; stripe_len = geom.stripe_len; stripe_nr = geom.stripe_nr; @@ -6509,37 +6513,32 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, dev_replace_is_ongoing); mirror_num = stripe_index - old_stripe_index + 1; } + } else if (need_raid_map) { + /* push stripe_nr back to the start of the full stripe */ + stripe_nr = div64_u64(raid56_full_stripe_start, + stripe_len * data_stripes); - } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { - if (need_raid_map && (need_full_stripe(op) || mirror_num > 1)) { - /* push stripe_nr back to the start of the full stripe */ - stripe_nr = div64_u64(raid56_full_stripe_start, - stripe_len * data_stripes); - - /* RAID[56] write or recovery. Return all stripes */ - num_stripes = map->num_stripes; - max_errors = nr_parity_stripes(map); - - *length = map->stripe_len; - stripe_index = 0; - stripe_offset = 0; - } else { - /* - * Mirror #0 or #1 means the original data block. - * Mirror #2 is RAID5 parity block. - * Mirror #3 is RAID6 Q block. - */ - stripe_nr = div_u64_rem(stripe_nr, - data_stripes, &stripe_index); - if (mirror_num > 1) - stripe_index = data_stripes + mirror_num - 2; + /* RAID[56] write or recovery. Return all stripes */ + num_stripes = map->num_stripes; + max_errors = nr_parity_stripes(map); - /* We distribute the parity blocks across stripes */ - div_u64_rem(stripe_nr + stripe_index, map->num_stripes, - &stripe_index); - if (!need_full_stripe(op) && mirror_num <= 1) - mirror_num = 1; - } + *length = map->stripe_len; + stripe_index = 0; + stripe_offset = 0; + } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { + /* + * Mirror #0 or #1 means the original data block. + * Mirror #2 is RAID5 parity block. + * Mirror #3 is RAID6 Q block. + */ + stripe_nr = div_u64_rem(stripe_nr, data_stripes, &stripe_index); + if (mirror_num > 1) + stripe_index = data_stripes + mirror_num - 2; + /* We distribute the parity blocks across stripes */ + div_u64_rem(stripe_nr + stripe_index, map->num_stripes, + &stripe_index); + if (!need_full_stripe(op) && mirror_num <= 1) + mirror_num = 1; } else { /* * after this, stripe_nr is the number of stripes on this @@ -6581,8 +6580,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, } /* Build raid_map */ - if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK && need_raid_map && - (need_full_stripe(op) || mirror_num > 1)) { + if (need_raid_map) { u64 tmp; unsigned rot;