Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp3099108rwb; Mon, 15 Aug 2022 18:04:57 -0700 (PDT) X-Google-Smtp-Source: AA6agR4SnPyLgxbs1+9HmGxadQsK8afR7OdYCxiEtgLTzrzGn7MyODux6Pd7paUG+a/3MXYienjw X-Received: by 2002:a17:906:6a0f:b0:730:df34:6ec4 with SMTP id qw15-20020a1709066a0f00b00730df346ec4mr12445116ejc.659.1660611896864; Mon, 15 Aug 2022 18:04:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660611896; cv=none; d=google.com; s=arc-20160816; b=CF1qc/qs0c4RikzVwBrWGY5msp2xXFvk06kM6WZt6qEYW1uPSmAgJfbdZTZQXbUJha 3EEkD6EmPneH2/pb0ZbJEGWygnEVScx/DuMYb9lyAcGGSC23qAlUBN72PeA2yoqWc31F sCMnSRO4mwB4IEIzHUDt8juxHNIHsKUBZuV27TxvefDead0XHw6YZPCy8U6xlLdeEqRI 8erU8Rhudj625nIyXj/Rlkiiga9ir4p9fjVOW9sRTLD6EIBLiyTIPlzLTVKizo5zfOM7 Cl/TUXkYQzUVnxWgyJlbhVOucC8yXWMXxoJypKlBEhcvVD5jVhMIvbA5R1e+PyOJ5hzV B2YA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=68y1pO+/6l5TPMB3MEASSm3DLlAfDgXWN8iJhKtdIPY=; b=idGkDTGnWdcdai45SgXIzNOISgPbLaeXJ5rs7lBobxwGPn7iADS7MYkH55OQP9vuKo JSPjM42Z3t5m3tNlEJxi/PVRK1nWgz8/dLsWQkcTLUfWmRu8STjA/rYvzldkf/o78cr9 7T9jgCdV27dZEwWfuUpTJAurlWJzJe72OSnJekQuFFzR2L7ToMviBHf3UVS5SvTOtRhw YfGfZNehBGdlFgAn6BrxfMlake0NYX1YpTYnmmuJj2qZY7JwfODcGeTidGRmo50I+zb/ SUwX4YukEF/olK7PGIByU8VGNcWWrZwCthQtDBi1fbqp0zESiVLOLdDntjQbOVZeB92C fiJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=pojaVERL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u8-20020a50eac8000000b0043e6a16bca1si8449217edp.475.2022.08.15.18.04.12; Mon, 15 Aug 2022 18:04:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=pojaVERL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347440AbiHPBCB (ORCPT + 99 others); Mon, 15 Aug 2022 21:02:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344282AbiHPA4b (ORCPT ); Mon, 15 Aug 2022 20:56:31 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C603819DAAF; Mon, 15 Aug 2022 13:48:11 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5B3E86127D; Mon, 15 Aug 2022 20:48:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14D14C4314C; Mon, 15 Aug 2022 20:48:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660596490; bh=QWABRTprLy9+UMnIwAwPfZnR1exe3gryeLHIPnzbSmo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pojaVERLzXVlgIPuGfecrRcTTnSNLmLylJ0BXOj21i6WIqhrfEXSfHyr6ZygZj3tV jp7a6lhJ1+Yr8/NyXhxb0PYFgZplE4t7R8Tp1BrmJ0LiDaKf3SPhrwpCyWQp4zI0Xu lVRieWRThaV9mnNiG8VLTzCFI+EZc+atEgbYgt8I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Zygo Blaxell , Josef Bacik , Filipe Manana , David Sterba , Sasha Levin Subject: [PATCH 5.19 1097/1157] btrfs: join running log transaction when logging new name Date: Mon, 15 Aug 2022 20:07:33 +0200 Message-Id: <20220815180524.132079476@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180439.416659447@linuxfoundation.org> References: <20220815180439.416659447@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Filipe Manana [ Upstream commit 723df2bcc9e166ac7fb82b3932a53e09415dfcde ] When logging a new name, in case of a rename, we pin the log before changing it. We then either delete a directory entry from the log or insert a key range item to mark the old name for deletion on log replay. However when doing one of those log changes we may have another task that started writing out the log (at btrfs_sync_log()) and it started before we pinned the log root. So we may end up changing a log tree while its writeback is being started by another task syncing the log. This can lead to inconsistencies in a log tree and other unexpected results during log replay, because we can get some committed node pointing to a node/leaf that ends up not getting written to disk before the next log commit. The problem, conceptually, started to happen in commit 88d2beec7e53fc ("btrfs: avoid logging all directory changes during renames"), because there we started to update the log without joining its current transaction first. However the problem only became visible with commit 259c4b96d78dda ("btrfs: stop doing unnecessary log updates during a rename"), and that is because we used to pin the log at btrfs_rename() and then before entering btrfs_log_new_name(), when unlinking the old dentry, we ended up at btrfs_del_inode_ref_in_log() and btrfs_del_dir_entries_in_log(). Both of them join the current log transaction, effectively waiting for any log transaction writeout (due to acquiring the root's log_mutex). This made it safe even after leaving the current log transaction, because we remained with the log pinned when we called btrfs_log_new_name(). Then in commit 259c4b96d78dda ("btrfs: stop doing unnecessary log updates during a rename"), we removed the log pinning from btrfs_rename() and stopped calling btrfs_del_inode_ref_in_log() and btrfs_del_dir_entries_in_log() during the rename, and started to do all the needed work at btrfs_log_new_name(), but without joining the current log transaction, only pinning the log, which is racy because another task may have started writeout of the log tree right before we pinned the log. Both commits landed in kernel 5.18, so it doesn't make any practical difference which should be blamed, but I'm blaming the second commit only because with the first one, by chance, the problem did not happen due to the fact we joined the log transaction after pinning the log and unpinned it only after calling btrfs_log_new_name(). So make btrfs_log_new_name() join the current log transaction instead of pinning it, so that we never do log updates if it's writeout is starting. Fixes: 259c4b96d78dda ("btrfs: stop doing unnecessary log updates during a rename") CC: stable@vger.kernel.org # 5.18+ Reported-by: Zygo Blaxell Tested-by: Zygo Blaxell Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/tree-log.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index c94713c811bb..3c962bfd204f 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -7029,8 +7029,15 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, * anyone from syncing the log until we have updated both inodes * in the log. */ + ret = join_running_log_trans(root); + /* + * At least one of the inodes was logged before, so this should + * not fail, but if it does, it's not serious, just bail out and + * mark the log for a full commit. + */ + if (WARN_ON_ONCE(ret < 0)) + goto out; log_pinned = true; - btrfs_pin_log_trans(root); path = btrfs_alloc_path(); if (!path) { -- 2.35.1