From nobody Fri Dec 19 17:35:30 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAD20C07E9D for ; Mon, 26 Sep 2022 11:16:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237623AbiIZLQY (ORCPT ); Mon, 26 Sep 2022 07:16:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234442AbiIZLPk (ORCPT ); Mon, 26 Sep 2022 07:15:40 -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 8B0DB65274; Mon, 26 Sep 2022 03:37:09 -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 E01F060AF0; Mon, 26 Sep 2022 10:30:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D450BC433D6; Mon, 26 Sep 2022 10:30:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1664188257; bh=XrY/kvQJTArJAl3vqCiYNo4EjSadl360AmWIo/uNlew=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=inXAuG9cYTiRGRLfzzCDG2H1Wknq70QYSiatdh2B5INVquWVseTONhCnD5lra3spP e0OU4ngxjMbkTHApmKK3r3YMIXywaGlkZuF181OvDI8XBIqlnCRO7fweLthkPjy04P 1d3RIYUusz7jRnjfRGEiIgXmND3Ma+tJmhoj0a64= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Frank Hofmann , Dave Chinner , "Darrick J. Wong" , Dave Chinner , Amir Goldstein , "Darrick J. Wong" Subject: [PATCH 5.10 061/141] xfs: reorder iunlink remove operation in xfs_ifree Date: Mon, 26 Sep 2022 12:11:27 +0200 Message-Id: <20220926100756.662473396@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220926100754.639112000@linuxfoundation.org> References: <20220926100754.639112000@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Dave Chinner commit 9a5280b312e2e7898b6397b2ca3cfd03f67d7be1 upstream. [backport for 5.10.y] The O_TMPFILE creation implementation creates a specific order of operations for inode allocation/freeing and unlinked list modification. Currently both are serialised by the AGI, so the order doesn't strictly matter as long as the are both in the same transaction. However, if we want to move the unlinked list insertions largely out from under the AGI lock, then we have to be concerned about the order in which we do unlinked list modification operations. O_TMPFILE creation tells us this order is inode allocation/free, then unlinked list modification. Change xfs_ifree() to use this same ordering on unlinked list removal. This way we always guarantee that when we enter the iunlinked list removal code from this path, we already have the AGI locked and we don't have to worry about lock nesting AGI reads inside unlink list locks because it's already locked and attached to the transaction. We can do this safely as the inode freeing and unlinked list removal are done in the same transaction and hence are atomic operations with respect to log recovery. Reported-by: Frank Hofmann Fixes: 298f7bec503f ("xfs: pin inode backing buffer to the inode log item") Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Acked-by: Darrick J. Wong Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_inode.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2669,14 +2669,13 @@ xfs_ifree_cluster( } =20 /* - * This is called to return an inode to the inode free list. - * The inode should already be truncated to 0 length and have - * no pages associated with it. This routine also assumes that - * the inode is already a part of the transaction. + * This is called to return an inode to the inode free list. The inode sh= ould + * already be truncated to 0 length and have no pages associated with it. = This + * routine also assumes that the inode is already a part of the transactio= n. * - * The on-disk copy of the inode will have been added to the list - * of unlinked inodes in the AGI. We need to remove the inode from - * that list atomically with respect to freeing it here. + * The on-disk copy of the inode will have been added to the list of unlin= ked + * inodes in the AGI. We need to remove the inode from that list atomicall= y with + * respect to freeing it here. */ int xfs_ifree( @@ -2694,13 +2693,16 @@ xfs_ifree( ASSERT(ip->i_d.di_nblocks =3D=3D 0); =20 /* - * Pull the on-disk inode from the AGI unlinked list. + * Free the inode first so that we guarantee that the AGI lock is going + * to be taken before we remove the inode from the unlinked list. This + * makes the AGI lock -> unlinked list modification order the same as + * used in O_TMPFILE creation. */ - error =3D xfs_iunlink_remove(tp, ip); + error =3D xfs_difree(tp, ip->i_ino, &xic); if (error) return error; =20 - error =3D xfs_difree(tp, ip->i_ino, &xic); + error =3D xfs_iunlink_remove(tp, ip); if (error) return error;