Commit 0ae653fb authored by Johannes Thumshirn's avatar Johannes Thumshirn Committed by David Sterba
Browse files

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: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 6d752cac
Loading
Loading
Loading
Loading
+27 −22
Original line number Diff line number Diff line
@@ -5781,11 +5781,31 @@ void btrfs_mapping_tree_free(struct btrfs_fs_info *fs_info)
	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)
{
	struct btrfs_chunk_map *map;
	enum btrfs_raid_types index;
	int ret = 1;
	int ret;

	map = btrfs_get_chunk_map(fs_info, logical, len);
	if (IS_ERR(map))
@@ -5797,22 +5817,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
		 */
		return 1;

	index = btrfs_bg_flags_to_raid_index(map->type);

	/* 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;
	ret = btrfs_chunk_map_num_copies(map);
	btrfs_free_chunk_map(map);
	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.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);
	if (IS_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;
	io_geom.raid56_full_stripe_start = (u64)-1;
	max_len = btrfs_max_io_len(map, map_offset, &io_geom);