summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2024-10-03 11:43:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-02-17 11:35:54 +0100
commitf1e49780e72c72829cc76fc06eabeeaaa4f731a3 (patch)
tree03f9bb0d60734c39c6c09b35d0cdf248fe38df39 /fs/btrfs
parent5fdd8f98c78b12a9a1e1f32362f31f2a67a1fe33 (diff)
downloadlinux-f1e49780e72c72829cc76fc06eabeeaaa4f731a3.tar.gz
linux-f1e49780e72c72829cc76fc06eabeeaaa4f731a3.tar.bz2
linux-f1e49780e72c72829cc76fc06eabeeaaa4f731a3.zip
btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling
[ Upstream commit 6a4730b325aaa48f7a5d5ba97aff0a955e2d9cec ] This BUG_ON is meant to catch backref cache problems, but these can arise from either bugs in the backref cache or corruption in the extent tree. Fix it to be a proper error. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/relocation.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index db8b42f674b7..ab2de2d1b2be 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4405,8 +4405,18 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
WARN_ON(!first_cow && level == 0);
node = rc->backref_cache.path[level];
- BUG_ON(node->bytenr != buf->start &&
- node->new_bytenr != buf->start);
+
+ /*
+ * If node->bytenr != buf->start and node->new_bytenr !=
+ * buf->start then we've got the wrong backref node for what we
+ * expected to see here and the cache is incorrect.
+ */
+ if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) {
+ btrfs_err(fs_info,
+"bytenr %llu was found but our backref cache was expecting %llu or %llu",
+ buf->start, node->bytenr, node->new_bytenr);
+ return -EUCLEAN;
+ }
btrfs_backref_drop_node_buffer(node);
atomic_inc(&cow->refs);