Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux.git] / fs / btrfs / ctree.c
index 88d1b1eedc9cd3a9679758dc1d209e0bf88767aa..1bcfcdb23cf4c4b999e75bc0896466938aaaaeb7 100644 (file)
@@ -2769,9 +2769,13 @@ again:
                 * the commit roots are read only
                 * so we always do read locks
                 */
+               if (p->need_commit_sem)
+                       down_read(&root->fs_info->commit_root_sem);
                b = root->commit_root;
                extent_buffer_get(b);
                level = btrfs_header_level(b);
+               if (p->need_commit_sem)
+                       up_read(&root->fs_info->commit_root_sem);
                if (!p->skip_locking)
                        btrfs_tree_read_lock(b);
        } else {
@@ -5360,7 +5364,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
 {
        int ret;
        int cmp;
-       struct btrfs_trans_handle *trans = NULL;
        struct btrfs_path *left_path = NULL;
        struct btrfs_path *right_path = NULL;
        struct btrfs_key left_key;
@@ -5378,9 +5381,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
        u64 right_blockptr;
        u64 left_gen;
        u64 right_gen;
-       u64 left_start_ctransid;
-       u64 right_start_ctransid;
-       u64 ctransid;
 
        left_path = btrfs_alloc_path();
        if (!left_path) {
@@ -5404,21 +5404,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
        right_path->search_commit_root = 1;
        right_path->skip_locking = 1;
 
-       spin_lock(&left_root->root_item_lock);
-       left_start_ctransid = btrfs_root_ctransid(&left_root->root_item);
-       spin_unlock(&left_root->root_item_lock);
-
-       spin_lock(&right_root->root_item_lock);
-       right_start_ctransid = btrfs_root_ctransid(&right_root->root_item);
-       spin_unlock(&right_root->root_item_lock);
-
-       trans = btrfs_join_transaction(left_root);
-       if (IS_ERR(trans)) {
-               ret = PTR_ERR(trans);
-               trans = NULL;
-               goto out;
-       }
-
        /*
         * Strategy: Go to the first items of both trees. Then do
         *
@@ -5455,6 +5440,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
         *   the right if possible or go up and right.
         */
 
+       down_read(&left_root->fs_info->commit_root_sem);
        left_level = btrfs_header_level(left_root->commit_root);
        left_root_level = left_level;
        left_path->nodes[left_level] = left_root->commit_root;
@@ -5464,6 +5450,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
        right_root_level = right_level;
        right_path->nodes[right_level] = right_root->commit_root;
        extent_buffer_get(right_path->nodes[right_level]);
+       up_read(&left_root->fs_info->commit_root_sem);
 
        if (left_level == 0)
                btrfs_item_key_to_cpu(left_path->nodes[left_level],
@@ -5482,67 +5469,6 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
        advance_left = advance_right = 0;
 
        while (1) {
-               /*
-                * We need to make sure the transaction does not get committed
-                * while we do anything on commit roots. This means, we need to
-                * join and leave transactions for every item that we process.
-                */
-               if (trans && btrfs_should_end_transaction(trans, left_root)) {
-                       btrfs_release_path(left_path);
-                       btrfs_release_path(right_path);
-
-                       ret = btrfs_end_transaction(trans, left_root);
-                       trans = NULL;
-                       if (ret < 0)
-                               goto out;
-               }
-               /* now rejoin the transaction */
-               if (!trans) {
-                       trans = btrfs_join_transaction(left_root);
-                       if (IS_ERR(trans)) {
-                               ret = PTR_ERR(trans);
-                               trans = NULL;
-                               goto out;
-                       }
-
-                       spin_lock(&left_root->root_item_lock);
-                       ctransid = btrfs_root_ctransid(&left_root->root_item);
-                       spin_unlock(&left_root->root_item_lock);
-                       if (ctransid != left_start_ctransid)
-                               left_start_ctransid = 0;
-
-                       spin_lock(&right_root->root_item_lock);
-                       ctransid = btrfs_root_ctransid(&right_root->root_item);
-                       spin_unlock(&right_root->root_item_lock);
-                       if (ctransid != right_start_ctransid)
-                               right_start_ctransid = 0;
-
-                       if (!left_start_ctransid || !right_start_ctransid) {
-                               WARN(1, KERN_WARNING
-                                       "BTRFS: btrfs_compare_tree detected "
-                                       "a change in one of the trees while "
-                                       "iterating. This is probably a "
-                                       "bug.\n");
-                               ret = -EIO;
-                               goto out;
-                       }
-
-                       /*
-                        * the commit root may have changed, so start again
-                        * where we stopped
-                        */
-                       left_path->lowest_level = left_level;
-                       right_path->lowest_level = right_level;
-                       ret = btrfs_search_slot(NULL, left_root,
-                                       &left_key, left_path, 0, 0);
-                       if (ret < 0)
-                               goto out;
-                       ret = btrfs_search_slot(NULL, right_root,
-                                       &right_key, right_path, 0, 0);
-                       if (ret < 0)
-                               goto out;
-               }
-
                if (advance_left && !left_end_reached) {
                        ret = tree_advance(left_root, left_path, &left_level,
                                        left_root_level,
@@ -5672,14 +5598,6 @@ out:
        btrfs_free_path(left_path);
        btrfs_free_path(right_path);
        kfree(tmp_buf);
-
-       if (trans) {
-               if (!ret)
-                       ret = btrfs_end_transaction(trans, left_root);
-               else
-                       btrfs_end_transaction(trans, left_root);
-       }
-
        return ret;
 }