Btrfs: always clear a block group node when removing it from the tree
authorFilipe Manana <fdmanana@suse.com>
Thu, 4 Dec 2014 18:38:30 +0000 (18:38 +0000)
committerChris Mason <clm@fb.com>
Wed, 10 Dec 2014 20:22:29 +0000 (12:22 -0800)
Always clear a block group's rbnode after removing it from the rbtree to
ensure that any tasks that might be holding a reference on the block group
don't end up accessing stale rbnode left and right child pointers through
next_block_group().

This is a leftover from the change titled:
"Btrfs: fix invalid block group rbtree access after bg is removed"

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/extent-tree.c

index 222d6aea4a8a778cff8386873d8cb51ed5f86b16..974b3edf69c7336ee15bcdb49284d57a7186def8 100644 (file)
@@ -8872,6 +8872,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
                                       cache_node);
                rb_erase(&block_group->cache_node,
                         &info->block_group_cache_tree);
+               RB_CLEAR_NODE(&block_group->cache_node);
                spin_unlock(&info->block_group_cache_lock);
 
                down_write(&block_group->space_info->groups_sem);
@@ -9130,6 +9131,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                        spin_lock(&info->block_group_cache_lock);
                        rb_erase(&cache->cache_node,
                                 &info->block_group_cache_tree);
+                       RB_CLEAR_NODE(&cache->cache_node);
                        spin_unlock(&info->block_group_cache_lock);
                        btrfs_put_block_group(cache);
                        goto error;
@@ -9271,6 +9273,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
                spin_lock(&root->fs_info->block_group_cache_lock);
                rb_erase(&cache->cache_node,
                         &root->fs_info->block_group_cache_tree);
+               RB_CLEAR_NODE(&cache->cache_node);
                spin_unlock(&root->fs_info->block_group_cache_lock);
                btrfs_put_block_group(cache);
                return ret;