diff options
| -rw-r--r-- | fs/btrfs/block-group.c | 16 | ||||
| -rw-r--r-- | fs/btrfs/block-group.h | 8 | ||||
| -rw-r--r-- | fs/btrfs/tests/extent-map-tests.c | 2 | 
3 files changed, 15 insertions, 11 deletions
| diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 70a0c0f8f99f..f5e9f560ce6d 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -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; diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h index 0fd66febe115..d14ac03bb93d 100644 --- a/fs/btrfs/block-group.h +++ b/fs/btrfs/block-group.h @@ -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 */ diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c index 57379e96ccc9..c0aefe6dee0b 100644 --- a/fs/btrfs/tests/extent-map-tests.c +++ b/fs/btrfs/tests/extent-map-tests.c @@ -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", | 
