Merge tag 'for-6.5-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[platform/kernel/linux-rpi.git] / fs / btrfs / block-group.c
index 2372615..030ab44 100644 (file)
@@ -499,12 +499,16 @@ static void fragment_free_space(struct btrfs_block_group *block_group)
  * used yet since their free space will be released as soon as the transaction
  * commits.
  */
-u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end)
+int add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end,
+                      u64 *total_added_ret)
 {
        struct btrfs_fs_info *info = block_group->fs_info;
-       u64 extent_start, extent_end, size, total_added = 0;
+       u64 extent_start, extent_end, size;
        int ret;
 
+       if (total_added_ret)
+               *total_added_ret = 0;
+
        while (start < end) {
                ret = find_first_extent_bit(&info->excluded_extents, start,
                                            &extent_start, &extent_end,
@@ -517,10 +521,12 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
                        start = extent_end + 1;
                } else if (extent_start > start && extent_start < end) {
                        size = extent_start - start;
-                       total_added += size;
                        ret = btrfs_add_free_space_async_trimmed(block_group,
                                                                 start, size);
-                       BUG_ON(ret); /* -ENOMEM or logic error */
+                       if (ret)
+                               return ret;
+                       if (total_added_ret)
+                               *total_added_ret += size;
                        start = extent_end + 1;
                } else {
                        break;
@@ -529,13 +535,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
 
        if (start < end) {
                size = end - start;
-               total_added += size;
                ret = btrfs_add_free_space_async_trimmed(block_group, start,
                                                         size);
-               BUG_ON(ret); /* -ENOMEM or logic error */
+               if (ret)
+                       return ret;
+               if (total_added_ret)
+                       *total_added_ret += size;
        }
 
-       return total_added;
+       return 0;
 }
 
 /*
@@ -779,8 +787,13 @@ next:
 
                if (key.type == BTRFS_EXTENT_ITEM_KEY ||
                    key.type == BTRFS_METADATA_ITEM_KEY) {
-                       total_found += add_new_free_space(block_group, last,
-                                                         key.objectid);
+                       u64 space_added;
+
+                       ret = add_new_free_space(block_group, last, key.objectid,
+                                                &space_added);
+                       if (ret)
+                               goto out;
+                       total_found += space_added;
                        if (key.type == BTRFS_METADATA_ITEM_KEY)
                                last = key.objectid +
                                        fs_info->nodesize;
@@ -795,11 +808,10 @@ next:
                }
                path->slots[0]++;
        }
-       ret = 0;
-
-       total_found += add_new_free_space(block_group, last,
-                               block_group->start + block_group->length);
 
+       ret = add_new_free_space(block_group, last,
+                                block_group->start + block_group->length,
+                                NULL);
 out:
        btrfs_free_path(path);
        return ret;
@@ -2294,9 +2306,11 @@ static int read_one_block_group(struct btrfs_fs_info *info,
                btrfs_free_excluded_extents(cache);
        } else if (cache->used == 0) {
                cache->cached = BTRFS_CACHE_FINISHED;
-               add_new_free_space(cache, cache->start,
-                                  cache->start + cache->length);
+               ret = add_new_free_space(cache, cache->start,
+                                        cache->start + cache->length, NULL);
                btrfs_free_excluded_extents(cache);
+               if (ret)
+                       goto error;
        }
 
        ret = btrfs_add_block_group_cache(info, cache);
@@ -2740,9 +2754,12 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
                return ERR_PTR(ret);
        }
 
-       add_new_free_space(cache, chunk_offset, chunk_offset + size);
-
+       ret = add_new_free_space(cache, chunk_offset, chunk_offset + size, NULL);
        btrfs_free_excluded_extents(cache);
+       if (ret) {
+               btrfs_put_block_group(cache);
+               return ERR_PTR(ret);
+       }
 
        /*
         * Ensure the corresponding space_info object is created and