Received: by 2002:a05:7412:da14:b0:e2:908c:2ebd with SMTP id fe20csp1200588rdb; Sat, 7 Oct 2023 17:51:45 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFWUR67/MhAxOeGLwH4j/17/MjMBimF0H8EmaYDASRCxKOaOdysUZBbnRpILwoe3CdPaogG X-Received: by 2002:a17:902:e5c1:b0:1c6:23fd:fb18 with SMTP id u1-20020a170902e5c100b001c623fdfb18mr11997699plf.0.1696726305393; Sat, 07 Oct 2023 17:51:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696726305; cv=none; d=google.com; s=arc-20160816; b=X6mf3PAkLxgTlET/FydCxmXwkJ1Wz5Mpssc/UPTFgWMI49hPKsv74gxza2RzcOl5X4 gyuFT7+M7VvoaiC3ID85vb+G4FGF2VpYPgVEcoUyfkkBmBn9mi+GQMRqN7ZRTTmx8W/i xQtOZ6RYJkgWjJXJM+7LKT8OLwZgJ5B818hU6UMEjjcGJtic1Eta4JN6WVZxr9rWq3lo vG213DM+FbXN/eeyYFkw1870kmZPfJQ2n0bwxLklGYXkGSSWi/wwKmGMdipwH+xf/HrR msmLnGSCVkJIWSvQgxsBWqDtxH1N+Wg8mbcHmsqKiZXdIoOLqo9bFc1mBCSkICphJvaA yVDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wLDhQsTtzTvCepXi3qDR9+7MFfRdMjyJLF+0j2A81cM=; fh=YRcs3hqD9mDbXInKZFMvdIhhIomYF9yTSbAgbo3uYgs=; b=wz2r4Y6nFFSWirDZkcjJEtaDVwMp3v9fvAe220D+WM9N3Bg7JNDgDirEhVD9E7Gy+z 5WJTB7IR1YXLXdwcJdnP7IPEoHNcIWnEu9kYBJfYAjWk+sTsDFiC+/nPkcp0x2c2Kj5J NwSLiM5zdJsjrH+Et+Vex/MrGgM5J0ojdzwxgMrIhkhZ7bLH6U3Lj6tjcmKHHycXS2lp BFSFxg5aSAhoNyqb/3Zc4IWQI2ByIL9pcTJJP4yMCdnASwCECCpQdO69uItse56qdwj+ b2rmuVFBw22EP9gmVC4pva5g5R1HsSyt1anC43kovjSm3HoneqwGDcFnGVHQ1IJMYVFb GPcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="Wg/IJ9WK"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id e17-20020a170902f1d100b001b9e9fa3a38si6259912plc.646.2023.10.07.17.51.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Oct 2023 17:51:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="Wg/IJ9WK"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id EA78B8034664; Sat, 7 Oct 2023 17:51:36 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234427AbjJHAub (ORCPT + 99 others); Sat, 7 Oct 2023 20:50:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234374AbjJHAuF (ORCPT ); Sat, 7 Oct 2023 20:50:05 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93D3BDB; Sat, 7 Oct 2023 17:49:37 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 40D2BC433BC; Sun, 8 Oct 2023 00:49:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1696726177; bh=aySlpxPzYKweouPrs23+PsDDuAGtneQiFKNVAje+y6Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wg/IJ9WKuMZNj/TA93oXJuA5PbhXBz3DzfQ7FVw8g1M8UE0i+35xQFMdnByfh7P6J HFmRnY4m/TJbSUlWayMqNu80Ghx9MgizRRR43sMBUW4OhREh8lYU6djf0IaPKdmb+E 9nRsPdwxC5raKG3dZjO0emG9WSZkqW8TFb05KAXYLrzFC79BBDoKptXJNy/ZcYiIqC VFK3dCOGVB6mQjKwSiLdcX9dMKAwxta+XLbYT+rZpZPXNP6Q0cZaYRyZIJTejeFczR Cof3LVLpeAPZiYsDVM79KJDknb6fXHzyCOWNDTMaa67Wqp1O7+sgutAqzVtXgpl6TV Z/1eGclP7p+rQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Filipe Manana , Josef Bacik , David Sterba , Sasha Levin , clm@fb.com, linux-btrfs@vger.kernel.org Subject: [PATCH AUTOSEL 6.1 04/12] btrfs: prevent transaction block reserve underflow when starting transaction Date: Sat, 7 Oct 2023 20:49:21 -0400 Message-Id: <20231008004929.3767992-4-sashal@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231008004929.3767992-1-sashal@kernel.org> References: <20231008004929.3767992-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.1.56 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=2.4 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RCVD_IN_SBL_CSS,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Sat, 07 Oct 2023 17:51:37 -0700 (PDT) X-Spam-Level: ** From: Filipe Manana [ Upstream commit a7ddeeb079505961355cf0106154da0110f1fdff ] When starting a transaction, with a non-zero number of items, we reserve metadata space for that number of items and for delayed refs by doing a call to btrfs_block_rsv_add(), with the transaction block reserve passed as the block reserve argument. This reserves metadata space and adds it to the transaction block reserve. Later we migrate the space we reserved for delayed references from the transaction block reserve into the delayed refs block reserve, by calling btrfs_migrate_to_delayed_refs_rsv(). btrfs_migrate_to_delayed_refs_rsv() decrements the number of bytes to migrate from the source block reserve, and this however may result in an underflow in case the space added to the transaction block reserve ended up being used by another task that has not reserved enough space for its own use - examples are tasks doing reflinks or hole punching because they end up calling btrfs_replace_file_extents() -> btrfs_drop_extents() and may need to modify/COW a variable number of leaves/paths, so they keep trying to use space from the transaction block reserve when they need to COW an extent buffer, and may end up trying to use more space then they have reserved (1 unit/path only for removing file extent items). This can be avoided by simply reserving space first without adding it to the transaction block reserve, then add the space for delayed refs to the delayed refs block reserve and finally add the remaining reserved space to the transaction block reserve. This also makes the code a bit shorter and simpler. So just do that. Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/delayed-ref.c | 9 +-------- fs/btrfs/delayed-ref.h | 1 - fs/btrfs/transaction.c | 6 +++--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 36a3debe94930..e08e3852c4788 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c @@ -141,24 +141,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) * Transfer bytes to our delayed refs rsv * * @fs_info: the filesystem - * @src: source block rsv to transfer from * @num_bytes: number of bytes to transfer * - * This transfers up to the num_bytes amount from the src rsv to the + * This transfers up to the num_bytes amount, previously reserved, to the * delayed_refs_rsv. Any extra bytes are returned to the space info. */ void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, - struct btrfs_block_rsv *src, u64 num_bytes) { struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; u64 to_free = 0; - spin_lock(&src->lock); - src->reserved -= num_bytes; - src->size -= num_bytes; - spin_unlock(&src->lock); - spin_lock(&delayed_refs_rsv->lock); if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { u64 delta = delayed_refs_rsv->size - diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index d6304b690ec4a..712a6315e956b 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h @@ -383,7 +383,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, enum btrfs_reserve_flush_enum flush); void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, - struct btrfs_block_rsv *src, u64 num_bytes); int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans); bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a555567594418..847eee1e0db6f 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -613,14 +613,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, reloc_reserved = true; } - ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); + ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); if (ret) goto reserve_fail; if (delayed_refs_bytes) { - btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, - delayed_refs_bytes); + btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); num_bytes -= delayed_refs_bytes; } + btrfs_block_rsv_add_bytes(rsv, num_bytes, true); if (rsv->space_info->force_alloc) do_chunk_alloc = true; -- 2.40.1