Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp3078860rwb; Mon, 15 Aug 2022 17:36:16 -0700 (PDT) X-Google-Smtp-Source: AA6agR5b/uBBxMlCLgpm8yQr76YT5aw/76UZBr5FJorhq3ilnM2WAyNED8sTqHuLBK8adjnGNabD X-Received: by 2002:a17:906:7309:b0:731:5c2:a9a6 with SMTP id di9-20020a170906730900b0073105c2a9a6mr11960772ejc.486.1660610175972; Mon, 15 Aug 2022 17:36:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660610175; cv=none; d=google.com; s=arc-20160816; b=TBjQco4VsgdNOu4zWaPhvp5F6QtRVztgP6/lXdGiH5zkBYUv7nIWSpdeeCW9hmSCh1 3HIWATfT/7J2y/1r26Vhmz8VRDrgvj9+UMsYmwo1Wnk3kptAT+vYn2Qi1sVZtvoNBYnf Xic4QEM7AH2SaqMZYJRTRznU2BgxF2mrmoOfH9biyfaCU2mSrQ12RwACEPhpgHokPCEh C0gqxiBXLpIKXaia68yPAN3TFXrhQIz5BG1aXtJmVU+fOYczgPTUka2QLFluBiuKKfZ7 LU4TtGH8A0YiOyGlmpKrpXnbIWkX8rDUZZxkIxd7zgSFIPgtefPesOv7XIrgEMgGJvmH oENA== 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=V8+m8kQ4yVkGQktS5upvi0lDziZvtGGx4nFdS4CNtf4=; b=MyC9ifCBtI1ZLHM3FWS9gNxAv51r6AMptUF+R6o/yYWgWmFFy8xLtOGMmjtdNuKro5 qDcyUCZB8dmpo5NgxvKJOHq3NlYIbuW8ifwCuJBg8JQOKtGXZ0VTFCMeyj6qZ9KAqxGT CjD/0+16CTKu0NizAjM+k8pZbw6HGtNSUFJFIf0N5UAMaXhxoD7Fj0qKDeHSLWfNpLd1 F0bdnn91NcdCqf8pa1n7CCAgD+lWFLL/dk3RvG4lCNus6RAczSXnGT7L/V+TPga0cU7r HUPahXReom9gD+GHDbb25Uip8SE46GWiN3H5jWaAvzJ+gvXWbaFCrifH6bW6iynAaLoh dR9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ziiJtNo8; 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 gt6-20020a1709072d8600b007309efc29a4si12723568ejc.691.2022.08.15.17.35.50; Mon, 15 Aug 2022 17:36:15 -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=ziiJtNo8; 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 S1347274AbiHOXm6 (ORCPT + 99 others); Mon, 15 Aug 2022 19:42:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353855AbiHOXkj (ORCPT ); Mon, 15 Aug 2022 19:40:39 -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 2BF207AC36; Mon, 15 Aug 2022 13:10:21 -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 91D1760025; Mon, 15 Aug 2022 20:10:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8FFB7C433C1; Mon, 15 Aug 2022 20:10:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660594220; bh=erej0F3HfFa9PrnUxX23hPKwC7NbDr3RNag2SKdL+00=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ziiJtNo8uYw8Gmr43LpcGU1HHR8ea/nkpNyc7G3JCnnOy/PlIbhnA8+WUaRTN3zLH IXL342TBgcu5WbrjHZ1JjHUrfhCdH9jWNv1rCIuq8BGPiNVeh6fnBjMA+ks9OVf3QI 5jvreosYmogmNKETC2mskvbMwCtvpwV3ALQek/Cw= 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 Subject: [PATCH 5.18 1074/1095] btrfs: join running log transaction when logging new name Date: Mon, 15 Aug 2022 20:07:53 +0200 Message-Id: <20220815180513.477170920@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180429.240518113@linuxfoundation.org> References: <20220815180429.240518113@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 commit 723df2bcc9e166ac7fb82b3932a53e09415dfcde upstream. 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: Greg Kroah-Hartman --- fs/btrfs/tree-log.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -7030,8 +7030,15 @@ void btrfs_log_new_name(struct btrfs_tra * 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) {