}
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;
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)
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);
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
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);
}
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;
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);
* 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);
*/
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;
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;
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,