summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2021-03-12 15:25:33 -0500
committerDavid Sterba <dsterba@suse.com>2021-04-19 17:25:22 +0200
commit24213fa46c7080c31d79aa2e3e2f0d9480cab700 (patch)
treec5b5630cc1646c40e1e963e6526af356ab562086
parent8717cf440db670ba87596d8f5f6660d2a94f4401 (diff)
downloadlinux-24213fa46c7080c31d79aa2e3e2f0d9480cab700.tar.gz
btrfs: do proper error handling in merge_reloc_roots
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>
-rw-r--r--fs/btrfs/relocation.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 3b9c9a001d0d..fb5125c8308c 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -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) {