aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e990d2d1ba4a..1efeda3b2f6f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -440,7 +440,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
440 * allocate blocks for the tree root we can't do the fast caching since 440 * allocate blocks for the tree root we can't do the fast caching since
441 * we likely hold important locks. 441 * we likely hold important locks.
442 */ 442 */
443 if (!trans->transaction->in_commit && 443 if (trans && (!trans->transaction->in_commit) &&
444 (root && root != root->fs_info->tree_root)) { 444 (root && root != root->fs_info->tree_root)) {
445 spin_lock(&cache->lock); 445 spin_lock(&cache->lock);
446 if (cache->cached != BTRFS_CACHE_NO) { 446 if (cache->cached != BTRFS_CACHE_NO) {
@@ -8778,3 +8778,51 @@ int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
8778{ 8778{
8779 return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes); 8779 return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes);
8780} 8780}
8781
8782int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
8783{
8784 struct btrfs_fs_info *fs_info = root->fs_info;
8785 struct btrfs_block_group_cache *cache = NULL;
8786 u64 group_trimmed;
8787 u64 start;
8788 u64 end;
8789 u64 trimmed = 0;
8790 int ret = 0;
8791
8792 cache = btrfs_lookup_block_group(fs_info, range->start);
8793
8794 while (cache) {
8795 if (cache->key.objectid >= (range->start + range->len)) {
8796 btrfs_put_block_group(cache);
8797 break;
8798 }
8799
8800 start = max(range->start, cache->key.objectid);
8801 end = min(range->start + range->len,
8802 cache->key.objectid + cache->key.offset);
8803
8804 if (end - start >= range->minlen) {
8805 if (!block_group_cache_done(cache)) {
8806 ret = cache_block_group(cache, NULL, root, 0);
8807 if (!ret)
8808 wait_block_group_cache_done(cache);
8809 }
8810 ret = btrfs_trim_block_group(cache,
8811 &group_trimmed,
8812 start,
8813 end,
8814 range->minlen);
8815
8816 trimmed += group_trimmed;
8817 if (ret) {
8818 btrfs_put_block_group(cache);
8819 break;
8820 }
8821 }
8822
8823 cache = next_block_group(fs_info->tree_root, cache);
8824 }
8825
8826 range->len = trimmed;
8827 return ret;
8828}