From patchwork Mon May 31 22:40:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12290117 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48ED5C47080 for ; Mon, 31 May 2021 22:40:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C6B9611CB for ; Mon, 31 May 2021 22:40:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232366AbhEaWmi (ORCPT ); Mon, 31 May 2021 18:42:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:49912 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232349AbhEaWmh (ORCPT ); Mon, 31 May 2021 18:42:37 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id ED32A60FDC; Mon, 31 May 2021 22:40:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622500857; bh=egRICAkw17b7GYUc6RQshfGpFY/JWDVgRP3qIe03SKs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=gRbwa04BJ2VwkpQJzc91XFF9/R5tH0THfh+59VVs/CglbB4ZtPxoVuexE2kH+uqTa Q3Qe9+tnpsS5gtPXeU4cm7qCK6Ewtan3w0j7ggGC3Cg7bQ4yHUb13WooLqKBnofIfN 24b881FUoIQdzXXQUN2JG/CouAE9C4sygwaWgt1OF9lSr2AQz/kNyYiVn0aOe8Rlv5 ZLPvd8NPmpXK/t8e0B5f6f36CxwwCoYdqyVfGBOB9gZs8wPUBiXj3qEiYeelp1DlI7 LabbfPg07v1SJzaeBJJVsrw/aeNrJXGnyqxIBjdRLgDwPu1mq7zRITWsG/TMUwfvju 09kg2h+PcYAtA== Subject: [PATCH 1/5] xfs: move the quotaoff dqrele inode walk into xfs_icache.c From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org, hch@infradead.org Date: Mon, 31 May 2021 15:40:56 -0700 Message-ID: <162250085666.490412.5742339414043345426.stgit@locust> In-Reply-To: <162250085103.490412.4291071116538386696.stgit@locust> References: <162250085103.490412.4291071116538386696.stgit@locust> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong The only external caller of xfs_inode_walk* happens in quotaoff, when we want to walk all the incore inodes to detach the dquots. Move this code to xfs_icache.c so that we can hide xfs_inode_walk as the starting step in more cleanups of inode walks. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 52 +++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_icache.h | 13 +++++++++-- fs/xfs/xfs_qm.h | 1 - fs/xfs/xfs_qm_syscalls.c | 54 ++-------------------------------------------- 4 files changed, 63 insertions(+), 57 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 3c81daca0e9a..32c17e84efa0 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -890,7 +890,7 @@ xfs_inode_walk_get_perag( * Call the @execute function on all incore inodes matching the radix tree * @tag. */ -int +static int xfs_inode_walk( struct xfs_mount *mp, int iter_flags, @@ -917,6 +917,56 @@ xfs_inode_walk( return last_error; } +/* Drop this inode's dquots. */ +static int +xfs_dqrele_inode( + struct xfs_inode *ip, + void *priv) +{ + struct xfs_eofblocks *eofb = priv; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + if (eofb->eof_flags & XFS_EOFB_DROP_UDQUOT) { + xfs_qm_dqrele(ip->i_udquot); + ip->i_udquot = NULL; + } + if (eofb->eof_flags & XFS_EOFB_DROP_GDQUOT) { + xfs_qm_dqrele(ip->i_gdquot); + ip->i_gdquot = NULL; + } + if (eofb->eof_flags & XFS_EOFB_DROP_PDQUOT) { + xfs_qm_dqrele(ip->i_pdquot); + ip->i_pdquot = NULL; + } + xfs_iunlock(ip, XFS_ILOCK_EXCL); + return 0; +} + +/* + * Detach all dquots from incore inodes if we can. The caller must already + * have dropped the relevant XFS_[UGP]QUOTA_ACTIVE flags so that dquots will + * not get reattached. + */ +int +xfs_dqrele_all_inodes( + struct xfs_mount *mp, + unsigned int qflags) +{ + struct xfs_eofblocks eofb = { .eof_flags = 0 }; + + BUILD_BUG_ON(XFS_EOFB_PRIVATE_FLAGS & XFS_EOF_FLAGS_VALID); + + if (qflags & XFS_UQUOTA_ACCT) + eofb.eof_flags |= XFS_EOFB_DROP_UDQUOT; + if (qflags & XFS_GQUOTA_ACCT) + eofb.eof_flags |= XFS_EOFB_DROP_GDQUOT; + if (qflags & XFS_PQUOTA_ACCT) + eofb.eof_flags |= XFS_EOFB_DROP_PDQUOT; + + return xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, + &eofb, XFS_ICI_NO_TAG); +} + /* * Grab the inode for reclaim exclusively. * diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index d1fddb152420..77029e92ba4c 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -17,6 +17,15 @@ struct xfs_eofblocks { __u64 eof_min_file_size; }; +/* Special eof_flags for dropping dquots. */ +#define XFS_EOFB_DROP_UDQUOT (1U << 31) +#define XFS_EOFB_DROP_GDQUOT (1U << 30) +#define XFS_EOFB_DROP_PDQUOT (1U << 29) + +#define XFS_EOFB_PRIVATE_FLAGS (XFS_EOFB_DROP_UDQUOT | \ + XFS_EOFB_DROP_GDQUOT | \ + XFS_EOFB_DROP_PDQUOT) + /* * tags for inode radix tree */ @@ -68,9 +77,7 @@ void xfs_inode_clear_cowblocks_tag(struct xfs_inode *ip); void xfs_blockgc_worker(struct work_struct *work); -int xfs_inode_walk(struct xfs_mount *mp, int iter_flags, - int (*execute)(struct xfs_inode *ip, void *args), - void *args, int tag); +int xfs_dqrele_all_inodes(struct xfs_mount *mp, unsigned int qflags); int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino, bool *inuse); diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index e3dabab44097..ebbb484c49dc 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -142,7 +142,6 @@ extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); /* dquot stuff */ extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); -extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint); /* quota ops */ extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 11f1e2fbf22f..13a56e1ea15c 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -201,7 +201,8 @@ xfs_qm_scall_quotaoff( * depend on the quota inodes (and other things) being valid as long as * we keep the lock(s). */ - xfs_qm_dqrele_all_inodes(mp, flags); + error = xfs_dqrele_all_inodes(mp, flags); + ASSERT(!error); /* * Next we make the changes in the quota flag in the mount struct. @@ -747,54 +748,3 @@ xfs_qm_scall_getquota_next( xfs_qm_dqput(dqp); return error; } - -STATIC int -xfs_dqrele_inode( - struct xfs_inode *ip, - void *args) -{ - uint *flags = args; - - /* skip quota inodes */ - if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || - ip == ip->i_mount->m_quotainfo->qi_gquotaip || - ip == ip->i_mount->m_quotainfo->qi_pquotaip) { - ASSERT(ip->i_udquot == NULL); - ASSERT(ip->i_gdquot == NULL); - ASSERT(ip->i_pdquot == NULL); - return 0; - } - - xfs_ilock(ip, XFS_ILOCK_EXCL); - if ((*flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { - xfs_qm_dqrele(ip->i_udquot); - ip->i_udquot = NULL; - } - if ((*flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { - xfs_qm_dqrele(ip->i_gdquot); - ip->i_gdquot = NULL; - } - if ((*flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) { - xfs_qm_dqrele(ip->i_pdquot); - ip->i_pdquot = NULL; - } - xfs_iunlock(ip, XFS_ILOCK_EXCL); - return 0; -} - - -/* - * Go thru all the inodes in the file system, releasing their dquots. - * - * Note that the mount structure gets modified to indicate that quotas are off - * AFTER this, in the case of quotaoff. - */ -void -xfs_qm_dqrele_all_inodes( - struct xfs_mount *mp, - uint flags) -{ - ASSERT(mp->m_quotainfo); - xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, - &flags, XFS_ICI_NO_TAG); -} From patchwork Mon May 31 22:41:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12290119 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A93FC47080 for ; Mon, 31 May 2021 22:41:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3CEE3611CB for ; Mon, 31 May 2021 22:41:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231890AbhEaWmn (ORCPT ); Mon, 31 May 2021 18:42:43 -0400 Received: from mail.kernel.org ([198.145.29.99]:50046 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232268AbhEaWmm (ORCPT ); Mon, 31 May 2021 18:42:42 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 73543611CA; Mon, 31 May 2021 22:41:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622500862; bh=Qq/EaDuOT7OHdUg0Pj3P9kaOKblRYxo8LBcIkFQEKkc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=bGnDmE9TdcBDgMDZ+xM3sXlFl1KjOkqk245OYtENbKvTFYsHzr8iXM/I6W0dLzjwi aFh1U3+KoiLC9Algu8mI/7+jHmyW5Uf0+pcpX4n45+rRbKGtq390vTQA356Ys9fxrI 5mJXlGXvuypkGQqo+ZBlNlt5ySrnh4TzPBy373JiGSCFtoE+GcyC5aGBEEWs7cb6IY LREpXL9RrdFQ7o2axMyLY5EpH4b+3PnIh1zs+OnVWnyXJrA1rNxZLWsWVacZaXzSre k4TTPXo4FnqiCTen8mxUn0ZKQw3uBmRxdh+ZwuxFG9x7GZx/a6k2Bk+i+1nrTZn3Ly 7UrVhTbpY6NHw== Subject: [PATCH 2/5] xfs: detach inode dquots at the end of inactivation From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org, hch@infradead.org Date: Mon, 31 May 2021 15:41:02 -0700 Message-ID: <162250086215.490412.4278433430856337071.stgit@locust> In-Reply-To: <162250085103.490412.4291071116538386696.stgit@locust> References: <162250085103.490412.4291071116538386696.stgit@locust> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Once we're done with inactivating an inode, we're finished updating metadata for that inode. This means that we can detach the dquots at the end and not have to wait for reclaim to do it for us. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_inode.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 32c17e84efa0..34b8b5fbd60d 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1080,7 +1080,7 @@ xfs_reclaim_inode( * unlocked after the lookup before we go ahead and free it. */ xfs_ilock(ip, XFS_ILOCK_EXCL); - xfs_qm_dqdetach(ip); + ASSERT(!ip->i_udquot && !ip->i_gdquot && !ip->i_pdquot); xfs_iunlock(ip, XFS_ILOCK_EXCL); ASSERT(xfs_inode_clean(ip)); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1e28997c6f78..718ab0c17b9d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1713,7 +1713,7 @@ xfs_inactive( */ if (VFS_I(ip)->i_mode == 0) { ASSERT(ip->i_df.if_broot_bytes == 0); - return; + goto out; } mp = ip->i_mount; @@ -1721,11 +1721,11 @@ xfs_inactive( /* If this is a read-only mount, don't do this (would generate I/O) */ if (mp->m_flags & XFS_MOUNT_RDONLY) - return; + goto out; /* Metadata inodes require explicit resource cleanup. */ if (xfs_is_metadata_inode(ip)) - return; + goto out; /* Try to clean out the cow blocks if there are any. */ if (xfs_inode_has_cow_data(ip)) @@ -1744,7 +1744,7 @@ xfs_inactive( if (xfs_can_free_eofblocks(ip, true)) xfs_free_eofblocks(ip); - return; + goto out; } if (S_ISREG(VFS_I(ip)->i_mode) && @@ -1754,14 +1754,14 @@ xfs_inactive( error = xfs_qm_dqattach(ip); if (error) - return; + goto out; if (S_ISLNK(VFS_I(ip)->i_mode)) error = xfs_inactive_symlink(ip); else if (truncate) error = xfs_inactive_truncate(ip); if (error) - return; + goto out; /* * If there are attributes associated with the file then blow them away @@ -1771,7 +1771,7 @@ xfs_inactive( if (XFS_IFORK_Q(ip)) { error = xfs_attr_inactive(ip); if (error) - return; + goto out; } ASSERT(!ip->i_afp); @@ -1780,12 +1780,12 @@ xfs_inactive( /* * Free the inode. */ - error = xfs_inactive_ifree(ip); - if (error) - return; + xfs_inactive_ifree(ip); +out: /* - * Release the dquots held by inode, if any. + * We're done making metadata updates for this inode, so we can release + * the attached dquots. */ xfs_qm_dqdetach(ip); } From patchwork Mon May 31 22:41:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12290121 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C943C47082 for ; Mon, 31 May 2021 22:41:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 328FC611CB for ; Mon, 31 May 2021 22:41:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231144AbhEaWms (ORCPT ); Mon, 31 May 2021 18:42:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:50128 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232268AbhEaWms (ORCPT ); Mon, 31 May 2021 18:42:48 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id EEC8B60FDC; Mon, 31 May 2021 22:41:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622500868; bh=QMk4en1hpmqqhS2kssR9HBSjeN2L50NQvMy0jDAzg9s=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=aOkz5q77SHBw0QTn+X6bGSObVAWowesd2dbj2qaxUQyglCZARoogRRel31SIG+dOs jgbEgpDQ9myxA57nsisafr3QL1GjwdxwQioMFRAreazNXDP3uw4HF0yIUj2mQZu7zo pvcjKrtn4MfBcz9R2DnrzitQMOzNwUuyFYs/yo8rvpOYZBtXv1X+B1Un+TQQNwa2jY GEmPyOu+umXM6M92fAIGkC6wxtoQRtpdC2wvvEK7OjsiYDZs2nTqOaTvYricZ2eDkn lrnL6xqri2RtoFQTDLhZjJ1k9AV9lJCbbW47z1b68JVI/JrRXucGOqfXXZZML3oW9q KKGazzshrxslA== Subject: [PATCH 3/5] xfs: separate the dqrele_all inode grab logic from xfs_inode_walk_ag_grab From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org, hch@infradead.org Date: Mon, 31 May 2021 15:41:07 -0700 Message-ID: <162250086766.490412.9229536536315438431.stgit@locust> In-Reply-To: <162250085103.490412.4291071116538386696.stgit@locust> References: <162250085103.490412.4291071116538386696.stgit@locust> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Disentangle the dqrele_all inode grab code from the "generic" inode walk grabbing code, and and use the opportunity to document why the dqrele grab function does what it does. Since dqrele_all is the only user of XFS_ICI_NO_TAG, rename it to something more specific for what we're doing. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--- fs/xfs/xfs_icache.h | 4 ++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 34b8b5fbd60d..5501318b5db0 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -26,6 +26,8 @@ #include +static bool xfs_dqrele_inode_grab(struct xfs_inode *ip); + /* * Allocate and initialise an xfs_inode. */ @@ -765,6 +767,22 @@ xfs_inode_walk_ag_grab( return false; } +static inline bool +xfs_grabbed_for_walk( + int tag, + struct xfs_inode *ip, + int iter_flags) +{ + switch (tag) { + case XFS_ICI_BLOCKGC_TAG: + return xfs_inode_walk_ag_grab(ip, iter_flags); + case XFS_ICI_DQRELE_NONTAG: + return xfs_dqrele_inode_grab(ip); + default: + return false; + } +} + /* * For a given per-AG structure @pag, grab, @execute, and rele all incore * inodes with the given radix tree @tag. @@ -796,7 +814,7 @@ xfs_inode_walk_ag( rcu_read_lock(); - if (tag == XFS_ICI_NO_TAG) + if (tag == XFS_ICI_DQRELE_NONTAG) nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void **)batch, first_index, XFS_LOOKUP_BATCH); @@ -818,7 +836,7 @@ xfs_inode_walk_ag( for (i = 0; i < nr_found; i++) { struct xfs_inode *ip = batch[i]; - if (done || !xfs_inode_walk_ag_grab(ip, iter_flags)) + if (done || !xfs_grabbed_for_walk(tag, ip, iter_flags)) batch[i] = NULL; /* @@ -881,7 +899,7 @@ xfs_inode_walk_get_perag( xfs_agnumber_t agno, int tag) { - if (tag == XFS_ICI_NO_TAG) + if (tag == XFS_ICI_DQRELE_NONTAG) return xfs_perag_get(mp, agno); return xfs_perag_get_tag(mp, agno, tag); } @@ -917,6 +935,44 @@ xfs_inode_walk( return last_error; } +/* Decide if we want to grab this inode to drop its dquots. */ +static bool +xfs_dqrele_inode_grab( + struct xfs_inode *ip) +{ + bool ret = false; + + ASSERT(rcu_read_lock_held()); + + /* Check for stale RCU freed inode */ + spin_lock(&ip->i_flags_lock); + if (!ip->i_ino) + goto out_unlock; + + /* + * Skip inodes that are anywhere in the reclaim machinery because we + * drop dquots before tagging an inode for reclamation. + */ + if (ip->i_flags & (XFS_IRECLAIM | XFS_IRECLAIMABLE)) + goto out_unlock; + + /* + * The inode looks alive; try to grab a VFS reference so that it won't + * get destroyed. If we got the reference, return true to say that + * we grabbed the inode. + * + * If we can't get the reference, then we know the inode had its VFS + * state torn down and hasn't yet entered the reclaim machinery. Since + * we also know that dquots are detached from an inode before it enters + * reclaim, we can skip the inode. + */ + ret = igrab(VFS_I(ip)) != NULL; + +out_unlock: + spin_unlock(&ip->i_flags_lock); + return ret; +} + /* Drop this inode's dquots. */ static int xfs_dqrele_inode( @@ -964,7 +1020,7 @@ xfs_dqrele_all_inodes( eofb.eof_flags |= XFS_EOFB_DROP_PDQUOT; return xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, - &eofb, XFS_ICI_NO_TAG); + &eofb, XFS_ICI_DQRELE_NONTAG); } /* diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 77029e92ba4c..fcfcdad7f977 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -29,8 +29,8 @@ struct xfs_eofblocks { /* * tags for inode radix tree */ -#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup - in xfs_inode_walk */ +#define XFS_ICI_DQRELE_NONTAG (-1) /* quotaoff dqdetach inode walk uses + untagged lookups */ #define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */ /* Inode has speculative preallocations (posteof or cow) to clean. */ #define XFS_ICI_BLOCKGC_TAG 1 From patchwork Mon May 31 22:41:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12290123 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8F69C47082 for ; Mon, 31 May 2021 22:41:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC8A6611CA for ; Mon, 31 May 2021 22:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231624AbhEaWmy (ORCPT ); Mon, 31 May 2021 18:42:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:50194 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232268AbhEaWmx (ORCPT ); Mon, 31 May 2021 18:42:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 77F5D60FDC; Mon, 31 May 2021 22:41:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622500873; bh=ve4/+B7ihihTcsno8nIpyoQCEzSiyEeYfiPNOHlwcn4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=FVHIyTp391sCKBHJQXRe47gTCU0Xhba7y/Uo8ju3kLew9I3AxskGzuBAkQSbyOWys nHzo87He9t1SQSOxaNnSxqxTD0W9We664JlCeW5NjsyPXea85EVqE+O8jSS47CRwOx lo8IoTZ9uvuPvTEbOSBrmSSRJ26EhiZbHqM09D3j4Nuqfg9I9u8fp2oYEIdyjrgrYx bUI6bwfEK2kyvBbVuwy++l9r0suABsSb9OIlr14THyB69oNvV8lDGuBJI9unrT5wrK cxOoOaufhJdp7pTb9pgxOOYcm5C3nApfVd79ao7mKyPQRTZB+lhN3GgGLnu392/uLG wAjDlWVkZR1qw== Subject: [PATCH 4/5] xfs: drop inactive dquots before inactivating inodes From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org, hch@infradead.org Date: Mon, 31 May 2021 15:41:13 -0700 Message-ID: <162250087317.490412.346108244268292896.stgit@locust> In-Reply-To: <162250085103.490412.4291071116538386696.stgit@locust> References: <162250085103.490412.4291071116538386696.stgit@locust> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong During quotaoff, the incore inode scan to detach dquots from inodes won't touch inodes that have lost their VFS state but haven't yet been queued for reclaim. This isn't strictly a problem because we drop the dquots at the end of inactivation, but if we detect this situation before starting inactivation, we can drop the inactive dquots early to avoid delaying quotaoff further. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_super.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index a2dab05332ac..79f1cd1a0221 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -637,22 +637,46 @@ xfs_fs_destroy_inode( struct inode *inode) { struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; trace_xfs_destroy_inode(ip); ASSERT(!rwsem_is_locked(&inode->i_rwsem)); - XFS_STATS_INC(ip->i_mount, vn_rele); - XFS_STATS_INC(ip->i_mount, vn_remove); + XFS_STATS_INC(mp, vn_rele); + XFS_STATS_INC(mp, vn_remove); + + /* + * If a quota type is turned off but we still have a dquot attached to + * the inode, detach it before processing this inode to avoid delaying + * quotaoff for longer than is necessary. + * + * The inode has no VFS state and hasn't been tagged for any kind of + * reclamation, which means that iget, quotaoff, blockgc, and reclaim + * will not touch it. It is therefore safe to do this locklessly + * because we have the only reference here. + */ + if (!XFS_IS_UQUOTA_ON(mp)) { + xfs_qm_dqrele(ip->i_udquot); + ip->i_udquot = NULL; + } + if (!XFS_IS_GQUOTA_ON(mp)) { + xfs_qm_dqrele(ip->i_gdquot); + ip->i_gdquot = NULL; + } + if (!XFS_IS_PQUOTA_ON(mp)) { + xfs_qm_dqrele(ip->i_pdquot); + ip->i_pdquot = NULL; + } xfs_inactive(ip); - if (!XFS_FORCED_SHUTDOWN(ip->i_mount) && ip->i_delayed_blks) { + if (!XFS_FORCED_SHUTDOWN(mp) && ip->i_delayed_blks) { xfs_check_delalloc(ip, XFS_DATA_FORK); xfs_check_delalloc(ip, XFS_COW_FORK); ASSERT(0); } - XFS_STATS_INC(ip->i_mount, vn_reclaim); + XFS_STATS_INC(mp, vn_reclaim); /* * We should never get here with one of the reclaim flags already set. From patchwork Mon May 31 22:41:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12290125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63622C47082 for ; Mon, 31 May 2021 22:41:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4739C611CB for ; Mon, 31 May 2021 22:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232268AbhEaWm7 (ORCPT ); Mon, 31 May 2021 18:42:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:50264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232042AbhEaWm7 (ORCPT ); Mon, 31 May 2021 18:42:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id F1A78611CA; Mon, 31 May 2021 22:41:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622500879; bh=On1KisaY724niV5YETgIzrty25KZCppMYFGwZzZCQWc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=jtrGEjs05wzWv+/9anQtIPVMGnJ0/ZMXj839Do6vX360jVm3AV5zEj0j11fHLmvvR hlpZHtnqYwi4uk5/k2Tl6yaeg9uO18YRoHhCeNOQPm77z+7UCOGPAkO8VvMRAdqQEJ EPez+BA4++SN59JRSWbyknGucw4xebfA0nDjyCVd/uvwqdBfLL8KffYp7E+zSwEu7E enuOGJrfQWWnXOwzU7PzZIOaiivNzz0GWzXYNOoznPLsFOoN/PNrb14ScyLNLKSKMq fi7ujhcsk3BuXf1yNEB/kXPYPU8EMYG/DFBT2BeDRP4OTynkEooVoZCbe/fcfHZ1bC EKjzk4nspDzcA== Subject: [PATCH 5/5] xfs: move xfs_inew_wait call into xfs_dqrele_inode From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org, hch@infradead.org Date: Mon, 31 May 2021 15:41:18 -0700 Message-ID: <162250087868.490412.809961177992047138.stgit@locust> In-Reply-To: <162250085103.490412.4291071116538386696.stgit@locust> References: <162250085103.490412.4291071116538386696.stgit@locust> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move the INEW wait into xfs_dqrele_inode so that we can drop the iter_flags parameter in the next patch. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 5501318b5db0..859ab1279d8d 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -981,6 +981,9 @@ xfs_dqrele_inode( { struct xfs_eofblocks *eofb = priv; + if (xfs_iflags_test(ip, XFS_INEW)) + xfs_inew_wait(ip); + xfs_ilock(ip, XFS_ILOCK_EXCL); if (eofb->eof_flags & XFS_EOFB_DROP_UDQUOT) { xfs_qm_dqrele(ip->i_udquot); @@ -1019,8 +1022,8 @@ xfs_dqrele_all_inodes( if (qflags & XFS_PQUOTA_ACCT) eofb.eof_flags |= XFS_EOFB_DROP_PDQUOT; - return xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, - &eofb, XFS_ICI_DQRELE_NONTAG); + return xfs_inode_walk(mp, 0, xfs_dqrele_inode, &eofb, + XFS_ICI_DQRELE_NONTAG); } /*