Btrfs: cleanup orphaned root orphan item
authorJosef Bacik <jbacik@fusionio.com>
Thu, 27 Jun 2013 15:32:16 +0000 (11:32 -0400)
committerJosef Bacik <jbacik@fusionio.com>
Tue, 2 Jul 2013 15:50:52 +0000 (11:50 -0400)
I hit a weird problem were my root item had been deleted but the orphan item had
not.  This isn't necessarily a problem, but it keeps the file system from being
mounted.  To fix this we just need to axe the orphan item if we can't find the
fs root when we're putting them altogether.  With this patch I was able to
successfully mount my file system.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
fs/btrfs/root-tree.c

index 723a5312763f7b894e6f0ca87b0c24647946ef0d..ffb1036ef10db97f31bfa4c00ca7c36a45d09e4f 100644 (file)
@@ -228,6 +228,10 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
        struct btrfs_root *root;
        int err = 0;
        int ret;
+       bool can_recover = true;
+
+       if (tree_root->fs_info->sb->s_flags & MS_RDONLY)
+               can_recover = false;
 
        path = btrfs_alloc_path();
        if (!path)
@@ -268,9 +272,32 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
                key.offset++;
 
                root = btrfs_read_fs_root(tree_root, &root_key);
-               if (IS_ERR(root)) {
-                       err = PTR_ERR(root);
+               err = PTR_RET(root);
+               if (err && err != -ENOENT) {
                        break;
+               } else if (err == -ENOENT) {
+                       struct btrfs_trans_handle *trans;
+
+                       btrfs_release_path(path);
+
+                       trans = btrfs_join_transaction(tree_root);
+                       if (IS_ERR(trans)) {
+                               err = PTR_ERR(trans);
+                               btrfs_error(tree_root->fs_info, err,
+                                           "Failed to start trans to delete "
+                                           "orphan item");
+                               break;
+                       }
+                       err = btrfs_del_orphan_item(trans, tree_root,
+                                                   root_key.objectid);
+                       btrfs_end_transaction(trans, tree_root);
+                       if (err) {
+                               btrfs_error(tree_root->fs_info, err,
+                                           "Failed to delete root orphan "
+                                           "item");
+                               break;
+                       }
+                       continue;
                }
 
                if (btrfs_root_refs(&root->root_item) == 0) {