From patchwork Thu Feb 16 20:37:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143770 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 F16C4C636CC for ; Thu, 16 Feb 2023 20:37:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229506AbjBPUh0 (ORCPT ); Thu, 16 Feb 2023 15:37:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229764AbjBPUhZ (ORCPT ); Thu, 16 Feb 2023 15:37:25 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 779C2D505 for ; Thu, 16 Feb 2023 12:37:24 -0800 (PST) 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 ams.source.kernel.org (Postfix) with ESMTPS id 2EB28B826BA for ; Thu, 16 Feb 2023 20:37:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAB73C433EF; Thu, 16 Feb 2023 20:37:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676579841; bh=M8YD+8rKE3mJ3o/zsXUt7fG1b1BqE+A3JMOmOabDa8w=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Sx4hIIh/1DxKF/tYFkt287UJf7Ykz8N7Z58qQNKsN62SneY+YvySV1/sJEsCd/lRQ XMhm+I+EWzNQGJIvNU0cUfYHGhugjrweMbhTLiCwLnDhfalpyiu5mWLN5yVAehNOS2 9lmtvPAhTNEgS4DcztM89kf7uusHiTsGHWQ8TvOr6WWgEBE41pW2ZkXFP/6+PeOcvF 9YG9xH7TTr5qy7qmDw2TPmA9f3dWCBSUb0SDGFrZU8EKuhL+gIEnGpJjiVlKyhJjbx emJNUlmVfYAxD9OpL+akHn7TmDEScJbRBAXMjQdNdCSLSJckliB1a3551CghF3e38Q xJ55ayV7fBCjg== Date: Thu, 16 Feb 2023 12:37:21 -0800 Subject: [PATCH 18/28] xfs: remove parent pointers in unlink From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657872640.3473407.7393115324146048389.stgit@magnolia> In-Reply-To: <167657872335.3473407.14628732092515467392.stgit@magnolia> References: <167657872335.3473407.14628732092515467392.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch removes the parent pointer attribute during unlink Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 2 +- fs/xfs/libxfs/xfs_attr.h | 1 + fs/xfs/libxfs/xfs_parent.c | 17 ++++++++++++++++ fs/xfs/libxfs/xfs_parent.h | 5 +++++ fs/xfs/libxfs/xfs_trans_space.h | 2 -- fs/xfs/xfs_inode.c | 42 +++++++++++++++++++++++++++++++++------ 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index f68d41f0f998..a8db44728b11 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -946,7 +946,7 @@ xfs_attr_defer_replace( } /* Removes an attribute for an inode as a deferred operation */ -static int +int xfs_attr_defer_remove( struct xfs_da_args *args) { diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 0cf23f5117ad..033005542b9e 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -545,6 +545,7 @@ bool xfs_attr_is_leaf(struct xfs_inode *ip); int xfs_attr_get_ilocked(struct xfs_da_args *args); int xfs_attr_get(struct xfs_da_args *args); int xfs_attr_defer_add(struct xfs_da_args *args); +int xfs_attr_defer_remove(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); diff --git a/fs/xfs/libxfs/xfs_parent.c b/fs/xfs/libxfs/xfs_parent.c index 6b6d415319e6..245855a5f969 100644 --- a/fs/xfs/libxfs/xfs_parent.c +++ b/fs/xfs/libxfs/xfs_parent.c @@ -115,6 +115,23 @@ xfs_parent_defer_add( return xfs_attr_defer_add(args); } +int +xfs_parent_defer_remove( + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_parent_defer *parent, + xfs_dir2_dataptr_t diroffset, + struct xfs_inode *child) +{ + struct xfs_da_args *args = &parent->args; + + xfs_init_parent_name_rec(&parent->rec, dp, diroffset); + args->trans = tp; + args->dp = child; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return xfs_attr_defer_remove(args); +} + void __xfs_parent_cancel( xfs_mount_t *mp, diff --git a/fs/xfs/libxfs/xfs_parent.h b/fs/xfs/libxfs/xfs_parent.h index d5a8c8e52cb5..0f39d033d84e 100644 --- a/fs/xfs/libxfs/xfs_parent.h +++ b/fs/xfs/libxfs/xfs_parent.h @@ -40,6 +40,11 @@ xfs_parent_start( int xfs_parent_defer_add(struct xfs_trans *tp, struct xfs_parent_defer *parent, struct xfs_inode *dp, struct xfs_name *parent_name, xfs_dir2_dataptr_t diroffset, struct xfs_inode *child); +int xfs_parent_defer_remove(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_parent_defer *parent, + xfs_dir2_dataptr_t diroffset, + struct xfs_inode *child); + void __xfs_parent_cancel(struct xfs_mount *mp, struct xfs_parent_defer *parent); static inline void diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h index 25a55650baf4..b5ab6701e7fb 100644 --- a/fs/xfs/libxfs/xfs_trans_space.h +++ b/fs/xfs/libxfs/xfs_trans_space.h @@ -91,8 +91,6 @@ XFS_DQUOT_CLUSTER_SIZE_FSB) #define XFS_QM_QINOCREATE_SPACE_RES(mp) \ XFS_IALLOC_SPACE_RES(mp) -#define XFS_REMOVE_SPACE_RES(mp) \ - XFS_DIRREMOVE_SPACE_RES(mp) #define XFS_RENAME_SPACE_RES(mp,nl) \ (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_IFREE_SPACE_RES(mp) \ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b4318df03b5c..7b34ca2de569 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2477,6 +2477,19 @@ xfs_iunpin_wait( __xfs_iunpin_wait(ip); } +static unsigned int +xfs_remove_space_res( + struct xfs_mount *mp, + unsigned int namelen) +{ + unsigned int ret = XFS_DIRREMOVE_SPACE_RES(mp); + + if (xfs_has_parent(mp)) + ret += xfs_pptr_calc_space_res(mp, namelen); + + return ret; +} + /* * Removing an inode from the namespace involves removing the directory entry * and dropping the link count on the inode. Removing the directory entry can @@ -2506,16 +2519,18 @@ xfs_iunpin_wait( */ int xfs_remove( - xfs_inode_t *dp, + struct xfs_inode *dp, struct xfs_name *name, - xfs_inode_t *ip) + struct xfs_inode *ip) { - xfs_mount_t *mp = dp->i_mount; - xfs_trans_t *tp = NULL; + struct xfs_mount *mp = dp->i_mount; + struct xfs_trans *tp = NULL; int is_dir = S_ISDIR(VFS_I(ip)->i_mode); int dontcare; int error = 0; uint resblks; + xfs_dir2_dataptr_t dir_offset; + struct xfs_parent_defer *parent = NULL; trace_xfs_remove(dp, name); @@ -2530,6 +2545,10 @@ xfs_remove( if (error) goto std_return; + error = xfs_parent_start(mp, &parent); + if (error) + goto std_return; + /* * We try to get the real space reservation first, allowing for * directory btree deletion(s) implying possible bmap insert(s). If we @@ -2541,12 +2560,12 @@ xfs_remove( * the directory code can handle a reservationless update and we don't * want to prevent a user from trying to free space by deleting things. */ - resblks = XFS_REMOVE_SPACE_RES(mp); + resblks = xfs_remove_space_res(mp, name->len); error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, ip, &resblks, &tp, &dontcare); if (error) { ASSERT(error != -ENOSPC); - goto std_return; + goto out_parent; } /* @@ -2600,12 +2619,18 @@ xfs_remove( if (error) goto out_trans_cancel; - error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks, NULL); + error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks, &dir_offset); if (error) { ASSERT(error != -ENOENT); goto out_trans_cancel; } + if (parent) { + error = xfs_parent_defer_remove(tp, dp, parent, dir_offset, ip); + if (error) + goto out_trans_cancel; + } + /* * If this is a synchronous mount, make sure that the * remove transaction goes to disk before returning to @@ -2623,6 +2648,7 @@ xfs_remove( xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL); + xfs_parent_finish(mp, parent); return 0; out_trans_cancel: @@ -2630,6 +2656,8 @@ xfs_remove( out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL); + out_parent: + xfs_parent_finish(mp, parent); std_return: return error; }