|
@@ -272,6 +272,23 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
|
|
root_key.objectid = key.offset;
|
|
|
key.offset++;
|
|
|
|
|
|
+ /*
|
|
|
+ * The root might have been inserted already, as before we look
|
|
|
+ * for orphan roots, log replay might have happened, which
|
|
|
+ * triggers a transaction commit and qgroup accounting, which
|
|
|
+ * in turn reads and inserts fs roots while doing backref
|
|
|
+ * walking.
|
|
|
+ */
|
|
|
+ root = btrfs_lookup_fs_root(tree_root->fs_info,
|
|
|
+ root_key.objectid);
|
|
|
+ if (root) {
|
|
|
+ WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
|
|
|
+ &root->state));
|
|
|
+ if (btrfs_root_refs(&root->root_item) == 0)
|
|
|
+ btrfs_add_dead_root(root);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
root = btrfs_read_fs_root(tree_root, &root_key);
|
|
|
err = PTR_ERR_OR_ZERO(root);
|
|
|
if (err && err != -ENOENT) {
|
|
@@ -310,16 +327,8 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
|
|
set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
|
|
|
|
|
|
err = btrfs_insert_fs_root(root->fs_info, root);
|
|
|
- /*
|
|
|
- * The root might have been inserted already, as before we look
|
|
|
- * for orphan roots, log replay might have happened, which
|
|
|
- * triggers a transaction commit and qgroup accounting, which
|
|
|
- * in turn reads and inserts fs roots while doing backref
|
|
|
- * walking.
|
|
|
- */
|
|
|
- if (err == -EEXIST)
|
|
|
- err = 0;
|
|
|
if (err) {
|
|
|
+ BUG_ON(err == -EEXIST);
|
|
|
btrfs_free_fs_root(root);
|
|
|
break;
|
|
|
}
|