diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 67 |
1 files changed, 24 insertions, 43 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f79e477a378e..5faf057f6f37 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -757,12 +757,14 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
| 757 | } | 757 | } |
| 758 | 758 | ||
| 759 | static void add_pinned_bytes(struct btrfs_fs_info *fs_info, | 759 | static void add_pinned_bytes(struct btrfs_fs_info *fs_info, |
| 760 | struct btrfs_ref *ref) | 760 | struct btrfs_ref *ref, int sign) |
| 761 | { | 761 | { |
| 762 | struct btrfs_space_info *space_info; | 762 | struct btrfs_space_info *space_info; |
| 763 | s64 num_bytes = -ref->len; | 763 | s64 num_bytes; |
| 764 | u64 flags; | 764 | u64 flags; |
| 765 | 765 | ||
| 766 | ASSERT(sign == 1 || sign == -1); | ||
| 767 | num_bytes = sign * ref->len; | ||
| 766 | if (ref->type == BTRFS_REF_METADATA) { | 768 | if (ref->type == BTRFS_REF_METADATA) { |
| 767 | if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID) | 769 | if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID) |
| 768 | flags = BTRFS_BLOCK_GROUP_SYSTEM; | 770 | flags = BTRFS_BLOCK_GROUP_SYSTEM; |
| @@ -2063,7 +2065,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
| 2063 | btrfs_ref_tree_mod(fs_info, generic_ref); | 2065 | btrfs_ref_tree_mod(fs_info, generic_ref); |
| 2064 | 2066 | ||
| 2065 | if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0) | 2067 | if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0) |
| 2066 | add_pinned_bytes(fs_info, generic_ref); | 2068 | add_pinned_bytes(fs_info, generic_ref, -1); |
| 2067 | 2069 | ||
| 2068 | return ret; | 2070 | return ret; |
| 2069 | } | 2071 | } |
| @@ -3882,8 +3884,7 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) | |||
| 3882 | info->space_info_kobj, "%s", | 3884 | info->space_info_kobj, "%s", |
| 3883 | alloc_name(space_info->flags)); | 3885 | alloc_name(space_info->flags)); |
| 3884 | if (ret) { | 3886 | if (ret) { |
| 3885 | percpu_counter_destroy(&space_info->total_bytes_pinned); | 3887 | kobject_put(&space_info->kobj); |
| 3886 | kfree(space_info); | ||
| 3887 | return ret; | 3888 | return ret; |
| 3888 | } | 3889 | } |
| 3889 | 3890 | ||
| @@ -7190,7 +7191,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
| 7190 | } | 7191 | } |
| 7191 | out: | 7192 | out: |
| 7192 | if (pin) | 7193 | if (pin) |
| 7193 | add_pinned_bytes(fs_info, &generic_ref); | 7194 | add_pinned_bytes(fs_info, &generic_ref, 1); |
| 7194 | 7195 | ||
| 7195 | if (last_ref) { | 7196 | if (last_ref) { |
| 7196 | /* | 7197 | /* |
| @@ -7238,7 +7239,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref) | |||
| 7238 | btrfs_ref_tree_mod(fs_info, ref); | 7239 | btrfs_ref_tree_mod(fs_info, ref); |
| 7239 | 7240 | ||
| 7240 | if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0) | 7241 | if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0) |
| 7241 | add_pinned_bytes(fs_info, ref); | 7242 | add_pinned_bytes(fs_info, ref, 1); |
| 7242 | 7243 | ||
| 7243 | return ret; | 7244 | return ret; |
| 7244 | } | 7245 | } |
| @@ -10830,17 +10831,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 10830 | remove_em = (atomic_read(&block_group->trimming) == 0); | 10831 | remove_em = (atomic_read(&block_group->trimming) == 0); |
| 10831 | spin_unlock(&block_group->lock); | 10832 | spin_unlock(&block_group->lock); |
| 10832 | 10833 | ||
| 10833 | if (remove_em) { | ||
| 10834 | struct extent_map_tree *em_tree; | ||
| 10835 | |||
| 10836 | em_tree = &fs_info->mapping_tree.map_tree; | ||
| 10837 | write_lock(&em_tree->lock); | ||
| 10838 | remove_extent_mapping(em_tree, em); | ||
| 10839 | write_unlock(&em_tree->lock); | ||
| 10840 | /* once for the tree */ | ||
| 10841 | free_extent_map(em); | ||
| 10842 | } | ||
| 10843 | |||
| 10844 | mutex_unlock(&fs_info->chunk_mutex); | 10834 | mutex_unlock(&fs_info->chunk_mutex); |
| 10845 | 10835 | ||
| 10846 | ret = remove_block_group_free_space(trans, block_group); | 10836 | ret = remove_block_group_free_space(trans, block_group); |
| @@ -10857,6 +10847,19 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 10857 | goto out; | 10847 | goto out; |
| 10858 | 10848 | ||
| 10859 | ret = btrfs_del_item(trans, root, path); | 10849 | ret = btrfs_del_item(trans, root, path); |
| 10850 | if (ret) | ||
| 10851 | goto out; | ||
| 10852 | |||
| 10853 | if (remove_em) { | ||
| 10854 | struct extent_map_tree *em_tree; | ||
| 10855 | |||
| 10856 | em_tree = &fs_info->mapping_tree.map_tree; | ||
| 10857 | write_lock(&em_tree->lock); | ||
| 10858 | remove_extent_mapping(em_tree, em); | ||
| 10859 | write_unlock(&em_tree->lock); | ||
| 10860 | /* once for the tree */ | ||
| 10861 | free_extent_map(em); | ||
| 10862 | } | ||
| 10860 | out: | 10863 | out: |
| 10861 | if (remove_rsv) | 10864 | if (remove_rsv) |
| 10862 | btrfs_delayed_refs_rsv_release(fs_info, 1); | 10865 | btrfs_delayed_refs_rsv_release(fs_info, 1); |
| @@ -11136,13 +11139,11 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, | |||
| 11136 | * it while performing the free space search since we have already | 11139 | * it while performing the free space search since we have already |
| 11137 | * held back allocations. | 11140 | * held back allocations. |
| 11138 | */ | 11141 | */ |
| 11139 | static int btrfs_trim_free_extents(struct btrfs_device *device, | 11142 | static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed) |
| 11140 | struct fstrim_range *range, u64 *trimmed) | ||
| 11141 | { | 11143 | { |
| 11142 | u64 start, len = 0, end = 0; | 11144 | u64 start = SZ_1M, len = 0, end = 0; |
| 11143 | int ret; | 11145 | int ret; |
| 11144 | 11146 | ||
| 11145 | start = max_t(u64, range->start, SZ_1M); | ||
| 11146 | *trimmed = 0; | 11147 | *trimmed = 0; |
| 11147 | 11148 | ||
| 11148 | /* Discard not supported = nothing to do. */ | 11149 | /* Discard not supported = nothing to do. */ |
| @@ -11185,22 +11186,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, | |||
| 11185 | break; | 11186 | break; |
| 11186 | } | 11187 | } |
| 11187 | 11188 | ||
| 11188 | /* Keep going until we satisfy minlen or reach end of space */ | ||
| 11189 | if (len < range->minlen) { | ||
| 11190 | mutex_unlock(&fs_info->chunk_mutex); | ||
| 11191 | start += len; | ||
| 11192 | continue; | ||
| 11193 | } | ||
| 11194 | |||
| 11195 | /* If we are out of the passed range break */ | ||
| 11196 | if (start > range->start + range->len - 1) { | ||
| 11197 | mutex_unlock(&fs_info->chunk_mutex); | ||
| 11198 | break; | ||
| 11199 | } | ||
| 11200 | |||
| 11201 | start = max(range->start, start); | ||
| 11202 | len = min(range->len, len); | ||
| 11203 | |||
| 11204 | ret = btrfs_issue_discard(device->bdev, start, len, | 11189 | ret = btrfs_issue_discard(device->bdev, start, len, |
| 11205 | &bytes); | 11190 | &bytes); |
| 11206 | if (!ret) | 11191 | if (!ret) |
| @@ -11215,10 +11200,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, | |||
| 11215 | start += len; | 11200 | start += len; |
| 11216 | *trimmed += bytes; | 11201 | *trimmed += bytes; |
| 11217 | 11202 | ||
| 11218 | /* We've trimmed enough */ | ||
| 11219 | if (*trimmed >= range->len) | ||
| 11220 | break; | ||
| 11221 | |||
| 11222 | if (fatal_signal_pending(current)) { | 11203 | if (fatal_signal_pending(current)) { |
| 11223 | ret = -ERESTARTSYS; | 11204 | ret = -ERESTARTSYS; |
| 11224 | break; | 11205 | break; |
| @@ -11302,7 +11283,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) | |||
| 11302 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | 11283 | mutex_lock(&fs_info->fs_devices->device_list_mutex); |
| 11303 | devices = &fs_info->fs_devices->devices; | 11284 | devices = &fs_info->fs_devices->devices; |
| 11304 | list_for_each_entry(device, devices, dev_list) { | 11285 | list_for_each_entry(device, devices, dev_list) { |
| 11305 | ret = btrfs_trim_free_extents(device, range, &group_trimmed); | 11286 | ret = btrfs_trim_free_extents(device, &group_trimmed); |
| 11306 | if (ret) { | 11287 | if (ret) { |
| 11307 | dev_failed++; | 11288 | dev_failed++; |
| 11308 | dev_ret = ret; | 11289 | dev_ret = ret; |
