btrfs: extend btrfs_rmap_block for specifying a device
btrfs_rmap_block currently reverse-maps the physical addresses on all devices to the corresponding logical addresses. Extend the function to match to a specified device. The old functionality of querying all devices is left intact by specifying NULL as target device. A block_device instead of a btrfs_device is passed into btrfs_rmap_block, as this function is intended to reverse-map the result of a bio, which only has a block_device. Also export the function for later use. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
cacb2cea46
commit
138082f366
@ -1588,6 +1588,7 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
|
||||
*
|
||||
* @fs_info: the filesystem
|
||||
* @chunk_start: logical address of block group
|
||||
* @bdev: physical device to resolve, can be NULL to indicate any device
|
||||
* @physical: physical address to map to logical addresses
|
||||
* @logical: return array of logical addresses which map to @physical
|
||||
* @naddrs: length of @logical
|
||||
@ -1597,9 +1598,9 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
|
||||
* Used primarily to exclude those portions of a block group that contain super
|
||||
* block copies.
|
||||
*/
|
||||
EXPORT_FOR_TESTS
|
||||
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
u64 physical, u64 **logical, int *naddrs, int *stripe_len)
|
||||
struct block_device *bdev, u64 physical, u64 **logical,
|
||||
int *naddrs, int *stripe_len)
|
||||
{
|
||||
struct extent_map *em;
|
||||
struct map_lookup *map;
|
||||
@ -1617,6 +1618,7 @@ int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
map = em->map_lookup;
|
||||
data_stripe_length = em->orig_block_len;
|
||||
io_stripe_size = map->stripe_len;
|
||||
chunk_start = em->start;
|
||||
|
||||
/* For RAID5/6 adjust to a full IO stripe length */
|
||||
if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
|
||||
@ -1631,14 +1633,18 @@ int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
for (i = 0; i < map->num_stripes; i++) {
|
||||
bool already_inserted = false;
|
||||
u64 stripe_nr;
|
||||
u64 offset;
|
||||
int j;
|
||||
|
||||
if (!in_range(physical, map->stripes[i].physical,
|
||||
data_stripe_length))
|
||||
continue;
|
||||
|
||||
if (bdev && map->stripes[i].dev->bdev != bdev)
|
||||
continue;
|
||||
|
||||
stripe_nr = physical - map->stripes[i].physical;
|
||||
stripe_nr = div64_u64(stripe_nr, map->stripe_len);
|
||||
stripe_nr = div64_u64_rem(stripe_nr, map->stripe_len, &offset);
|
||||
|
||||
if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
|
||||
stripe_nr = stripe_nr * map->num_stripes + i;
|
||||
@ -1652,7 +1658,7 @@ int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
* instead of map->stripe_len
|
||||
*/
|
||||
|
||||
bytenr = chunk_start + stripe_nr * io_stripe_size;
|
||||
bytenr = chunk_start + stripe_nr * io_stripe_size + offset;
|
||||
|
||||
/* Ensure we don't add duplicate addresses */
|
||||
for (j = 0; j < nr; j++) {
|
||||
@ -1694,7 +1700,7 @@ static int exclude_super_stripes(struct btrfs_block_group *cache)
|
||||
|
||||
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||
bytenr = btrfs_sb_offset(i);
|
||||
ret = btrfs_rmap_block(fs_info, cache->start,
|
||||
ret = btrfs_rmap_block(fs_info, cache->start, NULL,
|
||||
bytenr, &logical, &nr, &stripe_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -277,6 +277,9 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
|
||||
int btrfs_free_block_groups(struct btrfs_fs_info *info);
|
||||
void btrfs_wait_space_cache_v1_finished(struct btrfs_block_group *cache,
|
||||
struct btrfs_caching_control *caching_ctl);
|
||||
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
struct block_device *bdev, u64 physical, u64 **logical,
|
||||
int *naddrs, int *stripe_len);
|
||||
|
||||
static inline u64 btrfs_data_alloc_profile(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
@ -303,9 +306,4 @@ static inline int btrfs_block_group_done(struct btrfs_block_group *cache)
|
||||
void btrfs_freeze_block_group(struct btrfs_block_group *cache);
|
||||
void btrfs_unfreeze_block_group(struct btrfs_block_group *cache);
|
||||
|
||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
||||
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
||||
u64 physical, u64 **logical, int *naddrs, int *stripe_len);
|
||||
#endif
|
||||
|
||||
#endif /* BTRFS_BLOCK_GROUP_H */
|
||||
|
@ -507,7 +507,7 @@ static int test_rmap_block(struct btrfs_fs_info *fs_info,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = btrfs_rmap_block(fs_info, em->start, btrfs_sb_offset(1),
|
||||
ret = btrfs_rmap_block(fs_info, em->start, NULL, btrfs_sb_offset(1),
|
||||
&logical, &out_ndaddrs, &out_stripe_len);
|
||||
if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
|
||||
test_err("didn't rmap anything but expected %d",
|
||||
|
Loading…
Reference in New Issue
Block a user