Skip to content

Commit

Permalink
Btrfs: do not do fast caching if we are allocating blocks for tree_root
Browse files Browse the repository at this point in the history
Since the fast caching uses normal tree locking, we can possibly deadlock if we
get to the caching via a btrfs_search_slot() on the tree_root.  So just check to
see if the root we are on is the tree root, and just don't do the fast caching.

Reported-by: Sage Weil <sage@newdream.net>
Signed-off-by: Josef Bacik <josef@redhat.com>
  • Loading branch information
Josef Bacik committed Dec 9, 2010
1 parent 2b20982 commit b8399de
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ static int caching_kthread(void *data)

static int cache_block_group(struct btrfs_block_group_cache *cache,
struct btrfs_trans_handle *trans,
struct btrfs_root *root,
int load_cache_only)
{
struct btrfs_fs_info *fs_info = cache->fs_info;
Expand All @@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,

/*
* We can't do the read from on-disk cache during a commit since we need
* to have the normal tree locking.
* to have the normal tree locking. Also if we are currently trying to
* allocate blocks for the tree root we can't do the fast caching since
* we likely hold important locks.
*/
if (!trans->transaction->in_commit) {
if (!trans->transaction->in_commit &&
(root && root != root->fs_info->tree_root)) {
spin_lock(&cache->lock);
if (cache->cached != BTRFS_CACHE_NO) {
spin_unlock(&cache->lock);
Expand Down Expand Up @@ -4083,7 +4087,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
* space back to the block group, otherwise we will leak space.
*/
if (!alloc && cache->cached == BTRFS_CACHE_NO)
cache_block_group(cache, trans, 1);
cache_block_group(cache, trans, NULL, 1);

byte_in_group = bytenr - cache->key.objectid;
WARN_ON(byte_in_group > cache->key.offset);
Expand Down Expand Up @@ -4937,7 +4941,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
u64 free_percent;

ret = cache_block_group(block_group, trans, 1);
ret = cache_block_group(block_group, trans,
orig_root, 1);
if (block_group->cached == BTRFS_CACHE_FINISHED)
goto have_block_group;

Expand All @@ -4961,7 +4966,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
if (loop > LOOP_CACHING_NOWAIT ||
(loop > LOOP_FIND_IDEAL &&
atomic_read(&space_info->caching_threads) < 2)) {
ret = cache_block_group(block_group, trans, 0);
ret = cache_block_group(block_group, trans,
orig_root, 0);
BUG_ON(ret);
}
found_uncached_bg = true;
Expand Down Expand Up @@ -5518,7 +5524,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
u64 num_bytes = ins->offset;

block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
cache_block_group(block_group, trans, 0);
cache_block_group(block_group, trans, NULL, 0);
caching_ctl = get_caching_control(block_group);

if (!caching_ctl) {
Expand Down

0 comments on commit b8399de

Please sign in to comment.