btrfs: do proper error handling in merge_reloc_roots
authorJosef Bacik <josef@toxicpanda.com>
Fri, 12 Mar 2021 20:25:33 +0000 (15:25 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Apr 2021 15:25:22 +0000 (17:25 +0200)
We have a BUG_ON() if we get an error back from btrfs_get_fs_root().
This honestly should never fail, as at this point we have a solid
coordination of fs root to reloc root, and these roots will all be in
memory.  But in the name of killing BUG_ON()'s remove these and handle
the error condition properly, ASSERT()'ing for developers.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/relocation.c

index 3b9c9a001d0ddf30cc0617d3ef9a17e049ed9667..fb5125c8308cf0e9205ff053c0c9ca2f875f8a29 100644 (file)
@@ -1969,8 +1969,29 @@ again:
                root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
                                         false);
                if (btrfs_root_refs(&reloc_root->root_item) > 0) {
-                       BUG_ON(IS_ERR(root));
-                       BUG_ON(root->reloc_root != reloc_root);
+                       if (IS_ERR(root)) {
+                               /*
+                                * For recovery we read the fs roots on mount,
+                                * and if we didn't find the root then we marked
+                                * the reloc root as a garbage root.  For normal
+                                * relocation obviously the root should exist in
+                                * memory.  However there's no reason we can't
+                                * handle the error properly here just in case.
+                                */
+                               ASSERT(0);
+                               ret = PTR_ERR(root);
+                               goto out;
+                       }
+                       if (root->reloc_root != reloc_root) {
+                               /*
+                                * This is actually impossible without something
+                                * going really wrong (like weird race condition
+                                * or cosmic rays).
+                                */
+                               ASSERT(0);
+                               ret = -EINVAL;
+                               goto out;
+                       }
                        ret = merge_reloc_root(rc, root);
                        btrfs_put_root(root);
                        if (ret) {