Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp1148112imm; Wed, 1 Aug 2018 10:59:58 -0700 (PDT) X-Google-Smtp-Source: AAOMgpejC+V+8dxik42xz2ZPqI9/3mcOsfIhpVk6SDDaMpxwf4W7CsxJePLXdEuYmDESK+PbGY1U X-Received: by 2002:a63:d002:: with SMTP id z2-v6mr6734888pgf.262.1533146398864; Wed, 01 Aug 2018 10:59:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533146398; cv=none; d=google.com; s=arc-20160816; b=EN3awAQmkcAYNCJ2K4rr3Q7PdkE/4owAowfIww6ox1CcZSfa9/weAf1Xmz+XF/5Cck WWiDT+lINnSeSt/09l5b3Pt3JnDpHKp1w5uDbikCywxRKZnJkXAtk0NCLmISCnhonANH OVPBe9++JiJo+oBoKL+f+MJP4PUVEzOWKXY9f/1lfgBGQ3NkdwmvjNhJ1kdTXZozdWha SWung0Fb6prs7hhc8SopzDfNvSwCE9gH/5OJuey3eWPm9FUSEGX8Wpp/YZdYezBTZUq3 9X/o3Y53RX9HPpP3S2AVfjpjIgao6yxjbMsjXDWDTmnpveRDvWCDIz+nHvI+Xe7WB8DY a91A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=wCjIlvlbfRLG7x+xTozg5L4cYr1x4kPA0h51W8D9SZs=; b=k2E6juoOjBdRwCrMGI1SPmW2WCgX1o/OqLfohPNpO9RrtPsLYWQ1NyvInm3qJbh+LM kBXCxG1iRnUo7qLD36pISHU8VNDzMHqdshGihe5qVdYzuqhnFxiA9U8Fh2D14RXyFoKo rjAhPc6fEmwHfNBSoaOeYD3qvC7ZkvYDs6Vl6xHQ51/fMximNMA4XePoWgkRxbblzB2V Kw5uv6UlG9pcp+J8sVLcvzWN7qDMhcCGE30b4QRw0D6hp/CsNwBvgbtgwcji4PDHGFvH /9fG9AjSRXBU4hBhxrY78eTT0rKBQe/7q7E/L4tW/V/4IdN5z9qNOtvxKWY5dnKowZWd DY1A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s23-v6si16867305pgs.499.2018.08.01.10.59.44; Wed, 01 Aug 2018 10:59:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732497AbeHATpR (ORCPT + 99 others); Wed, 1 Aug 2018 15:45:17 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:49926 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405922AbeHATIj (ORCPT ); Wed, 1 Aug 2018 15:08:39 -0400 Received: from localhost (D57E6652.static.ziggozakelijk.nl [213.126.102.82]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 0E9D713D1; Wed, 1 Aug 2018 17:16:04 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nikolay Borisov , Qu Wenruo , David Sterba , Sasha Levin Subject: [PATCH 4.14 085/246] btrfs: qgroup: Finish rescan when hit the last leaf of extent tree Date: Wed, 1 Aug 2018 18:49:55 +0200 Message-Id: <20180801165015.794432322@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180801165011.700991984@linuxfoundation.org> References: <20180801165011.700991984@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Qu Wenruo [ Upstream commit ff3d27a048d926b3920ccdb75d98788c567cae0d ] Under the following case, qgroup rescan can double account cowed tree blocks: In this case, extent tree only has one tree block. - | transid=5 last committed=4 | btrfs_qgroup_rescan_worker() | |- btrfs_start_transaction() | | transid = 5 | |- qgroup_rescan_leaf() | |- btrfs_search_slot_for_read() on extent tree | Get the only extent tree block from commit root (transid = 4). | Scan it, set qgroup_rescan_progress to the last | EXTENT/META_ITEM + 1 | now qgroup_rescan_progress = A + 1. | | fs tree get CoWed, new tree block is at A + 16K | transid 5 get committed - | transid=6 last committed=5 | btrfs_qgroup_rescan_worker() | btrfs_qgroup_rescan_worker() | |- btrfs_start_transaction() | | transid = 5 | |- qgroup_rescan_leaf() | |- btrfs_search_slot_for_read() on extent tree | Get the only extent tree block from commit root (transid = 5). | scan it using qgroup_rescan_progress (A + 1). | found new tree block beyong A, and it's fs tree block, | account it to increase qgroup numbers. - In above case, tree block A, and tree block A + 16K get accounted twice, while qgroup rescan should stop when it already reach the last leaf, other than continue using its qgroup_rescan_progress. Such case could happen by just looping btrfs/017 and with some possibility it can hit such double qgroup accounting problem. Fix it by checking the path to determine if we should finish qgroup rescan, other than relying on next loop to exit. Reported-by: Nikolay Borisov Signed-off-by: Qu Wenruo Signed-off-by: David Sterba Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/qgroup.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2500,6 +2500,21 @@ out: } /* + * Check if the leaf is the last leaf. Which means all node pointers + * are at their last position. + */ +static bool is_last_leaf(struct btrfs_path *path) +{ + int i; + + for (i = 1; i < BTRFS_MAX_LEVEL && path->nodes[i]; i++) { + if (path->slots[i] != btrfs_header_nritems(path->nodes[i]) - 1) + return false; + } + return true; +} + +/* * returns < 0 on error, 0 when more leafs are to be scanned. * returns 1 when done. */ @@ -2512,6 +2527,7 @@ qgroup_rescan_leaf(struct btrfs_fs_info struct ulist *roots = NULL; struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem); u64 num_bytes; + bool done; int slot; int ret; @@ -2540,6 +2556,7 @@ qgroup_rescan_leaf(struct btrfs_fs_info mutex_unlock(&fs_info->qgroup_rescan_lock); return ret; } + done = is_last_leaf(path); btrfs_item_key_to_cpu(path->nodes[0], &found, btrfs_header_nritems(path->nodes[0]) - 1); @@ -2586,6 +2603,8 @@ out: } btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem); + if (done && !ret) + ret = 1; return ret; }