From 1c7bfa159fe796f0f6d310b02215d765f066b9c2 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 12 Mar 2021 15:24:57 -0500 Subject: [PATCH] btrfs: convert BUG_ON()'s in relocate_tree_block We have a couple of BUG_ON()'s in relocate_tree_block() that can be tripped if we have file system corruption. Convert these to ASSERT()'s so developers still get yelled at when they break the backref code, but error out nicely for users so the whole box doesn't go down. Reviewed-by: Qu Wenruo Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/relocation.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 4d9b6f9344d3..e5fbc2c00166 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2454,8 +2454,28 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans, if (root) { if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) { - BUG_ON(node->new_bytenr); - BUG_ON(!list_empty(&node->list)); + /* + * This block was the root block of a root, and this is + * the first time we're processing the block and thus it + * should not have had the ->new_bytenr modified and + * should have not been included on the changed list. + * + * However in the case of corruption we could have + * multiple refs pointing to the same block improperly, + * and thus we would trip over these checks. ASSERT() + * for the developer case, because it could indicate a + * bug in the backref code, however error out for a + * normal user in the case of corruption. + */ + ASSERT(node->new_bytenr == 0); + ASSERT(list_empty(&node->list)); + if (node->new_bytenr || !list_empty(&node->list)) { + btrfs_err(root->fs_info, + "bytenr %llu has improper references to it", + node->bytenr); + ret = -EUCLEAN; + goto out; + } btrfs_record_root_in_trans(trans, root); root = root->reloc_root; node->new_bytenr = root->node->start;