mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
btrfs: reduce chunk_map lookups in btrfs_map_block()
Currently we're calling btrfs_num_copies() before btrfs_get_chunk_map() in btrfs_map_block(). But btrfs_num_copies() itself does a chunk map lookup to be able to calculate the number of copies. So split out the code getting the number of copies from btrfs_num_copies() into a helper called btrfs_chunk_map_num_copies() and directly call it from btrfs_map_block() and btrfs_num_copies(). This saves us one rbtree lookup per btrfs_map_block() invocation. Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
6d752cacae
commit
0ae653fbec
|
|
@ -5781,11 +5781,31 @@ void btrfs_mapping_tree_free(struct btrfs_fs_info *fs_info)
|
||||||
write_unlock(&fs_info->mapping_tree_lock);
|
write_unlock(&fs_info->mapping_tree_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int btrfs_chunk_map_num_copies(const struct btrfs_chunk_map *map)
|
||||||
|
{
|
||||||
|
enum btrfs_raid_types index = btrfs_bg_flags_to_raid_index(map->type);
|
||||||
|
|
||||||
|
if (map->type & BTRFS_BLOCK_GROUP_RAID5)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There could be two corrupted data stripes, we need to loop retry in
|
||||||
|
* order to rebuild the correct data.
|
||||||
|
*
|
||||||
|
* Fail a stripe at a time on every retry except the stripe under
|
||||||
|
* reconstruction.
|
||||||
|
*/
|
||||||
|
if (map->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||||
|
return map->num_stripes;
|
||||||
|
|
||||||
|
/* Non-RAID56, use their ncopies from btrfs_raid_array. */
|
||||||
|
return btrfs_raid_array[index].ncopies;
|
||||||
|
}
|
||||||
|
|
||||||
int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
|
int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
|
||||||
{
|
{
|
||||||
struct btrfs_chunk_map *map;
|
struct btrfs_chunk_map *map;
|
||||||
enum btrfs_raid_types index;
|
int ret;
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
map = btrfs_get_chunk_map(fs_info, logical, len);
|
map = btrfs_get_chunk_map(fs_info, logical, len);
|
||||||
if (IS_ERR(map))
|
if (IS_ERR(map))
|
||||||
|
|
@ -5797,22 +5817,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
|
||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
index = btrfs_bg_flags_to_raid_index(map->type);
|
ret = btrfs_chunk_map_num_copies(map);
|
||||||
|
|
||||||
/* Non-RAID56, use their ncopies from btrfs_raid_array. */
|
|
||||||
if (!(map->type & BTRFS_BLOCK_GROUP_RAID56_MASK))
|
|
||||||
ret = btrfs_raid_array[index].ncopies;
|
|
||||||
else if (map->type & BTRFS_BLOCK_GROUP_RAID5)
|
|
||||||
ret = 2;
|
|
||||||
else if (map->type & BTRFS_BLOCK_GROUP_RAID6)
|
|
||||||
/*
|
|
||||||
* There could be two corrupted data stripes, we need
|
|
||||||
* to loop retry in order to rebuild the correct data.
|
|
||||||
*
|
|
||||||
* Fail a stripe at a time on every retry except the
|
|
||||||
* stripe under reconstruction.
|
|
||||||
*/
|
|
||||||
ret = map->num_stripes;
|
|
||||||
btrfs_free_chunk_map(map);
|
btrfs_free_chunk_map(map);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -6462,14 +6467,14 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
|
||||||
io_geom.stripe_index = 0;
|
io_geom.stripe_index = 0;
|
||||||
io_geom.op = op;
|
io_geom.op = op;
|
||||||
|
|
||||||
num_copies = btrfs_num_copies(fs_info, logical, fs_info->sectorsize);
|
|
||||||
if (io_geom.mirror_num > num_copies)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
map = btrfs_get_chunk_map(fs_info, logical, *length);
|
map = btrfs_get_chunk_map(fs_info, logical, *length);
|
||||||
if (IS_ERR(map))
|
if (IS_ERR(map))
|
||||||
return PTR_ERR(map);
|
return PTR_ERR(map);
|
||||||
|
|
||||||
|
num_copies = btrfs_chunk_map_num_copies(map);
|
||||||
|
if (io_geom.mirror_num > num_copies)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
map_offset = logical - map->start;
|
map_offset = logical - map->start;
|
||||||
io_geom.raid56_full_stripe_start = (u64)-1;
|
io_geom.raid56_full_stripe_start = (u64)-1;
|
||||||
max_len = btrfs_max_io_len(map, map_offset, &io_geom);
|
max_len = btrfs_max_io_len(map, map_offset, &io_geom);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user