mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
btrfs: add do_remap parameter to btrfs_discard_extent()
btrfs_discard_extent() can be called either when an extent is removed or from walking the free-space tree. With a remapped block group these two things are no longer equivalent: the extent's addresses are remapped, while the free-space tree exclusively uses underlying addresses. Add a do_remap parameter to btrfs_discard_extent() and btrfs_map_discard(), saying whether or not the address needs to be run through the remap tree first. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Mark Harmstone <mark@harmstone.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
fd6594b144
commit
a645372e7e
6 changed files with 29 additions and 10 deletions
|
|
@ -1381,7 +1381,7 @@ out:
|
|||
}
|
||||
|
||||
int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
|
||||
u64 num_bytes, u64 *actual_bytes)
|
||||
u64 num_bytes, u64 *actual_bytes, bool do_remap)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 discarded_bytes = 0;
|
||||
|
|
@ -1399,7 +1399,8 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
|
|||
int i;
|
||||
|
||||
num_bytes = end - cur;
|
||||
stripes = btrfs_map_discard(fs_info, cur, &num_bytes, &num_stripes);
|
||||
stripes = btrfs_map_discard(fs_info, cur, &num_bytes, &num_stripes,
|
||||
do_remap);
|
||||
if (IS_ERR(stripes)) {
|
||||
ret = PTR_ERR(stripes);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
|
|
@ -2936,7 +2937,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
|
|||
|
||||
if (btrfs_test_opt(fs_info, DISCARD_SYNC))
|
||||
ret = btrfs_discard_extent(fs_info, start,
|
||||
end + 1 - start, NULL);
|
||||
end + 1 - start, NULL, true);
|
||||
|
||||
next_state = btrfs_next_extent_state(unpin, cached_state);
|
||||
btrfs_clear_extent_dirty(unpin, start, end, &cached_state);
|
||||
|
|
@ -2994,7 +2995,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
|
|||
ret = -EROFS;
|
||||
if (!TRANS_ABORTED(trans))
|
||||
ret = btrfs_discard_extent(fs_info, block_group->start,
|
||||
block_group->length, NULL);
|
||||
block_group->length, NULL, true);
|
||||
|
||||
/*
|
||||
* Not strictly necessary to lock, as the block_group should be
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
|
|||
struct extent_buffer *parent);
|
||||
void btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u64 end);
|
||||
int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
|
||||
u64 num_bytes, u64 *actual_bytes);
|
||||
u64 num_bytes, u64 *actual_bytes, bool do_remap);
|
||||
int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range);
|
||||
void btrfs_handle_fully_remapped_bgs(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_complete_bg_remapping(struct btrfs_block_group *bg);
|
||||
|
|
|
|||
|
|
@ -3677,7 +3677,7 @@ static int do_trimming(struct btrfs_block_group *block_group,
|
|||
}
|
||||
spin_unlock(&space_info->lock);
|
||||
|
||||
ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed);
|
||||
ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed, false);
|
||||
if (!ret) {
|
||||
*total_trimmed += trimmed;
|
||||
trim_state = BTRFS_TRIM_STATE_TRIMMED;
|
||||
|
|
|
|||
|
|
@ -3366,7 +3366,7 @@ out:
|
|||
btrfs_discard_extent(fs_info,
|
||||
ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes,
|
||||
NULL);
|
||||
NULL, true);
|
||||
btrfs_free_reserved_extent(fs_info,
|
||||
ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes, true);
|
||||
|
|
|
|||
|
|
@ -3419,7 +3419,7 @@ static int btrfs_relocate_chunk_finish(struct btrfs_fs_info *fs_info,
|
|||
* filesystem's point of view.
|
||||
*/
|
||||
if (btrfs_is_zoned(fs_info)) {
|
||||
ret = btrfs_discard_extent(fs_info, bg->start, length, NULL);
|
||||
ret = btrfs_discard_extent(fs_info, bg->start, length, NULL, true);
|
||||
if (ret)
|
||||
btrfs_info(fs_info, "failed to reset zone %llu after relocation",
|
||||
bg->start);
|
||||
|
|
@ -6101,7 +6101,7 @@ void btrfs_put_bioc(struct btrfs_io_context *bioc)
|
|||
*/
|
||||
struct btrfs_discard_stripe *btrfs_map_discard(struct btrfs_fs_info *fs_info,
|
||||
u64 logical, u64 *length_ret,
|
||||
u32 *num_stripes)
|
||||
u32 *num_stripes, bool do_remap)
|
||||
{
|
||||
struct btrfs_chunk_map *map;
|
||||
struct btrfs_discard_stripe *stripes;
|
||||
|
|
@ -6125,6 +6125,24 @@ struct btrfs_discard_stripe *btrfs_map_discard(struct btrfs_fs_info *fs_info,
|
|||
if (IS_ERR(map))
|
||||
return ERR_CAST(map);
|
||||
|
||||
if (do_remap && (map->type & BTRFS_BLOCK_GROUP_REMAPPED)) {
|
||||
u64 new_logical = logical;
|
||||
|
||||
ret = btrfs_translate_remap(fs_info, &new_logical, &length);
|
||||
if (ret)
|
||||
goto out_free_map;
|
||||
|
||||
if (new_logical != logical) {
|
||||
btrfs_free_chunk_map(map);
|
||||
|
||||
map = btrfs_get_chunk_map(fs_info, new_logical, length);
|
||||
if (IS_ERR(map))
|
||||
return ERR_CAST(map);
|
||||
|
||||
logical = new_logical;
|
||||
}
|
||||
}
|
||||
|
||||
/* we don't discard raid56 yet */
|
||||
if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
|
||||
ret = -EOPNOTSUPP;
|
||||
|
|
|
|||
|
|
@ -714,7 +714,7 @@ int btrfs_map_repair_block(struct btrfs_fs_info *fs_info,
|
|||
u32 length, int mirror_num);
|
||||
struct btrfs_discard_stripe *btrfs_map_discard(struct btrfs_fs_info *fs_info,
|
||||
u64 logical, u64 *length_ret,
|
||||
u32 *num_stripes);
|
||||
u32 *num_stripes, bool do_remap);
|
||||
int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
|
||||
struct btrfs_block_group *btrfs_create_chunk(struct btrfs_trans_handle *trans,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue