Received: by 10.213.65.68 with SMTP id h4csp1782659imn; Mon, 19 Mar 2018 13:08:09 -0700 (PDT) X-Google-Smtp-Source: AG47ELsYG44jAlScIKSoPfXZ+jOHqRhd1ssPSRg/xQ/hD9MWrLak/cHrpHs8caVpMQ5LfLYgdCgi X-Received: by 10.99.153.1 with SMTP id d1mr9962297pge.338.1521490089168; Mon, 19 Mar 2018 13:08:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521490089; cv=none; d=google.com; s=arc-20160816; b=tWdrjXGbkCKa3zt922WSAzsSpuqhU0lyfQcdvAyDcyP2WD9coF18XtWws9f0UXEB0b 51WKvdTNHWa/ijFv5ebCZmS55PwIzrm1AGsU280RvcXLvkMtIplVbWLvHLP3EJ1rBAfS V5TZSKCxdXQJ5if2+lszeDCwQdm0/A9beHdrLac6bbJPRyT0zpFqFnt5UD7DECWl2BOQ DVjWYPYzD7JWW2NRiaUIdh9hLG1sSwPRP35Kn5uUuQhzHN7HgQs2P+IzUIxRr1MbxNqi L/bv47DKltWUiZrzpMN1pl/X2cffF1cgECH046Y/INTGVblxSJEQ5Jpb1vPSWw7439Ze rLkQ== 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=J7PC1jB9UdlkvFyNp2JKfFxgAsx18T3TxAoE15JDv3Q=; b=NBe0Mq2PlW9pPCxFNgZwKnpgKYpYIuSGTTIHRicfMQZA9ANCX6VENnTBjMsYLmRUjG Lhr26qC1qrgmZsJDYlnyJDqJBLcCqmF6W/OhCqgR12ghUKcS4i6i1aiFWoB3ToqTwkSp p6jEzglVcY0o7GFgFDwMeTkFVrBCW3PV5QRKJUvTpx2leY8OhsE6KbpgzEVYLC3zzXXV 1TCFoCUGeQTQ7P5c52Cllu2Y+jzHS4E3ajni9H/pv00Uvve+5mGF3Pt1qo85gLE1cpC3 geof86nnj4CTg0dsoI1twd0t/Wb2KeKfnm8D4zj4UG7rmeeFtLUsWYU+BNrod+bkK7oR VakA== 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 m13si13712pgc.35.2018.03.19.13.07.54; Mon, 19 Mar 2018 13:08:09 -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 S969308AbeCSUFx (ORCPT + 99 others); Mon, 19 Mar 2018 16:05:53 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:45602 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934226AbeCSSRf (ORCPT ); Mon, 19 Mar 2018 14:17:35 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 1006E123F; Mon, 19 Mar 2018 18:17:34 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Naohiro Aota , Hans van Kranenburg , David Sterba Subject: [PATCH 4.4 130/134] btrfs: alloc_chunk: fix DUP stripe size handling Date: Mon, 19 Mar 2018 19:06:53 +0100 Message-Id: <20180319171908.027816489@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180319171849.024066323@linuxfoundation.org> References: <20180319171849.024066323@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.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Hans van Kranenburg commit 92e222df7b8f05c565009c7383321b593eca488b upstream. In case of using DUP, we search for enough unallocated disk space on a device to hold two stripes. The devices_info[ndevs-1].max_avail that holds the amount of unallocated space found is directly assigned to stripe_size, while it's actually twice the stripe size. Later on in the code, an unconditional division of stripe_size by dev_stripes corrects the value, but in the meantime there's a check to see if the stripe_size does not exceed max_chunk_size. Since during this check stripe_size is twice the amount as intended, the check will reduce the stripe_size to max_chunk_size if the actual correct to be used stripe_size is more than half the amount of max_chunk_size. The unconditional division later tries to correct stripe_size, but will actually make sure we can't allocate more than half the max_chunk_size. Fix this by moving the division by dev_stripes before the max chunk size check, so it always contains the right value, instead of putting a duct tape division in further on to get it fixed again. Since in all other cases than DUP, dev_stripes is 1, this change only affects DUP. Other attempts in the past were made to fix this: * 37db63a400 "Btrfs: fix max chunk size check in chunk allocator" tried to fix the same problem, but still resulted in part of the code acting on a wrongly doubled stripe_size value. * 86db25785a "Btrfs: fix max chunk size on raid5/6" unintentionally broke this fix again. The real problem was already introduced with the rest of the code in 73c5de0051. The user visible result however will be that the max chunk size for DUP will suddenly double, while it's actually acting according to the limits in the code again like it was 5 years ago. Reported-by: Naohiro Aota Link: https://www.spinics.net/lists/linux-btrfs/msg69752.html Fixes: 73c5de0051 ("btrfs: quasi-round-robin for chunk allocation") Fixes: 86db25785a ("Btrfs: fix max chunk size on raid5/6") Signed-off-by: Hans van Kranenburg Reviewed-by: David Sterba [ update comment ] Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/volumes.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -4638,10 +4638,13 @@ static int __btrfs_alloc_chunk(struct bt if (devs_max && ndevs > devs_max) ndevs = devs_max; /* - * the primary goal is to maximize the number of stripes, so use as many - * devices as possible, even if the stripes are not maximum sized. + * The primary goal is to maximize the number of stripes, so use as + * many devices as possible, even if the stripes are not maximum sized. + * + * The DUP profile stores more than one stripe per device, the + * max_avail is the total size so we have to adjust. */ - stripe_size = devices_info[ndevs-1].max_avail; + stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes); num_stripes = ndevs * dev_stripes; /* @@ -4681,8 +4684,6 @@ static int __btrfs_alloc_chunk(struct bt stripe_size = devices_info[ndevs-1].max_avail; } - stripe_size = div_u64(stripe_size, dev_stripes); - /* align to BTRFS_STRIPE_LEN */ stripe_size = div_u64(stripe_size, raid_stripe_len); stripe_size *= raid_stripe_len;