|
@@ -607,6 +607,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
|
|
|
cache->cached = BTRFS_CACHE_NO;
|
|
|
} else {
|
|
|
cache->cached = BTRFS_CACHE_STARTED;
|
|
|
+ cache->has_caching_ctl = 1;
|
|
|
}
|
|
|
}
|
|
|
spin_unlock(&cache->lock);
|
|
@@ -627,6 +628,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
|
|
|
cache->cached = BTRFS_CACHE_NO;
|
|
|
} else {
|
|
|
cache->cached = BTRFS_CACHE_STARTED;
|
|
|
+ cache->has_caching_ctl = 1;
|
|
|
}
|
|
|
spin_unlock(&cache->lock);
|
|
|
wake_up(&caching_ctl->wait);
|
|
@@ -9317,6 +9319,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
|
|
int ret;
|
|
|
int index;
|
|
|
int factor;
|
|
|
+ struct btrfs_caching_control *caching_ctl = NULL;
|
|
|
|
|
|
root = root->fs_info->extent_root;
|
|
|
|
|
@@ -9425,8 +9428,32 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
|
|
kobject_put(kobj);
|
|
|
}
|
|
|
|
|
|
+ if (block_group->has_caching_ctl)
|
|
|
+ caching_ctl = get_caching_control(block_group);
|
|
|
if (block_group->cached == BTRFS_CACHE_STARTED)
|
|
|
wait_block_group_cache_done(block_group);
|
|
|
+ if (block_group->has_caching_ctl) {
|
|
|
+ down_write(&root->fs_info->commit_root_sem);
|
|
|
+ if (!caching_ctl) {
|
|
|
+ struct btrfs_caching_control *ctl;
|
|
|
+
|
|
|
+ list_for_each_entry(ctl,
|
|
|
+ &root->fs_info->caching_block_groups, list)
|
|
|
+ if (ctl->block_group == block_group) {
|
|
|
+ caching_ctl = ctl;
|
|
|
+ atomic_inc(&caching_ctl->count);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (caching_ctl)
|
|
|
+ list_del_init(&caching_ctl->list);
|
|
|
+ up_write(&root->fs_info->commit_root_sem);
|
|
|
+ if (caching_ctl) {
|
|
|
+ /* Once for the caching bgs list and once for us. */
|
|
|
+ put_caching_control(caching_ctl);
|
|
|
+ put_caching_control(caching_ctl);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
btrfs_remove_free_space_cache(block_group);
|
|
|
|