From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from prv3-mh.provo.novell.com ([137.65.250.26]:50812 "EHLO prv3-mh.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751736AbdKMHfQ (ORCPT ); Mon, 13 Nov 2017 02:35:16 -0500 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz, chris@colorremedies.com Subject: [PATCH 2/4] btrfs-progs: lowmem check: Fix function call stack overflow caused by wrong tree reloc tree detection Date: Mon, 13 Nov 2017 15:34:51 +0800 Message-Id: <20171113073453.29198-3-wqu@suse.com> In-Reply-To: <20171113073453.29198-1-wqu@suse.com> References: <20171113073453.29198-1-wqu@suse.com> Sender: linux-btrfs-owner@vger.kernel.org List-ID: For tree reloc tree root, its backref points to it self. So for such case, we should finish the lookup. Previous end condition is to ensure it's tree reloc tree *and* needs its root bytenr to match the bytenr passed in. However the @root passed in can be other tree, e.g. other tree reloc tree which shares the node/leaf. This makes any check based on @root passed in invalid. The patch removes the unreliable root objectid detection, and only use root->bytenr check. For the possibility of invalid self-pointing backref, extent tree checker should have already handled it, so we don't need to bother in fs tree checker. Fixes: 54c8f9152fd9 ("btrfs-progs: check: Fix lowmem mode stack overflow caused by fsck/023") Signed-off-by: Qu Wenruo --- cmds-check.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index b9943a0d3a0f..36e4a91b7e17 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -10251,15 +10251,10 @@ static int check_tree_block_ref(struct btrfs_root *root, u32 nodesize = root->fs_info->nodesize; u32 item_size; u64 offset; - int tree_reloc_root = 0; int found_ref = 0; int err = 0; int ret; - if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID && - btrfs_header_bytenr(root->node) == bytenr) - tree_reloc_root = 1; - btrfs_init_path(&path); key.objectid = bytenr; if (btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) @@ -10350,8 +10345,12 @@ static int check_tree_block_ref(struct btrfs_root *root, /* * Backref of tree reloc root points to itself, no need * to check backref any more. + * + * This may be an error of loop backref, but extent tree + * checker should have already handled it. + * Here we only need to avoid infinite iteration. */ - if (tree_reloc_root) + if (offset == bytenr) found_ref = 1; else /* Check if the backref points to valid referencer */ -- 2.15.0