@@ -900,6 +900,31 @@ static int remove_block_group_item(struct btrfs_trans_handle *trans,
return ret;
}
+static void unlink_block_group(struct btrfs_block_group *cache)
+{
+ struct btrfs_fs_info *fs_info = cache->fs_info;
+ struct kobject *kobj = NULL;
+ int index = btrfs_bg_flags_to_raid_index(cache->flags);
+
+ down_write(&cache->space_info->groups_sem);
+ /*
+ * we must use list_del_init so people can check to see if they
+ * are still on the list after taking the semaphore
+ */
+ list_del_init(&cache->list);
+ if (list_empty(&cache->space_info->block_groups[index])) {
+ kobj = cache->space_info->block_group_kobjs[index];
+ cache->space_info->block_group_kobjs[index] = NULL;
+ clear_avail_alloc_bits(fs_info, cache->flags);
+ }
+ up_write(&cache->space_info->groups_sem);
+ clear_incompat_bg_bits(fs_info, cache->flags);
+ if (kobj) {
+ kobject_del(kobj);
+ kobject_put(kobj);
+ }
+}
+
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
u64 group_start, struct extent_map *em)
{
@@ -910,9 +935,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_key key;
struct inode *inode;
- struct kobject *kobj = NULL;
int ret;
- int index;
int factor;
struct btrfs_caching_control *caching_ctl = NULL;
bool remove_em;
@@ -931,7 +954,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
btrfs_free_ref_tree_range(fs_info, block_group->start,
block_group->length);
- index = btrfs_bg_flags_to_raid_index(block_group->flags);
factor = btrfs_bg_type_to_factor(block_group->flags);
/* make sure this block group isn't part of an allocation cluster */
@@ -1027,23 +1049,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
/* Once for the block groups rbtree */
btrfs_put_block_group(block_group);
- down_write(&block_group->space_info->groups_sem);
- /*
- * we must use list_del_init so people can check to see if they
- * are still on the list after taking the semaphore
- */
- list_del_init(&block_group->list);
- if (list_empty(&block_group->space_info->block_groups[index])) {
- kobj = block_group->space_info->block_group_kobjs[index];
- block_group->space_info->block_group_kobjs[index] = NULL;
- clear_avail_alloc_bits(fs_info, block_group->flags);
- }
- up_write(&block_group->space_info->groups_sem);
- clear_incompat_bg_bits(fs_info, block_group->flags);
- if (kobj) {
- kobject_del(kobj);
- kobject_put(kobj);
- }
+ unlink_block_group(block_group);
if (block_group->has_caching_ctl)
caching_ctl = btrfs_get_caching_control(block_group);
@@ -3322,9 +3328,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
RB_CLEAR_NODE(&block_group->cache_node);
spin_unlock(&info->block_group_cache_lock);
- down_write(&block_group->space_info->groups_sem);
- list_del(&block_group->list);
- up_write(&block_group->space_info->groups_sem);
+ unlink_block_group(block_group);
/*
* We haven't cached this block group, which means we could
Introduce a new helper, unlink_block_group(), to unlink a block group from space info. The function will remove the block group from space info, and cleanup the kobject if that block group is the last one of the space info. There are two callers, btrfs_free_block_groups() and btrfs_remove_block_group() for now. Signed-off-by: Qu Wenruo <wqu@suse.com> --- fs/btrfs/block-group.c | 50 +++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 23 deletions(-)