From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: Nikolay Borisov <nborisov@suse.com>
Subject: [PATCH v3 4/5] btrfs: extent-tree: Kill the BUG_ON() in insert_inline_extent_backref()
Date: Sun, 9 Aug 2020 20:09:18 +0800 [thread overview]
Message-ID: <20200809120919.85271-5-wqu@suse.com> (raw)
In-Reply-To: <20200809120919.85271-1-wqu@suse.com>
[BUG]
With crafted image, btrfs can panic at insert_inline_extent_backref():
kernel BUG at fs/btrfs/extent-tree.c:1857!
invalid opcode: 0000 [#1] SMP PTI
CPU: 0 PID: 1117 Comm: btrfs-transacti Not tainted 5.0.0-rc8+ #9
RIP: 0010:insert_inline_extent_backref+0xcc/0xe0
Code: 45 20 49 8b 7e 50 49 89 d8 4c 8b 4d 10 48 8b 55 c8 4c 89 e1 41 57 4c 89 ee 50 ff 75 18 e8 cc bf ff ff 31 c0 48 83 c4 18 eb b2 <0f> 0b e8 9d df bd ff 0f 1f 00 66 2e 0f 1f 84 00 00 00 00 00 66 66
RSP: 0018:ffffac4dc1287be8 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 0000000000000007 RCX: 0000000000000001
RDX: 0000000000001000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffffac4dc1287c28 R08: ffffac4dc1287ab8 R09: ffffac4dc1287ac0
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: ffff8febef88a540 R14: ffff8febeaa7bc30 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff8febf7a00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f663ace94c0 CR3: 0000000235698006 CR4: 00000000000206f0
Call Trace:
? _cond_resched+0x1a/0x50
__btrfs_inc_extent_ref.isra.64+0x7e/0x240
? btrfs_merge_delayed_refs+0xa5/0x330
__btrfs_run_delayed_refs+0x653/0x1120
btrfs_run_delayed_refs+0xdb/0x1b0
btrfs_commit_transaction+0x52/0x950
? start_transaction+0x94/0x450
transaction_kthread+0x163/0x190
kthread+0x105/0x140
? btrfs_cleanup_transaction+0x560/0x560
? kthread_destroy_worker+0x50/0x50
ret_from_fork+0x35/0x40
Modules linked in:
---[ end trace 2ad8b3de903cf825 ]---
[CAUSE]
Due to extent tree corruption (still valid by itself, but bad cross ref),
we can allocate an extent which is still in extent tree.
The offending tree block of that case is from csum tree.
The newly allocated tree block is also for csum tree.
Then we will try to insert an tree block ref for the existing tree block
ref.
For btrfs tree extent item, a tree block can never be shared directly by
the same tree twice.
We have such BUG_ON() to prevent such problem, but BUG_ON() is
definitely not good enough.
[FIX]
Replace that BUG_ON() with proper error message and leaf dump for debug
build.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=202829
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/extent-tree.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 8e86e3524861..b664ad361bd8 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1177,7 +1177,22 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
num_bytes, parent, root_objectid,
owner, offset, 1);
if (ret == 0) {
- BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID);
+ /*
+ * We're adding refs to an tree block we already own, this
+ * should not happen at all.
+ */
+ if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+ btrfs_crit(trans->fs_info,
+"invalid operation, adding refs to an existing tree ref, bytenr=%llu num_bytes=%llu root_objectid=%llu",
+ bytenr, num_bytes, root_objectid);
+ if (IS_ENABLED(CONFIG_BTRFS_DEBUG)) {
+ WARN_ON(1);
+ btrfs_crit(trans->fs_info,
+ "path->slots[0]=%d path->nodes[0]:", path->slots[0]);
+ btrfs_print_leaf(path->nodes[0]);
+ }
+ return -EUCLEAN;
+ }
update_inline_extent_backref(path, iref, refs_to_add,
extent_op, NULL);
} else if (ret == -ENOENT) {
@@ -1397,6 +1412,9 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
/*
* __btrfs_inc_extent_ref - insert backreference for a given extent
*
+ * The work is opposite as __btrfs_free_extent().
+ * For more info about how it works or examples, refer to __btrfs_free_extent().
+ *
* @trans: Handle of transaction
*
* @node: The delayed ref node used to get the bytenr/length for
--
2.28.0
next prev parent reply other threads:[~2020-08-09 12:09 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-09 12:09 [PATCH v3 0/5] btrfs: Enhanced runtime defence against fuzzed images Qu Wenruo
2020-08-09 12:09 ` [PATCH v3 1/5] btrfs: extent_io: Do extra check for extent buffer read write functions Qu Wenruo
2020-08-11 18:42 ` Josef Bacik
2020-08-09 12:09 ` [PATCH v3 2/5] btrfs: extent-tree: Kill BUG_ON() in __btrfs_free_extent() and do better comment Qu Wenruo
2020-08-10 18:05 ` kernel test robot
2020-08-11 18:45 ` Josef Bacik
2020-08-09 12:09 ` [PATCH v3 3/5] btrfs: Detect unbalanced tree with empty leaf before crashing btree operations Qu Wenruo
2020-08-11 18:48 ` Josef Bacik
2020-08-11 23:04 ` Qu Wenruo
2020-08-12 0:23 ` Josef Bacik
2020-08-12 0:29 ` Qu Wenruo
2020-08-12 1:50 ` Josef Bacik
2020-08-12 1:53 ` Qu Wenruo
2020-09-09 7:08 ` [btrfs] 3b54a0a703: WARNING:at_fs/btrfs/inode.c:#btrfs_finish_ordered_io[btrfs] kernel test robot
2020-09-09 7:49 ` Qu Wenruo
2020-09-09 7:49 ` Qu Wenruo
2020-09-15 5:54 ` Oliver Sang
2020-09-15 5:54 ` Oliver Sang
2020-09-15 7:40 ` Qu Wenruo
2020-09-15 7:40 ` Qu Wenruo
2020-09-15 8:00 ` Qu Wenruo
2020-09-15 8:00 ` Qu Wenruo
2020-09-16 3:32 ` Oliver Sang
2020-09-16 4:20 ` Qu Wenruo
2020-09-16 4:20 ` Qu Wenruo
2020-09-16 6:31 ` Oliver Sang
2020-09-16 6:31 ` Oliver Sang
2020-08-09 12:09 ` Qu Wenruo [this message]
2020-08-11 18:50 ` [PATCH v3 4/5] btrfs: extent-tree: Kill the BUG_ON() in insert_inline_extent_backref() Josef Bacik
2020-08-09 12:09 ` [PATCH v3 5/5] btrfs: ctree: Checking key orders before merged tree blocks Qu Wenruo
2020-08-11 18:53 ` Josef Bacik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200809120919.85271-5-wqu@suse.com \
--to=wqu@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=nborisov@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.