Signed-off-by: Chris Mason <chris.mason@oracle.com>
                BUG_ON(ret);
                if (refs != 1)
                        continue;
+               mutex_unlock(&root->fs_info->fs_mutex);
                ret = readahead_tree_block(root, blocknr);
+               cond_resched();
+               mutex_lock(&root->fs_info->fs_mutex);
                if (ret)
                        break;
        }
        struct btrfs_path *path;
        int i;
        int orig_level;
-       int num_walks = 0;
        struct btrfs_root_item *root_item = &root->root_item;
 
        path = btrfs_alloc_path();
                        break;
                if (wret < 0)
                        ret = wret;
-               num_walks++;
-               if (num_walks > 2) {
-                       ret = -EAGAIN;
-                       get_bh(root->node);
-                       break;
-               }
+               ret = -EAGAIN;
+               get_bh(root->node);
+               break;
        }
        for (i = 0; i <= orig_level; i++) {
                if (path->nodes[i]) {
 
                                        break;
                        }
                        root->defrag_running = 0;
+                       radix_tree_tag_clear(&info->fs_roots_radix,
+                                    (unsigned long)root->root_key.objectid,
+                                    BTRFS_ROOT_DEFRAG_TAG);
                }
        }
        btrfs_end_transaction(trans, tree_root);
 
        int level;
        int orig_level;
        int i;
-       int num_runs = 0;
 
        if (root->ref_cows == 0) {
                goto out;
                        break;
                if (wret < 0)
                        ret = wret;
-               if (num_runs++ > 8) {
-                       ret = -EAGAIN;
-                       break;
-               }
+               ret = -EAGAIN;
+               break;
        }
        for (i = 0; i <= orig_level; i++) {
                if (path->nodes[i]) {