[PATCH] btrfs: replace BUG_ON() with error return in get_new_location()
From: Teng Liu
Date: Sat Apr 25 2026 - 02:12:29 EST
In get_new_location(), BUG_ON() crashes the kernel if the looked up
file extent item has any of offset, compression, encryption, or other
encoding set. While entries created by the relocation code itself are
not expected to have these fields set, the values come from on-disk
data and a malformed file system can reach this code with non-zero
values, panicking the kernel during a balance operation.
Replace the BUG_ON() with a return of -EUCLEAN, the established error
code in fs/btrfs/relocation.c for filesystem corruption. The caller in
replace_file_extents() already handles errors from get_new_location()
by breaking out of the loop without aborting the transaction so no
caller changes are needed.
Reported-by: syzbot+3e20d8f3d41bac5dc9a2@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=3e20d8f3d41bac5dc9a2
Signed-off-by: Teng Liu <27rabbitlt@xxxxxxxxx>
---
fs/btrfs/relocation.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 1c42c5180bdd..ce751c35945f 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -835,10 +835,11 @@ static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr,
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
- BUG_ON(btrfs_file_extent_offset(leaf, fi) ||
- btrfs_file_extent_compression(leaf, fi) ||
- btrfs_file_extent_encryption(leaf, fi) ||
- btrfs_file_extent_other_encoding(leaf, fi));
+ if (unlikely(btrfs_file_extent_offset(leaf, fi) ||
+ btrfs_file_extent_compression(leaf, fi) ||
+ btrfs_file_extent_encryption(leaf, fi) ||
+ btrfs_file_extent_other_encoding(leaf, fi)))
+ return -EUCLEAN;
if (num_bytes != btrfs_file_extent_disk_num_bytes(leaf, fi))
return -EINVAL;
--
2.54.0