@@ -102,6 +102,15 @@ static int cache_block_group(struct btrfs_root *root,
if (block_group->cached)
return 0;
+ if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
+ btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE_VALID)) {
+ ret = load_free_space_tree(root->fs_info, block_group);
+ if (!ret) {
+ block_group->cached = 1;
+ return 0;
+ }
+ }
+
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
@@ -3594,9 +3603,11 @@ int exclude_super_stripes(struct btrfs_fs_info *fs_info,
u64 add_new_free_space(struct btrfs_block_group *block_group,
struct btrfs_fs_info *info, u64 start, u64 end)
{
+ struct extent_io_tree *free_space_cache;
u64 extent_start, extent_end, size, total_added = 0;
int ret;
+ free_space_cache = &info->free_space_cache;
while (start < end) {
ret = find_first_extent_bit(&info->pinned_extents, start,
&extent_start, &extent_end,
@@ -3609,6 +3620,8 @@ u64 add_new_free_space(struct btrfs_block_group *block_group,
} else if (extent_start > start && extent_start < end) {
size = extent_start - start;
total_added += size;
+ set_extent_dirty(free_space_cache, start,
+ start + size - 1);
ret = btrfs_add_free_space(block_group->free_space_ctl,
start, size);
BUG_ON(ret); /* -ENOMEM or logic error */
@@ -3621,6 +3634,7 @@ u64 add_new_free_space(struct btrfs_block_group *block_group,
if (start < end) {
size = end - start;
total_added += size;
+ set_extent_dirty(free_space_cache, start, start + size - 1);
ret = btrfs_add_free_space(block_group->free_space_ctl, start,
size);
BUG_ON(ret); /* -ENOMEM or logic error */
@@ -828,6 +828,9 @@ int btrfs_add_free_space(struct btrfs_free_space_ctl *ctl, u64 offset,
struct btrfs_free_space *info;
int ret = 0;
+ if (!ctl)
+ return 0;
+
info = calloc(1, sizeof(*info));
if (!info)
return -ENOMEM;
We currently always cache the block group based on the extent tree in progs. However with extent-tree-v2 we will not be able to do this, so we need to load the free space tree. However the free space tree is tied into the normal free space cache, which progs doesn't use for allocation, instead it uses an extent_io_tree. Handle this by setting the range dirty in our extent_io_tree. We still need to be able to load the free space tree into the normal free space cache stuff for fsck, so simply bail doing the normal free space cache adding if block_group->free_space_ctl is NULL, which will be the case unless we're checking it via check. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- kernel-shared/extent-tree.c | 14 ++++++++++++++ kernel-shared/free-space-cache.c | 3 +++ 2 files changed, 17 insertions(+)