aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-02 12:40:42 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:54:32 -0400
commit8c579fe745d96d0841c28295c10ac3e427cef9f2 (patch)
treea857b4aee9d38f88fcf54ef38859771333ed3bb3 /fs/btrfs/extent-tree.c
parent5c2d867fdcbc11a6862379ebd60b2c1a66e13671 (diff)
Btrfs: fix error handling in make/read block group
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>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 171f8d676d9c..cba98c1bcc0c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -8175,10 +8175,26 @@ int btrfs_read_block_groups(struct btrfs_root *root)
8175 free_excluded_extents(root, cache); 8175 free_excluded_extents(root, cache);
8176 } 8176 }
8177 8177
8178 ret = btrfs_add_block_group_cache(root->fs_info, cache);
8179 if (ret) {
8180 btrfs_remove_free_space_cache(cache);
8181 btrfs_put_block_group(cache);
8182 goto error;
8183 }
8184
8178 ret = update_space_info(info, cache->flags, found_key.offset, 8185 ret = update_space_info(info, cache->flags, found_key.offset,
8179 btrfs_block_group_used(&cache->item), 8186 btrfs_block_group_used(&cache->item),
8180 &space_info); 8187 &space_info);
8181 BUG_ON(ret); /* -ENOMEM */ 8188 if (ret) {
8189 btrfs_remove_free_space_cache(cache);
8190 spin_lock(&info->block_group_cache_lock);
8191 rb_erase(&cache->cache_node,
8192 &info->block_group_cache_tree);
8193 spin_unlock(&info->block_group_cache_lock);
8194 btrfs_put_block_group(cache);
8195 goto error;
8196 }
8197
8182 cache->space_info = space_info; 8198 cache->space_info = space_info;
8183 spin_lock(&cache->space_info->lock); 8199 spin_lock(&cache->space_info->lock);
8184 cache->space_info->bytes_readonly += cache->bytes_super; 8200 cache->space_info->bytes_readonly += cache->bytes_super;
@@ -8186,9 +8202,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
8186 8202
8187 __link_block_group(space_info, cache); 8203 __link_block_group(space_info, cache);
8188 8204
8189 ret = btrfs_add_block_group_cache(root->fs_info, cache);
8190 BUG_ON(ret); /* Logic error */
8191
8192 set_avail_alloc_bits(root->fs_info, cache->flags); 8205 set_avail_alloc_bits(root->fs_info, cache->flags);
8193 if (btrfs_chunk_readonly(root, cache->key.objectid)) 8206 if (btrfs_chunk_readonly(root, cache->key.objectid))
8194 set_block_group_ro(cache, 1); 8207 set_block_group_ro(cache, 1);
@@ -8311,9 +8324,24 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
8311 8324
8312 free_excluded_extents(root, cache); 8325 free_excluded_extents(root, cache);
8313 8326
8327 ret = btrfs_add_block_group_cache(root->fs_info, cache);
8328 if (ret) {
8329 btrfs_remove_free_space_cache(cache);
8330 btrfs_put_block_group(cache);
8331 return ret;
8332 }
8333
8314 ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, 8334 ret = update_space_info(root->fs_info, cache->flags, size, bytes_used,
8315 &cache->space_info); 8335 &cache->space_info);
8316 BUG_ON(ret); /* -ENOMEM */ 8336 if (ret) {
8337 btrfs_remove_free_space_cache(cache);
8338 spin_lock(&root->fs_info->block_group_cache_lock);
8339 rb_erase(&cache->cache_node,
8340 &root->fs_info->block_group_cache_tree);
8341 spin_unlock(&root->fs_info->block_group_cache_lock);
8342 btrfs_put_block_group(cache);
8343 return ret;
8344 }
8317 update_global_block_rsv(root->fs_info); 8345 update_global_block_rsv(root->fs_info);
8318 8346
8319 spin_lock(&cache->space_info->lock); 8347 spin_lock(&cache->space_info->lock);
@@ -8322,9 +8350,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
8322 8350
8323 __link_block_group(cache->space_info, cache); 8351 __link_block_group(cache->space_info, cache);
8324 8352
8325 ret = btrfs_add_block_group_cache(root->fs_info, cache);
8326 BUG_ON(ret); /* Logic error */
8327
8328 list_add_tail(&cache->new_bg_list, &trans->new_bgs); 8353 list_add_tail(&cache->new_bg_list, &trans->new_bgs);
8329 8354
8330 set_avail_alloc_bits(extent_root->fs_info, type); 8355 set_avail_alloc_bits(extent_root->fs_info, type);