aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c94
1 files changed, 6 insertions, 88 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 88d1b1eedc9c..1bcfcdb23cf4 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2769,9 +2769,13 @@ again:
2769 * the commit roots are read only 2769 * the commit roots are read only
2770 * so we always do read locks 2770 * so we always do read locks
2771 */ 2771 */
2772 if (p->need_commit_sem)
2773 down_read(&root->fs_info->commit_root_sem);
2772 b = root->commit_root; 2774 b = root->commit_root;
2773 extent_buffer_get(b); 2775 extent_buffer_get(b);
2774 level = btrfs_header_level(b); 2776 level = btrfs_header_level(b);
2777 if (p->need_commit_sem)
2778 up_read(&root->fs_info->commit_root_sem);
2775 if (!p->skip_locking) 2779 if (!p->skip_locking)
2776 btrfs_tree_read_lock(b); 2780 btrfs_tree_read_lock(b);
2777 } else { 2781 } else {
@@ -5360,7 +5364,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5360{ 5364{
5361 int ret; 5365 int ret;
5362 int cmp; 5366 int cmp;
5363 struct btrfs_trans_handle *trans = NULL;
5364 struct btrfs_path *left_path = NULL; 5367 struct btrfs_path *left_path = NULL;
5365 struct btrfs_path *right_path = NULL; 5368 struct btrfs_path *right_path = NULL;
5366 struct btrfs_key left_key; 5369 struct btrfs_key left_key;
@@ -5378,9 +5381,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5378 u64 right_blockptr; 5381 u64 right_blockptr;
5379 u64 left_gen; 5382 u64 left_gen;
5380 u64 right_gen; 5383 u64 right_gen;
5381 u64 left_start_ctransid;
5382 u64 right_start_ctransid;
5383 u64 ctransid;
5384 5384
5385 left_path = btrfs_alloc_path(); 5385 left_path = btrfs_alloc_path();
5386 if (!left_path) { 5386 if (!left_path) {
@@ -5404,21 +5404,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5404 right_path->search_commit_root = 1; 5404 right_path->search_commit_root = 1;
5405 right_path->skip_locking = 1; 5405 right_path->skip_locking = 1;
5406 5406
5407 spin_lock(&left_root->root_item_lock);
5408 left_start_ctransid = btrfs_root_ctransid(&left_root->root_item);
5409 spin_unlock(&left_root->root_item_lock);
5410
5411 spin_lock(&right_root->root_item_lock);
5412 right_start_ctransid = btrfs_root_ctransid(&right_root->root_item);
5413 spin_unlock(&right_root->root_item_lock);
5414
5415 trans = btrfs_join_transaction(left_root);
5416 if (IS_ERR(trans)) {
5417 ret = PTR_ERR(trans);
5418 trans = NULL;
5419 goto out;
5420 }
5421
5422 /* 5407 /*
5423 * Strategy: Go to the first items of both trees. Then do 5408 * Strategy: Go to the first items of both trees. Then do
5424 * 5409 *
@@ -5455,6 +5440,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5455 * the right if possible or go up and right. 5440 * the right if possible or go up and right.
5456 */ 5441 */
5457 5442
5443 down_read(&left_root->fs_info->commit_root_sem);
5458 left_level = btrfs_header_level(left_root->commit_root); 5444 left_level = btrfs_header_level(left_root->commit_root);
5459 left_root_level = left_level; 5445 left_root_level = left_level;
5460 left_path->nodes[left_level] = left_root->commit_root; 5446 left_path->nodes[left_level] = left_root->commit_root;
@@ -5464,6 +5450,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5464 right_root_level = right_level; 5450 right_root_level = right_level;
5465 right_path->nodes[right_level] = right_root->commit_root; 5451 right_path->nodes[right_level] = right_root->commit_root;
5466 extent_buffer_get(right_path->nodes[right_level]); 5452 extent_buffer_get(right_path->nodes[right_level]);
5453 up_read(&left_root->fs_info->commit_root_sem);
5467 5454
5468 if (left_level == 0) 5455 if (left_level == 0)
5469 btrfs_item_key_to_cpu(left_path->nodes[left_level], 5456 btrfs_item_key_to_cpu(left_path->nodes[left_level],
@@ -5482,67 +5469,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5482 advance_left = advance_right = 0; 5469 advance_left = advance_right = 0;
5483 5470
5484 while (1) { 5471 while (1) {
5485 /*
5486 * We need to make sure the transaction does not get committed
5487 * while we do anything on commit roots. This means, we need to
5488 * join and leave transactions for every item that we process.
5489 */
5490 if (trans && btrfs_should_end_transaction(trans, left_root)) {
5491 btrfs_release_path(left_path);
5492 btrfs_release_path(right_path);
5493
5494 ret = btrfs_end_transaction(trans, left_root);
5495 trans = NULL;
5496 if (ret < 0)
5497 goto out;
5498 }
5499 /* now rejoin the transaction */
5500 if (!trans) {
5501 trans = btrfs_join_transaction(left_root);
5502 if (IS_ERR(trans)) {
5503 ret = PTR_ERR(trans);
5504 trans = NULL;
5505 goto out;
5506 }
5507
5508 spin_lock(&left_root->root_item_lock);
5509 ctransid = btrfs_root_ctransid(&left_root->root_item);
5510 spin_unlock(&left_root->root_item_lock);
5511 if (ctransid != left_start_ctransid)
5512 left_start_ctransid = 0;
5513
5514 spin_lock(&right_root->root_item_lock);
5515 ctransid = btrfs_root_ctransid(&right_root->root_item);
5516 spin_unlock(&right_root->root_item_lock);
5517 if (ctransid != right_start_ctransid)
5518 right_start_ctransid = 0;
5519
5520 if (!left_start_ctransid || !right_start_ctransid) {
5521 WARN(1, KERN_WARNING
5522 "BTRFS: btrfs_compare_tree detected "
5523 "a change in one of the trees while "
5524 "iterating. This is probably a "
5525 "bug.\n");
5526 ret = -EIO;
5527 goto out;
5528 }
5529
5530 /*
5531 * the commit root may have changed, so start again
5532 * where we stopped
5533 */
5534 left_path->lowest_level = left_level;
5535 right_path->lowest_level = right_level;
5536 ret = btrfs_search_slot(NULL, left_root,
5537 &left_key, left_path, 0, 0);
5538 if (ret < 0)
5539 goto out;
5540 ret = btrfs_search_slot(NULL, right_root,
5541 &right_key, right_path, 0, 0);
5542 if (ret < 0)
5543 goto out;
5544 }
5545
5546 if (advance_left && !left_end_reached) { 5472 if (advance_left && !left_end_reached) {
5547 ret = tree_advance(left_root, left_path, &left_level, 5473 ret = tree_advance(left_root, left_path, &left_level,
5548 left_root_level, 5474 left_root_level,
@@ -5672,14 +5598,6 @@ out:
5672 btrfs_free_path(left_path); 5598 btrfs_free_path(left_path);
5673 btrfs_free_path(right_path); 5599 btrfs_free_path(right_path);
5674 kfree(tmp_buf); 5600 kfree(tmp_buf);
5675
5676 if (trans) {
5677 if (!ret)
5678 ret = btrfs_end_transaction(trans, left_root);
5679 else
5680 btrfs_end_transaction(trans, left_root);
5681 }
5682
5683 return ret; 5601 return ret;
5684} 5602}
5685 5603