From patchwork Fri Oct 30 15:28:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1391127 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CN5nY3vJJz9sSG; Sat, 31 Oct 2020 02:29:05 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kYWKn-00076y-Sq; Fri, 30 Oct 2020 15:28:57 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kYWKK-0006sP-Ia for kernel-team@lists.ubuntu.com; Fri, 30 Oct 2020 15:28:28 +0000 Received: from mail-qt1-f199.google.com ([209.85.160.199]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kYWKI-0003RG-RA for kernel-team@lists.ubuntu.com; Fri, 30 Oct 2020 15:28:26 +0000 Received: by mail-qt1-f199.google.com with SMTP id e8so4153086qtp.18 for ; Fri, 30 Oct 2020 08:28:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MzXtH5jvfH4Vkklf7Cbg/WzDTll+jTt8X6Yb7ds0XZE=; b=Yc4KM1ZFVOaWlBMNFqk2KF2Z17O6wlZoCMt9L8b/YcyGLVe1k+nR4irAdLUdE4O81c ChnzzWnTTUzNwPEZv3wla96AsDP+ErgglqkMoT0UTOEOw53mmzw/zXMYzUmYJ09qNsuL hIOpoSZgrOoN5HVVUoHjzzxmqc3LxcwowozOpgJDyu8/Cawi9ckv1fXN/KzAo3lktWWT /U0ti5MUGtSn1y1otoUTLeq3CYYWlqg+g65rGkukE3fzpLW3b1HmUBvfswKDKjE7yeHF f+qZwaS6z12/+wlti9V/ahiPGXkTuMGGiof7cptv6wlloAfexZoaC16YdSObyPc76cSY vpdg== X-Gm-Message-State: AOAM531Nsxjd1bU2szuBVzWi8h8T6yiJIM7GjQGge+LNEgxUyLhgREhu Kpxs+/7QRYwkR/rBY0OpYrr+se6y9D/sGqpA1j51uznO0gJ37nc2NAoZoBqh1xVt09pN0N6KFzY vATGJAMLUkPoLAP1UfZDWYc2ajaGRFVpj6iMO9wIxCQ== X-Received: by 2002:ac8:43c5:: with SMTP id w5mr2709055qtn.374.1604071705570; Fri, 30 Oct 2020 08:28:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwE4c6XD4FSwBTLrMRZos0jiULV/x9eB3irk2vqCH0ePfApnrgCR1OQ9NlzG5az6QsRGrstnQ== X-Received: by 2002:ac8:43c5:: with SMTP id w5mr2709030qtn.374.1604071705341; Fri, 30 Oct 2020 08:28:25 -0700 (PDT) Received: from localhost.localdomain ([201.82.49.101]) by smtp.gmail.com with ESMTPSA id a30sm2779515qtn.55.2020.10.30.08.28.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Oct 2020 08:28:24 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [F][G][PATCH 6/7] btrfs: extent-tree: kill the BUG_ON() in insert_inline_extent_backref() Date: Fri, 30 Oct 2020 12:28:01 -0300 Message-Id: <20201030152803.66033-11-mfo@canonical.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201030152803.66033-1-mfo@canonical.com> References: <20201030152803.66033-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Qu Wenruo BugLink: https://bugs.launchpad.net/bugs/1902254 [BUG] With a 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 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 a tree block ref for the existing tree block ref. For a tree extent item, tree block can never be shared directly by the same tree twice. We have such BUG_ON() to prevent such problem, but this is not a proper error handling. [FIX] Replace that BUG_ON() with proper error message and leaf dump for debug build. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202829 Reviewed-by: Nikolay Borisov Reviewed-by: Josef Bacik Signed-off-by: Qu Wenruo Signed-off-by: David Sterba (cherry picked from commit 07cce5cf3b489419aa8e87f48a55f4e190a30876) Signed-off-by: Mauricio Faria de Oliveira --- 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 faa029d58be3..46b588c2d2e9 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1180,7 +1180,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 a tree block we already own, this + * should not happen at all. + */ + if (owner < BTRFS_FIRST_FREE_OBJECTID) { + btrfs_crit(trans->fs_info, +"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) { @@ -1418,6 +1433,9 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, /* * __btrfs_inc_extent_ref - insert backreference for a given extent * + * The counterpart is in __btrfs_free_extent(), with examples and more details + * how it works. + * * @trans: Handle of transaction * * @node: The delayed ref node used to get the bytenr/length for