mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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:
committed by
David Sterba
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
|
* @fs_info: the filesystem
|
||||||
* @chunk_start: logical address of block group
|
* @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
|
* @physical: physical address to map to logical addresses
|
||||||
* @logical: return array of logical addresses which map to @physical
|
* @logical: return array of logical addresses which map to @physical
|
||||||
* @naddrs: length of @logical
|
* @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
|
* Used primarily to exclude those portions of a block group that contain super
|
||||||
* block copies.
|
* block copies.
|
||||||
*/
|
*/
|
||||||
EXPORT_FOR_TESTS
|
|
||||||
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
|
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 extent_map *em;
|
||||||
struct map_lookup *map;
|
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;
|
map = em->map_lookup;
|
||||||
data_stripe_length = em->orig_block_len;
|
data_stripe_length = em->orig_block_len;
|
||||||
io_stripe_size = map->stripe_len;
|
io_stripe_size = map->stripe_len;
|
||||||
|
chunk_start = em->start;
|
||||||
|
|
||||||
/* For RAID5/6 adjust to a full IO stripe length */
|
/* For RAID5/6 adjust to a full IO stripe length */
|
||||||
if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
|
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++) {
|
for (i = 0; i < map->num_stripes; i++) {
|
||||||
bool already_inserted = false;
|
bool already_inserted = false;
|
||||||
u64 stripe_nr;
|
u64 stripe_nr;
|
||||||
|
u64 offset;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (!in_range(physical, map->stripes[i].physical,
|
if (!in_range(physical, map->stripes[i].physical,
|
||||||
data_stripe_length))
|
data_stripe_length))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (bdev && map->stripes[i].dev->bdev != bdev)
|
||||||
|
continue;
|
||||||
|
|
||||||
stripe_nr = physical - map->stripes[i].physical;
|
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) {
|
if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
|
||||||
stripe_nr = stripe_nr * map->num_stripes + i;
|
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
|
* 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 */
|
/* Ensure we don't add duplicate addresses */
|
||||||
for (j = 0; j < nr; j++) {
|
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++) {
|
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||||
bytenr = btrfs_sb_offset(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);
|
bytenr, &logical, &nr, &stripe_len);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
int btrfs_free_block_groups(struct btrfs_fs_info *info);
|
||||||
void btrfs_wait_space_cache_v1_finished(struct btrfs_block_group *cache,
|
void btrfs_wait_space_cache_v1_finished(struct btrfs_block_group *cache,
|
||||||
struct btrfs_caching_control *caching_ctl);
|
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)
|
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_freeze_block_group(struct btrfs_block_group *cache);
|
||||||
void btrfs_unfreeze_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 */
|
#endif /* BTRFS_BLOCK_GROUP_H */
|
||||||
|
@@ -507,7 +507,7 @@ static int test_rmap_block(struct btrfs_fs_info *fs_info,
|
|||||||
goto out_free;
|
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);
|
&logical, &out_ndaddrs, &out_stripe_len);
|
||||||
if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
|
if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
|
||||||
test_err("didn't rmap anything but expected %d",
|
test_err("didn't rmap anything but expected %d",
|
||||||
|
Reference in New Issue
Block a user