Messages in this thread Patch in this message | | | From | Johannes Thumshirn <> | Date | Tue, 12 Dec 2023 04:38:06 -0800 | Subject | [PATCH 08/13] btrfs: factor out block mapping for RAID5/6 |
| |
Now that we have a container for the I/O geometry that has all the needed information for the block mappings of RAID5 and RAID6, factor out a helper calculating this information.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- fs/btrfs/volumes.c | 91 +++++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 42 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bc0988d8bd56..fd213bb7d619 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6437,6 +6437,54 @@ static void map_blocks_for_raid10(struct btrfs_fs_info *fs_info, io_geom->mirror_num = io_geom->stripe_index - old_stripe_index + 1; } +static void map_blocks_for_raid56(struct btrfs_chunk_map *map, + enum btrfs_map_op op, + struct btrfs_io_geometry *io_geom, + u64 logical, u64 *length) +{ + int data_stripes = nr_data_stripes(map); + + if (op != BTRFS_MAP_READ || io_geom->mirror_num > 1) { + /* + * Needs full stripe mapping. + * + * Push stripe_nr back to the start of the full stripe + * For those cases needing a full stripe, @stripe_nr + * is the full stripe number. + * + * Originally we go raid56_full_stripe_start / full_stripe_len, + * but that can be expensive. Here we just divide + * @stripe_nr with @data_stripes. + */ + io_geom->stripe_nr /= data_stripes; + + /* RAID[56] write or recovery. Return all stripes */ + io_geom->num_stripes = map->num_stripes; + io_geom->max_errors = btrfs_chunk_max_errors(map); + + /* Return the length to the full stripe end */ + *length = min(logical + *length, + io_geom->raid56_full_stripe_start + map->start + + btrfs_stripe_nr_to_offset(data_stripes)) - + logical; + io_geom->stripe_index = 0; + io_geom->stripe_offset = 0; + return; + } + + ASSERT(io_geom->mirror_num <= 1); + /* Just grab the data stripe directly. */ + io_geom->stripe_index = io_geom->stripe_nr % data_stripes; + io_geom->stripe_nr /= data_stripes; + + /* We distribute the parity blocks across stripes */ + io_geom->stripe_index = + (io_geom->stripe_nr + io_geom->stripe_index) % map->num_stripes; + + if (op == BTRFS_MAP_READ && io_geom->mirror_num < 1) + io_geom->mirror_num = 1; +} + /* * Map one logical range to one or more physical ranges. * @@ -6529,48 +6577,7 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op, map_blocks_for_raid10(fs_info, map, op, &io_geom, dev_replace_is_ongoing); } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { - int data_stripes = nr_data_stripes(map); - - if (op != BTRFS_MAP_READ || io_geom.mirror_num > 1) { - /* - * Needs full stripe mapping. - * - * Push stripe_nr back to the start of the full stripe - * For those cases needing a full stripe, @stripe_nr - * is the full stripe number. - * - * Originally we go raid56_full_stripe_start / full_stripe_len, - * but that can be expensive. Here we just divide - * @stripe_nr with @data_stripes. - */ - io_geom.stripe_nr /= data_stripes; - - /* RAID[56] write or recovery. Return all stripes */ - io_geom.num_stripes = map->num_stripes; - io_geom.max_errors = btrfs_chunk_max_errors(map); - - /* Return the length to the full stripe end */ - *length = min(logical + *length, - io_geom.raid56_full_stripe_start + - map->start + - btrfs_stripe_nr_to_offset( - data_stripes)) - - logical; - io_geom.stripe_index = 0; - io_geom.stripe_offset = 0; - } else { - ASSERT(io_geom.mirror_num <= 1); - /* Just grab the data stripe directly. */ - io_geom.stripe_index = io_geom.stripe_nr % data_stripes; - io_geom.stripe_nr /= data_stripes; - - /* We distribute the parity blocks across stripes */ - io_geom.stripe_index = - (io_geom.stripe_nr + io_geom.stripe_index) % - map->num_stripes; - if (op == BTRFS_MAP_READ && io_geom.mirror_num < 1) - io_geom.mirror_num = 1; - } + map_blocks_for_raid56(map, op, &io_geom, logical, length); } else { /* * After this, stripe_nr is the number of stripes on this -- 2.43.0
| |