Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp1320951ybz; Thu, 16 Apr 2020 07:10:36 -0700 (PDT) X-Google-Smtp-Source: APiQypL3HP88DT72ewuUC0Lw1Pcp9ObSfOZIAccnyrMs51nxU0jg+nV0DqkAydHg3zlcf4p6QPKR X-Received: by 2002:a50:f383:: with SMTP id g3mr28519475edm.316.1587046236434; Thu, 16 Apr 2020 07:10:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587046236; cv=none; d=google.com; s=arc-20160816; b=eBhLe/+DOH+Lh7tjXjAS4AseDx+ypNzMPpukDmT/OBnmj9ws0pbLQLTwqg16XNq6q3 LkV8gSCIpIa6FKVtyf6+hhjjf4u+WJj4YZUWGxHkBUHLbWUxmV3xupJ1vCCl55AzOBtN tEpuAnhXg6YMkcDuOrMSg1yWTnpLlaa4bc1gcrwGFp2lCY8oCfh/ERfGjmy/QFmuVPAO sI6fZ34ch0hd+0ewiZ1b/jXXHGPohdDa2IGPq8WIuq5D4Mi3Lj6/pKMolAxOuUb8dBoU MY2+Rq/BFDw7uOSgMSbFaIxddd1AWGbjyJjBRTQ8qi9Fp3zw40CEwOGbstR7EGYQ0ZgT hCtQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ZUmksqqMrMcrUilu+qJGuLBEy5v4+nLM1vHby07CceM=; b=BQ8ffKaiSxXaja3hcxlbY1QtPXaVH7yiWI3iPTFw0btLtqI2b0UdfCJW1Y1I1vcoLq ACYHwqoDAypd9Fafljt6uYEz2vFoDK2or9bpUrCGyLxVykbsI/MFcVyCCLDNB87SaULu PSe268JPTPL2IloFJg6vdFX8JtJwXK36Q7G/sylXlooVpk/s85usEcXHPULk5BZoGQQe jSYhchUTiJ7Un1rfyrmdbcSQKIxP6488ueA4wXcef/3CWiXrwS66EyGmktm4E/ndJG8e QjlVGhR6RDw+UxgUmZd7yuB4qd3lPmLGUWF8CAxRx7RKsthATjDJ6kb3DTtxJtOx4XDV a17w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=rGnHBj+u; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 18si12060610ejy.287.2020.04.16.07.10.12; Thu, 16 Apr 2020 07:10:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=rGnHBj+u; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2409763AbgDPOHc (ORCPT + 99 others); Thu, 16 Apr 2020 10:07:32 -0400 Received: from mail.kernel.org ([198.145.29.99]:58382 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2898473AbgDPNpC (ORCPT ); Thu, 16 Apr 2020 09:45:02 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A7E7121974; Thu, 16 Apr 2020 13:45:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1587044701; bh=2V62Zra6D9QRV83/D655htfiCHJDrI7SCiDNjGcKN5s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rGnHBj+unkXOvBxOz+elxNxVUekWlduAnp6hpMqRbD719d9slwIKBO7Z0D7xbbZUO X6NDI2KSWwAmXxVdBwAqpWg0G7ae94e4KXTRuxvkO96g06S311oEerZSgD3UQuNagx prEd5fThW30tJ/yR5Y9THxp031URa96VgY1arx0s= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Qu Wenruo , Josef Bacik , David Sterba , Sasha Levin Subject: [PATCH 5.4 066/232] btrfs: remove a BUG_ON() from merge_reloc_roots() Date: Thu, 16 Apr 2020 15:22:40 +0200 Message-Id: <20200416131323.594224015@linuxfoundation.org> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200416131316.640996080@linuxfoundation.org> References: <20200416131316.640996080@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Josef Bacik [ Upstream commit 7b7b74315b24dc064bc1c683659061c3d48f8668 ] This was pretty subtle, we default to reloc roots having 0 root refs, so if we crash in the middle of the relocation they can just be deleted. If we successfully complete the relocation operations we'll set our root refs to 1 in prepare_to_merge() and then go on to merge_reloc_roots(). At prepare_to_merge() time if any of the reloc roots have a 0 reference still, we will remove that reloc root from our reloc root rb tree, and then clean it up later. However this only happens if we successfully start a transaction. If we've aborted previously we will skip this step completely, and only have reloc roots with a reference count of 0, but were never properly removed from the reloc control's rb tree. This isn't a problem per-se, our references are held by the list the reloc roots are on, and by the original root the reloc root belongs to. If we end up in this situation all the reloc roots will be added to the dirty_reloc_list, and then properly dropped at that point. The reloc control will be free'd and the rb tree is no longer used. There were two options when fixing this, one was to remove the BUG_ON(), the other was to make prepare_to_merge() handle the case where we couldn't start a trans handle. IMO this is the cleaner solution. I started with handling the error in prepare_to_merge(), but it turned out super ugly. And in the end this BUG_ON() simply doesn't matter, the cleanup was happening properly, we were just panicing because this BUG_ON() only matters in the success case. So I've opted to just remove it and add a comment where it was. Reviewed-by: Qu Wenruo Signed-off-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/relocation.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index bc1d7f144ace9..7ce48f1364f76 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2562,7 +2562,21 @@ out: free_reloc_roots(&reloc_roots); } - BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root)); + /* + * We used to have + * + * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root)); + * + * here, but it's wrong. If we fail to start the transaction in + * prepare_to_merge() we will have only 0 ref reloc roots, none of which + * have actually been removed from the reloc_root_tree rb tree. This is + * fine because we're bailing here, and we hold a reference on the root + * for the list that holds it, so these roots will be cleaned up when we + * do the reloc_dirty_list afterwards. Meanwhile the root->reloc_root + * will be cleaned up on unmount. + * + * The remaining nodes will be cleaned up by free_reloc_control. + */ } static void free_block_list(struct rb_root *blocks) -- 2.20.1