Skip to content

Commit

Permalink
Btrfs: fix error handling in make/read block group
Browse files Browse the repository at this point in the history
I noticed that we will add a block group to the space info before we add it to
the block group cache rb tree, so we could potentially allocate from the block
group before it's able to be searched for.  I don't think this is too much of
a problem, the race window is microscopic, but just in case move the tree
insertion to above the space info linking.  This makes it easier to adjust the
error handling as well, so we can remove a couple of BUG_ON(ret)'s and have real
error handling setup for these scenarios.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
  • Loading branch information
Josef Bacik committed May 6, 2013
1 parent 5c2d867 commit 8c579fe
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -8175,20 +8175,33 @@ int btrfs_read_block_groups(struct btrfs_root *root)
free_excluded_extents(root, cache);
}

ret = btrfs_add_block_group_cache(root->fs_info, cache);
if (ret) {
btrfs_remove_free_space_cache(cache);
btrfs_put_block_group(cache);
goto error;
}

ret = update_space_info(info, cache->flags, found_key.offset,
btrfs_block_group_used(&cache->item),
&space_info);
BUG_ON(ret); /* -ENOMEM */
if (ret) {
btrfs_remove_free_space_cache(cache);
spin_lock(&info->block_group_cache_lock);
rb_erase(&cache->cache_node,
&info->block_group_cache_tree);
spin_unlock(&info->block_group_cache_lock);
btrfs_put_block_group(cache);
goto error;
}

cache->space_info = space_info;
spin_lock(&cache->space_info->lock);
cache->space_info->bytes_readonly += cache->bytes_super;
spin_unlock(&cache->space_info->lock);

__link_block_group(space_info, cache);

ret = btrfs_add_block_group_cache(root->fs_info, cache);
BUG_ON(ret); /* Logic error */

set_avail_alloc_bits(root->fs_info, cache->flags);
if (btrfs_chunk_readonly(root, cache->key.objectid))
set_block_group_ro(cache, 1);
Expand Down Expand Up @@ -8311,9 +8324,24 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,

free_excluded_extents(root, cache);

ret = btrfs_add_block_group_cache(root->fs_info, cache);
if (ret) {
btrfs_remove_free_space_cache(cache);
btrfs_put_block_group(cache);
return ret;
}

ret = update_space_info(root->fs_info, cache->flags, size, bytes_used,
&cache->space_info);
BUG_ON(ret); /* -ENOMEM */
if (ret) {
btrfs_remove_free_space_cache(cache);
spin_lock(&root->fs_info->block_group_cache_lock);
rb_erase(&cache->cache_node,
&root->fs_info->block_group_cache_tree);
spin_unlock(&root->fs_info->block_group_cache_lock);
btrfs_put_block_group(cache);
return ret;
}
update_global_block_rsv(root->fs_info);

spin_lock(&cache->space_info->lock);
Expand All @@ -8322,9 +8350,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,

__link_block_group(cache->space_info, cache);

ret = btrfs_add_block_group_cache(root->fs_info, cache);
BUG_ON(ret); /* Logic error */

list_add_tail(&cache->new_bg_list, &trans->new_bgs);

set_avail_alloc_bits(extent_root->fs_info, type);
Expand Down

0 comments on commit 8c579fe

Please sign in to comment.