btrfs: handle extent corruption with select_one_root properly
[linux-2.6-microblaze.git] / fs / btrfs / relocation.c
index 01c3937..3b9c9a0 100644 (file)
@@ -2218,7 +2218,13 @@ struct btrfs_root *select_one_root(struct btrfs_backref_node *node)
                cond_resched();
                next = walk_up_backref(next, edges, &index);
                root = next->root;
-               BUG_ON(!root);
+
+               /*
+                * This can occur if we have incomplete extent refs leading all
+                * the way up a particular path, in this case return -EUCLEAN.
+                */
+               if (!root)
+                       return ERR_PTR(-EUCLEAN);
 
                /* No other choice for non-shareable tree */
                if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
@@ -2608,8 +2614,15 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
 
        BUG_ON(node->processed);
        root = select_one_root(node);
-       if (root == ERR_PTR(-ENOENT)) {
-               update_processed_blocks(rc, node);
+       if (IS_ERR(root)) {
+               ret = PTR_ERR(root);
+
+               /* See explanation in select_one_root for the -EUCLEAN case. */
+               ASSERT(ret == -ENOENT);
+               if (ret == -ENOENT) {
+                       ret = 0;
+                       update_processed_blocks(rc, node);
+               }
                goto out;
        }