diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 120c448f58f8..3418bb62b996 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -396,6 +396,14 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | ||
400 | struct btrfs_root *root) | ||
401 | { | ||
402 | finish_current_insert(trans, root->fs_info->extent_root); | ||
403 | del_pending_extents(trans, root->fs_info->extent_root); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
399 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 407 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, |
400 | struct btrfs_root *root, u64 blocknr, | 408 | struct btrfs_root *root, u64 blocknr, |
401 | u64 num_blocks, u32 *refs) | 409 | u64 num_blocks, u32 *refs) |
@@ -1374,7 +1382,25 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1374 | BUG_ON(ret); | 1382 | BUG_ON(ret); |
1375 | continue; | 1383 | continue; |
1376 | } | 1384 | } |
1377 | next = read_tree_block(root, blocknr); | 1385 | next = btrfs_find_tree_block(root, blocknr); |
1386 | if (!next || !buffer_uptodate(next)) { | ||
1387 | brelse(next); | ||
1388 | mutex_unlock(&root->fs_info->fs_mutex); | ||
1389 | next = read_tree_block(root, blocknr); | ||
1390 | mutex_lock(&root->fs_info->fs_mutex); | ||
1391 | |||
1392 | /* we dropped the lock, check one more time */ | ||
1393 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | ||
1394 | BUG_ON(ret); | ||
1395 | if (refs != 1) { | ||
1396 | path->slots[*level]++; | ||
1397 | brelse(next); | ||
1398 | ret = btrfs_free_extent(trans, root, | ||
1399 | blocknr, 1, 1); | ||
1400 | BUG_ON(ret); | ||
1401 | continue; | ||
1402 | } | ||
1403 | } | ||
1378 | WARN_ON(*level <= 0); | 1404 | WARN_ON(*level <= 0); |
1379 | if (path->nodes[*level-1]) | 1405 | if (path->nodes[*level-1]) |
1380 | btrfs_block_release(root, path->nodes[*level-1]); | 1406 | btrfs_block_release(root, path->nodes[*level-1]); |