From patchwork Fri Dec 3 00:00:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653913 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 C4DB0C433EF for ; Fri, 3 Dec 2021 00:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377734AbhLCAE7 (ORCPT ); Thu, 2 Dec 2021 19:04:59 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58186 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377741AbhLCAEz (ORCPT ); Thu, 2 Dec 2021 19:04:55 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 78644606C62 for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Jv-7d for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkgI-6P for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 01/36] xfs: make last AG grow/shrink perag centric Date: Fri, 3 Dec 2021 11:00:36 +1100 Message-Id: <20211203000111.2800982-2-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e53 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=rNnZobXno7lJzOInF4AA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Because the perag must exist for these operations, look it up as part of the common shrink operations and pass it instead of the mount/agno pair. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 48 ++++++++++++++++-------------------------- fs/xfs/libxfs/xfs_ag.h | 11 +++++----- fs/xfs/xfs_fsops.c | 11 ++++++---- fs/xfs/xfs_ioctl.c | 8 ++++++- 4 files changed, 37 insertions(+), 41 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 1e4ee042d52f..84f8b0f12b50 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -762,11 +762,11 @@ xfs_ag_init_headers( int xfs_ag_shrink_space( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans **tpp, - xfs_agnumber_t agno, xfs_extlen_t delta) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_alloc_arg args = { .tp = *tpp, .mp = mp, @@ -783,14 +783,14 @@ xfs_ag_shrink_space( xfs_agblock_t aglen; int error, err2; - ASSERT(agno == mp->m_sb.sb_agcount - 1); - error = xfs_ialloc_read_agi(mp, *tpp, agno, &agibp); + ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1); + error = xfs_ialloc_read_agi(mp, *tpp, pag->pag_agno, &agibp); if (error) return error; agi = agibp->b_addr; - error = xfs_alloc_read_agf(mp, *tpp, agno, 0, &agfbp); + error = xfs_alloc_read_agf(mp, *tpp, pag->pag_agno, 0, &agfbp); if (error) return error; @@ -802,13 +802,13 @@ xfs_ag_shrink_space( if (delta >= aglen) return -EINVAL; - args.fsbno = XFS_AGB_TO_FSB(mp, agno, aglen - delta); + args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); /* * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. */ - error = xfs_ialloc_check_shrink(*tpp, agno, agibp, aglen - delta); + error = xfs_ialloc_check_shrink(*tpp, pag->pag_agno, agibp, aglen - delta); if (error) return error; @@ -884,9 +884,8 @@ xfs_ag_shrink_space( */ int xfs_ag_extend_space( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, - struct aghdr_init_data *id, xfs_extlen_t len) { struct xfs_buf *bp; @@ -894,23 +893,20 @@ xfs_ag_extend_space( struct xfs_agf *agf; int error; - /* - * Change the agi length. - */ - error = xfs_ialloc_read_agi(mp, tp, id->agno, &bp); + ASSERT(pag->pag_agno == pag->pag_mount->m_sb.sb_agcount - 1); + + error = xfs_ialloc_read_agi(pag->pag_mount, tp, pag->pag_agno, &bp); if (error) return error; agi = bp->b_addr; be32_add_cpu(&agi->agi_length, len); - ASSERT(id->agno == mp->m_sb.sb_agcount - 1 || - be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks); xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH); /* * Change agf length. */ - error = xfs_alloc_read_agf(mp, tp, id->agno, 0, &bp); + error = xfs_alloc_read_agf(pag->pag_mount, tp, pag->pag_agno, 0, &bp); if (error) return error; @@ -925,13 +921,12 @@ xfs_ag_extend_space( * XFS_RMAP_OINFO_SKIP_UPDATE is used here to tell the rmap btree that * this doesn't actually exist in the rmap btree. */ - error = xfs_rmap_free(tp, bp, bp->b_pag, - be32_to_cpu(agf->agf_length) - len, + error = xfs_rmap_free(tp, bp, pag, be32_to_cpu(agf->agf_length) - len, len, &XFS_RMAP_OINFO_SKIP_UPDATE); if (error) return error; - return xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno, + return xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno, be32_to_cpu(agf->agf_length) - len), len, &XFS_RMAP_OINFO_SKIP_UPDATE, XFS_AG_RESV_NONE); @@ -940,34 +935,27 @@ xfs_ag_extend_space( /* Retrieve AG geometry. */ int xfs_ag_get_geometry( - struct xfs_mount *mp, - xfs_agnumber_t agno, + struct xfs_perag *pag, struct xfs_ag_geometry *ageo) { struct xfs_buf *agi_bp; struct xfs_buf *agf_bp; struct xfs_agi *agi; struct xfs_agf *agf; - struct xfs_perag *pag; unsigned int freeblks; int error; - if (agno >= mp->m_sb.sb_agcount) - return -EINVAL; - /* Lock the AG headers. */ - error = xfs_ialloc_read_agi(mp, NULL, agno, &agi_bp); + error = xfs_ialloc_read_agi(pag->pag_mount, NULL, pag->pag_agno, &agi_bp); if (error) return error; - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp); + error = xfs_alloc_read_agf(pag->pag_mount, NULL, pag->pag_agno, 0, &agf_bp); if (error) goto out_agi; - pag = agi_bp->b_pag; - /* Fill out form. */ memset(ageo, 0, sizeof(*ageo)); - ageo->ag_number = agno; + ageo->ag_number = pag->pag_agno; agi = agi_bp->b_addr; ageo->ag_icount = be32_to_cpu(agi->agi_count); diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index e411d51c2589..1132cda9a92f 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -168,11 +168,10 @@ struct aghdr_init_data { }; int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id); -int xfs_ag_shrink_space(struct xfs_mount *mp, struct xfs_trans **tpp, - xfs_agnumber_t agno, xfs_extlen_t delta); -int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp, - struct aghdr_init_data *id, xfs_extlen_t len); -int xfs_ag_get_geometry(struct xfs_mount *mp, xfs_agnumber_t agno, - struct xfs_ag_geometry *ageo); +int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp, + xfs_extlen_t delta); +int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp, + xfs_extlen_t len); +int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); #endif /* __LIBXFS_AG_H */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 33e26690a8c4..7a209fd9eec7 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -40,6 +40,7 @@ xfs_resizefs_init_new_ags( xfs_agnumber_t oagcount, xfs_agnumber_t nagcount, xfs_rfsblock_t delta, + struct xfs_perag *last_pag, bool *lastag_extended) { struct xfs_mount *mp = tp->t_mountp; @@ -72,7 +73,7 @@ xfs_resizefs_init_new_ags( if (delta) { *lastag_extended = true; - error = xfs_ag_extend_space(mp, tp, id, delta); + error = xfs_ag_extend_space(last_pag, tp, delta); } return error; } @@ -95,6 +96,7 @@ xfs_growfs_data_private( xfs_agnumber_t oagcount; struct xfs_trans *tp; struct aghdr_init_data id = {}; + struct xfs_perag *last_pag; nb = in->newblocks; error = xfs_sb_validate_fsb_count(&mp->m_sb, nb); @@ -127,7 +129,6 @@ xfs_growfs_data_private( return -EINVAL; oagcount = mp->m_sb.sb_agcount; - /* allocate the new per-ag structures */ if (nagcount > oagcount) { error = xfs_initialize_perag(mp, nagcount, &nagimax); @@ -144,9 +145,10 @@ xfs_growfs_data_private( if (error) return error; + last_pag = xfs_perag_get(mp, oagcount - 1); if (delta > 0) { error = xfs_resizefs_init_new_ags(tp, &id, oagcount, nagcount, - delta, &lastag_extended); + delta, last_pag, &lastag_extended); } else { static struct ratelimit_state shrink_warning = \ RATELIMIT_STATE_INIT("shrink_warning", 86400 * HZ, 1); @@ -156,8 +158,9 @@ xfs_growfs_data_private( xfs_alert(mp, "EXPERIMENTAL online shrink feature in use. Use at your own risk!"); - error = xfs_ag_shrink_space(mp, &tp, nagcount - 1, -delta); + error = xfs_ag_shrink_space(last_pag, &tp, -delta); } + xfs_perag_put(last_pag); if (error) goto out_trans_cancel; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 174cd8950cb6..5af4da0e6621 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1031,6 +1031,7 @@ xfs_ioc_ag_geometry( struct xfs_mount *mp, void __user *arg) { + struct xfs_perag *pag; struct xfs_ag_geometry ageo; int error; @@ -1041,7 +1042,12 @@ xfs_ioc_ag_geometry( if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved))) return -EINVAL; - error = xfs_ag_get_geometry(mp, ageo.ag_number, &ageo); + pag = xfs_perag_get(mp, ageo.ag_number); + if (!pag) + return -EINVAL; + + error = xfs_ag_get_geometry(pag, &ageo); + xfs_perag_put(pag); if (error) return error; From patchwork Fri Dec 3 00:00:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653889 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 08A50C433EF for ; Fri, 3 Dec 2021 00:01:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377732AbhLCAEs (ORCPT ); Thu, 2 Dec 2021 19:04:48 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37035 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377728AbhLCAEr (ORCPT ); Thu, 2 Dec 2021 19:04:47 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 4AEF1869E03 for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Jx-8W for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkgM-7a for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 02/36] xfs: kill xfs_ialloc_pagi_init() Date: Fri, 3 Dec 2021 11:00:37 +1100 Message-Id: <20211203000111.2800982-3-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e53 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=3lADENaOb3umPYUkYKAA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner This is just a basic wrapper around xfs_ialloc_read_agi(), which can be entirely handled by xfs_ialloc_read_agi() by passing a NULL agibpp.... Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 3 ++- fs/xfs/libxfs/xfs_ialloc.c | 39 ++++++++++++++------------------------ fs/xfs/libxfs/xfs_ialloc.h | 10 ---------- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 84f8b0f12b50..33c382f67e44 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -128,9 +128,10 @@ xfs_initialize_perag_data( if (error) return error; - error = xfs_ialloc_pagi_init(mp, NULL, index); + error = xfs_ialloc_read_agi(mp, NULL, index, NULL); if (error) return error; + pag = xfs_perag_get(mp, index); ifree += pag->pagi_freecount; ialloc += pag->pagi_count; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index b418fe0c0679..e6ce3aed8fca 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1610,7 +1610,7 @@ xfs_dialloc_good_ag( return false; if (!pag->pagi_init) { - error = xfs_ialloc_pagi_init(mp, tp, pag->pag_agno); + error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, NULL); if (error) return false; } @@ -2593,25 +2593,30 @@ xfs_read_agi( return 0; } +/* + * Read in the agi and initialise the per-ag data. If the caller supplies a + * @agibpp, return the locked AGI buffer to them, otherwise release it. + */ int xfs_ialloc_read_agi( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ - struct xfs_buf **bpp) /* allocation group hdr buf */ + struct xfs_buf **agibpp) { + struct xfs_buf *agibp; struct xfs_agi *agi; /* allocation group header */ struct xfs_perag *pag; /* per allocation group data */ int error; trace_xfs_ialloc_read_agi(mp, agno); - error = xfs_read_agi(mp, tp, agno, bpp); + error = xfs_read_agi(mp, tp, agno, &agibp); if (error) return error; - agi = (*bpp)->b_addr; - pag = (*bpp)->b_pag; + agi = agibp->b_addr; + pag = agibp->b_pag; if (!pag->pagi_init) { pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); pag->pagi_count = be32_to_cpu(agi->agi_count); @@ -2624,26 +2629,10 @@ xfs_ialloc_read_agi( */ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || xfs_is_shutdown(mp)); - return 0; -} - -/* - * Read in the agi to initialise the per-ag data in the mount structure - */ -int -xfs_ialloc_pagi_init( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_agnumber_t agno) /* allocation group number */ -{ - struct xfs_buf *bp = NULL; - int error; - - error = xfs_ialloc_read_agi(mp, tp, agno, &bp); - if (error) - return error; - if (bp) - xfs_trans_brelse(tp, bp); + if (agibpp) + *agibpp = agibp; + else + xfs_trans_brelse(tp, agibp); return 0; } diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 8b5c2b709022..f539787c26d8 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -72,16 +72,6 @@ xfs_ialloc_read_agi( xfs_agnumber_t agno, /* allocation group number */ struct xfs_buf **bpp); /* allocation group hdr buf */ -/* - * Read in the allocation group header to initialise the per-ag data - * in the mount structure - */ -int -xfs_ialloc_pagi_init( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno); /* allocation group number */ - /* * Lookup a record by ino in the btree given by cur. */ From patchwork Fri Dec 3 00:00:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653907 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 CAAB5C433EF for ; Fri, 3 Dec 2021 00:01:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377736AbhLCAEx (ORCPT ); Thu, 2 Dec 2021 19:04:53 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:57548 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377747AbhLCAEw (ORCPT ); Thu, 2 Dec 2021 19:04:52 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 2936A6068AF for ; Fri, 3 Dec 2021 11:01:19 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1K0-9g for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkgQ-8a for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 03/36] xfs: pass perag to xfs_ialloc_read_agi() Date: Fri, 3 Dec 2021 11:00:38 +1100 Message-Id: <20211203000111.2800982-4-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4f a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=f84wIbli6KdFIQT5XmUA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner xfs_ialloc_read_agi() initialises the perag if it hasn't been done yet, so it makes sense to pass it the perag rather than pull a reference from the buffer. This allows callers to be per-ag centric rather than passing mount/agno pairs everywhere. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 23 +++++++++++++---------- fs/xfs/libxfs/xfs_ialloc.c | 23 ++++++++++------------- fs/xfs/libxfs/xfs_ialloc.h | 7 ++----- fs/xfs/libxfs/xfs_ialloc_btree.c | 9 ++++----- fs/xfs/scrub/common.c | 2 +- fs/xfs/scrub/fscounters.c | 2 +- fs/xfs/scrub/repair.c | 2 +- 7 files changed, 32 insertions(+), 36 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 33c382f67e44..2683ffcd0d29 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -128,11 +128,13 @@ xfs_initialize_perag_data( if (error) return error; - error = xfs_ialloc_read_agi(mp, NULL, index, NULL); - if (error) + pag = xfs_perag_get(mp, index); + error = xfs_ialloc_read_agi(pag, NULL, NULL); + if (error) { + xfs_perag_put(pag); return error; + } - pag = xfs_perag_get(mp, index); ifree += pag->pagi_freecount; ialloc += pag->pagi_count; bfree += pag->pagf_freeblks; @@ -785,7 +787,7 @@ xfs_ag_shrink_space( int error, err2; ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1); - error = xfs_ialloc_read_agi(mp, *tpp, pag->pag_agno, &agibp); + error = xfs_ialloc_read_agi(pag, *tpp, &agibp); if (error) return error; @@ -817,7 +819,7 @@ xfs_ag_shrink_space( * Disable perag reservations so it doesn't cause the allocation request * to fail. We'll reestablish reservation before we return. */ - error = xfs_ag_resv_free(agibp->b_pag); + error = xfs_ag_resv_free(pag); if (error) return error; @@ -834,7 +836,7 @@ xfs_ag_shrink_space( xfs_trans_bhold(*tpp, agfbp); err2 = xfs_trans_roll(tpp); if (err2) - return err2; + return error; xfs_trans_bjoin(*tpp, agfbp); goto resv_init_out; } @@ -846,7 +848,7 @@ xfs_ag_shrink_space( be32_add_cpu(&agi->agi_length, -delta); be32_add_cpu(&agf->agf_length, -delta); - err2 = xfs_ag_resv_init(agibp->b_pag, *tpp); + err2 = xfs_ag_resv_init(pag, *tpp); if (err2) { be32_add_cpu(&agi->agi_length, delta); be32_add_cpu(&agf->agf_length, delta); @@ -870,8 +872,9 @@ xfs_ag_shrink_space( xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH); xfs_alloc_log_agf(*tpp, agfbp, XFS_AGF_LENGTH); return 0; + resv_init_out: - err2 = xfs_ag_resv_init(agibp->b_pag, *tpp); + err2 = xfs_ag_resv_init(pag, *tpp); if (!err2) return error; resv_err: @@ -896,7 +899,7 @@ xfs_ag_extend_space( ASSERT(pag->pag_agno == pag->pag_mount->m_sb.sb_agcount - 1); - error = xfs_ialloc_read_agi(pag->pag_mount, tp, pag->pag_agno, &bp); + error = xfs_ialloc_read_agi(pag, tp, &bp); if (error) return error; @@ -947,7 +950,7 @@ xfs_ag_get_geometry( int error; /* Lock the AG headers. */ - error = xfs_ialloc_read_agi(pag->pag_mount, NULL, pag->pag_agno, &agi_bp); + error = xfs_ialloc_read_agi(pag, NULL, &agi_bp); if (error) return error; error = xfs_alloc_read_agf(pag->pag_mount, NULL, pag->pag_agno, 0, &agf_bp); diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index e6ce3aed8fca..d53d9808fab8 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1610,7 +1610,7 @@ xfs_dialloc_good_ag( return false; if (!pag->pagi_init) { - error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, NULL); + error = xfs_ialloc_read_agi(pag, tp, NULL); if (error) return false; } @@ -1679,7 +1679,7 @@ xfs_dialloc_try_ag( * Then read in the AGI buffer and recheck with the AGI buffer * lock held. */ - error = xfs_ialloc_read_agi(pag->pag_mount, *tpp, pag->pag_agno, &agbp); + error = xfs_ialloc_read_agi(pag, *tpp, &agbp); if (error) return error; @@ -2169,7 +2169,7 @@ xfs_difree( /* * Get the allocation group header. */ - error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, &agbp); + error = xfs_ialloc_read_agi(pag, tp, &agbp); if (error) { xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.", __func__, error); @@ -2215,7 +2215,7 @@ xfs_imap_lookup( int error; int i; - error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, &agbp); + error = xfs_ialloc_read_agi(pag, tp, &agbp); if (error) { xfs_alert(mp, "%s: xfs_ialloc_read_agi() returned error %d, agno %d", @@ -2599,24 +2599,21 @@ xfs_read_agi( */ int xfs_ialloc_read_agi( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ + struct xfs_perag *pag, + struct xfs_trans *tp, struct xfs_buf **agibpp) { struct xfs_buf *agibp; - struct xfs_agi *agi; /* allocation group header */ - struct xfs_perag *pag; /* per allocation group data */ + struct xfs_agi *agi; int error; - trace_xfs_ialloc_read_agi(mp, agno); + trace_xfs_ialloc_read_agi(pag->pag_mount, pag->pag_agno); - error = xfs_read_agi(mp, tp, agno, &agibp); + error = xfs_read_agi(pag->pag_mount, tp, pag->pag_agno, &agibp); if (error) return error; agi = agibp->b_addr; - pag = agibp->b_pag; if (!pag->pagi_init) { pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); pag->pagi_count = be32_to_cpu(agi->agi_count); @@ -2628,7 +2625,7 @@ xfs_ialloc_read_agi( * we are in the middle of a forced shutdown. */ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || - xfs_is_shutdown(mp)); + xfs_is_shutdown(pag->pag_mount)); if (agibpp) *agibpp = agibp; else diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index f539787c26d8..33cbae4c8ee9 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -66,11 +66,8 @@ xfs_ialloc_log_agi( * Read in the allocation group header (inode allocation section) */ int /* error */ -xfs_ialloc_read_agi( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - struct xfs_buf **bpp); /* allocation group hdr buf */ +xfs_ialloc_read_agi(struct xfs_perag *pag, struct xfs_trans *tp, + struct xfs_buf **agibpp); /* * Lookup a record by ino in the btree given by cur. diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index b2ad2fdc40f5..aa4367a0a0de 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -722,7 +722,7 @@ xfs_inobt_cur( ASSERT(*agi_bpp == NULL); ASSERT(*curpp == NULL); - error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, agi_bpp); + error = xfs_ialloc_read_agi(pag, tp, agi_bpp); if (error) return error; @@ -757,16 +757,15 @@ xfs_inobt_count_blocks( /* Read finobt block count from AGI header. */ static int xfs_finobt_read_blocks( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_extlen_t *tree_blocks) { struct xfs_buf *agbp; struct xfs_agi *agi; int error; - error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, &agbp); + error = xfs_ialloc_read_agi(pag, tp, &agbp); if (error) return error; @@ -794,7 +793,7 @@ xfs_finobt_calc_reserves( return 0; if (xfs_has_inobtcounts(mp)) - error = xfs_finobt_read_blocks(mp, tp, pag, &tree_len); + error = xfs_finobt_read_blocks(pag, tp, &tree_len); else error = xfs_inobt_count_blocks(mp, tp, pag, XFS_BTNUM_FINO, &tree_len); diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index bf1f3607d0b6..068489030bbb 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -414,7 +414,7 @@ xchk_ag_read_headers( if (!sa->pag) return -ENOENT; - error = xfs_ialloc_read_agi(mp, sc->tp, agno, &sa->agi_bp); + error = xfs_ialloc_read_agi(sa->pag, sc->tp, &sa->agi_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI)) return error; diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 48a6cbdf95d0..bd06a184c81c 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -78,7 +78,7 @@ xchk_fscount_warmup( continue; /* Lock both AG headers. */ - error = xfs_ialloc_read_agi(mp, sc->tp, agno, &agi_bp); + error = xfs_ialloc_read_agi(pag, sc->tp, &agi_bp); if (error) break; error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &agf_bp); diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 8f3cba14ada3..333ee7d7b753 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -198,7 +198,7 @@ xrep_calc_ag_resblks( icount = pag->pagi_count; } else { /* Try to get the actual counters from disk. */ - error = xfs_ialloc_read_agi(mp, NULL, sm->sm_agno, &bp); + error = xfs_ialloc_read_agi(pag, NULL, &bp); if (!error) { icount = pag->pagi_count; xfs_buf_relse(bp); From patchwork Fri Dec 3 00:00:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653915 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 664AAC433FE for ; Fri, 3 Dec 2021 00:01:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377777AbhLCAFA (ORCPT ); Thu, 2 Dec 2021 19:05:00 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58186 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349853AbhLCAE6 (ORCPT ); Thu, 2 Dec 2021 19:04:58 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 3AFDA6068D0 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1K2-Al for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkgW-9h for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 04/36] xfs: kill xfs_alloc_pagf_init() Date: Fri, 3 Dec 2021 11:00:39 +1100 Message-Id: <20211203000111.2800982-5-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=bQPFrWnIYC81Y4yJAFYA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Trivial wrapper around xfs_alloc_read_agf(), can be easily replaced by passing a NULL agfbp to xfs_alloc_read_agf(). Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 2 +- fs/xfs/libxfs/xfs_ag_resv.c | 2 +- fs/xfs/libxfs/xfs_alloc.c | 37 ++++++++++++------------------------- fs/xfs/libxfs/xfs_alloc.h | 10 ---------- fs/xfs/libxfs/xfs_bmap.c | 3 ++- fs/xfs/libxfs/xfs_ialloc.c | 2 +- fs/xfs/xfs_filestream.c | 4 ++-- 7 files changed, 19 insertions(+), 41 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 2683ffcd0d29..a782b9e584e4 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -124,7 +124,7 @@ xfs_initialize_perag_data( * all the information we need and populates the * per-ag structures for us. */ - error = xfs_alloc_pagf_init(mp, NULL, index, 0); + error = xfs_alloc_read_agf(mp, NULL, index, 0, NULL); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index fe94058d4e9e..ce28bf8f72dc 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -322,7 +322,7 @@ xfs_ag_resv_init( * address. */ if (has_resv) { - error2 = xfs_alloc_pagf_init(mp, tp, pag->pag_agno, 0); + error2 = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, NULL); if (error2) return error2; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 353e53b892e6..faa8f7a1ecf8 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2849,25 +2849,6 @@ xfs_alloc_log_agf( xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); } -/* - * Interface for inode allocation to force the pag data to be initialized. - */ -int /* error */ -xfs_alloc_pagf_init( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags) /* XFS_ALLOC_FLAGS_... */ -{ - struct xfs_buf *bp; - int error; - - error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp); - if (!error) - xfs_trans_brelse(tp, bp); - return error; -} - /* * Put the block on the freelist for the allocation group. */ @@ -3077,7 +3058,9 @@ xfs_read_agf( } /* - * Read in the allocation group header (free/alloc section). + * Read in the allocation group header (free/alloc section) and initialise the + * perag structure if necessary. If the caller provides @agfbpp, then return the + * locked buffer to the caller, otherwise free it. */ int /* error */ xfs_alloc_read_agf( @@ -3085,8 +3068,9 @@ xfs_alloc_read_agf( struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags, /* XFS_ALLOC_FLAG_... */ - struct xfs_buf **bpp) /* buffer for the ag freelist header */ + struct xfs_buf **agfbpp) { + struct xfs_buf *agfbp; struct xfs_agf *agf; /* ag freelist header */ struct xfs_perag *pag; /* per allocation group data */ int error; @@ -3100,13 +3084,12 @@ xfs_alloc_read_agf( ASSERT(agno != NULLAGNUMBER); error = xfs_read_agf(mp, tp, agno, (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, - bpp); + &agfbp); if (error) return error; - ASSERT(!(*bpp)->b_error); - agf = (*bpp)->b_addr; - pag = (*bpp)->b_pag; + agf = agfbp->b_addr; + pag = agfbp->b_pag; if (!pag->pagf_init) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); @@ -3147,6 +3130,10 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); } #endif + if (agfbpp) + *agfbpp = agfbp; + else + xfs_trans_brelse(tp, agfbp); return 0; } diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 1c14a0b1abea..76dd3b8b6971 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -124,16 +124,6 @@ xfs_alloc_log_agf( struct xfs_buf *bp, /* buffer for a.g. freelist header */ int fields);/* mask of fields to be logged (XFS_AGF_...) */ -/* - * Interface for inode allocation to force the pag data to be initialized. - */ -int /* error */ -xfs_alloc_pagf_init( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags); /* XFS_ALLOC_FLAGS_... */ - /* * Put the block on the freelist for the allocation group. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4dccd4d90622..8924b3749e6a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3187,7 +3187,8 @@ xfs_bmap_longest_free_extent( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK); + error = xfs_alloc_read_agf(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK, + NULL); if (error) { /* Couldn't lock the AGF, so skip this AG. */ if (error == -EAGAIN) { diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index d53d9808fab8..22edd49cfe81 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1621,7 +1621,7 @@ xfs_dialloc_good_ag( return false; if (!pag->pagf_init) { - error = xfs_alloc_pagf_init(mp, tp, pag->pag_agno, flags); + error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, flags, NULL); if (error) return false; } diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 6a3ce0f6dc9e..e82185aa13f8 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -126,7 +126,7 @@ xfs_filestream_pick_ag( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - err = xfs_alloc_pagf_init(mp, NULL, ag, trylock); + err = xfs_alloc_read_agf(mp, NULL, ag, trylock, NULL); if (err) { xfs_perag_put(pag); if (err != -EAGAIN) @@ -180,7 +180,7 @@ xfs_filestream_pick_ag( if (ag != startag) continue; - /* Allow sleeping in xfs_alloc_pagf_init() on the 2nd pass. */ + /* Allow sleeping in xfs_alloc_read_agf() on the 2nd pass. */ if (trylock != 0) { trylock = 0; continue; From patchwork Fri Dec 3 00:00:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653859 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 1A5D7C433FE for ; Fri, 3 Dec 2021 00:01:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349505AbhLCAEl (ORCPT ); Thu, 2 Dec 2021 19:04:41 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35151 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243809AbhLCAEk (ORCPT ); Thu, 2 Dec 2021 19:04:40 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 07852869D23 for ; Fri, 3 Dec 2021 11:01:15 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1K9-CM for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkgb-Am for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 05/36] xfs: pass perag to xfs_alloc_read_agf() Date: Fri, 3 Dec 2021 11:00:40 +1100 Message-Id: <20211203000111.2800982-6-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=DT-L6bsfT1kNlZdnF-gA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner xfs_alloc_read_agf() initialises the perag if it hasn't been done yet, so it makes sense to pass it the perag rather than pull a reference from the buffer. This allows callers to be per-ag centric rather than passing mount/agno pairs everywhere. Signed-off-by: Dave Chinner Reported-by: kernel test robot Reported-by: kernel test robot Reported-by: kernel test robot --- fs/xfs/libxfs/xfs_ag.c | 19 +++++++-------- fs/xfs/libxfs/xfs_ag_resv.c | 2 +- fs/xfs/libxfs/xfs_alloc.c | 30 ++++++++++------------- fs/xfs/libxfs/xfs_alloc.h | 13 ++-------- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 2 +- fs/xfs/libxfs/xfs_refcount.c | 6 ++--- fs/xfs/libxfs/xfs_refcount_btree.c | 2 +- fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- fs/xfs/scrub/agheader_repair.c | 6 ++--- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/common.c | 2 +- fs/xfs/scrub/fscounters.c | 2 +- fs/xfs/scrub/repair.c | 5 ++-- fs/xfs/xfs_discard.c | 2 +- fs/xfs/xfs_extfree_item.c | 6 ++++- fs/xfs/xfs_filestream.c | 2 +- fs/xfs/xfs_fsmap.c | 3 +-- fs/xfs/xfs_reflink.c | 38 +++++++++++++++++------------- fs/xfs/xfs_reflink.h | 3 --- 20 files changed, 68 insertions(+), 81 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index a782b9e584e4..a357ac6bc4ad 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -120,16 +120,13 @@ xfs_initialize_perag_data( for (index = 0; index < agcount; index++) { /* - * read the agf, then the agi. This gets us - * all the information we need and populates the - * per-ag structures for us. + * Read the AGF and AGI buffers to populate the per-ag + * structures for us. */ - error = xfs_alloc_read_agf(mp, NULL, index, 0, NULL); - if (error) - return error; - pag = xfs_perag_get(mp, index); - error = xfs_ialloc_read_agi(pag, NULL, NULL); + error = xfs_alloc_read_agf(pag, NULL, 0, NULL); + if (!error) + error = xfs_ialloc_read_agi(pag, NULL, NULL); if (error) { xfs_perag_put(pag); return error; @@ -793,7 +790,7 @@ xfs_ag_shrink_space( agi = agibp->b_addr; - error = xfs_alloc_read_agf(mp, *tpp, pag->pag_agno, 0, &agfbp); + error = xfs_alloc_read_agf(pag, *tpp, 0, &agfbp); if (error) return error; @@ -910,7 +907,7 @@ xfs_ag_extend_space( /* * Change agf length. */ - error = xfs_alloc_read_agf(pag->pag_mount, tp, pag->pag_agno, 0, &bp); + error = xfs_alloc_read_agf(pag, tp, 0, &bp); if (error) return error; @@ -953,7 +950,7 @@ xfs_ag_get_geometry( error = xfs_ialloc_read_agi(pag, NULL, &agi_bp); if (error) return error; - error = xfs_alloc_read_agf(pag->pag_mount, NULL, pag->pag_agno, 0, &agf_bp); + error = xfs_alloc_read_agf(pag, NULL, 0, &agf_bp); if (error) goto out_agi; diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index ce28bf8f72dc..5af123d13a63 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -322,7 +322,7 @@ xfs_ag_resv_init( * address. */ if (has_resv) { - error2 = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, NULL); + error2 = xfs_alloc_read_agf(pag, tp, 0, NULL); if (error2) return error2; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index faa8f7a1ecf8..a8f032e49fcd 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2591,7 +2591,7 @@ xfs_alloc_fix_freelist( ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ if (error == -EAGAIN) @@ -2621,7 +2621,7 @@ xfs_alloc_fix_freelist( * Can fail if we're not blocking on locks, and it's held. */ if (!agbp) { - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ if (error == -EAGAIN) @@ -3062,34 +3062,30 @@ xfs_read_agf( * perag structure if necessary. If the caller provides @agfbpp, then return the * locked buffer to the caller, otherwise free it. */ -int /* error */ +int xfs_alloc_read_agf( - struct xfs_mount *mp, /* mount point structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags, /* XFS_ALLOC_FLAG_... */ + struct xfs_perag *pag, + struct xfs_trans *tp, + int flags, struct xfs_buf **agfbpp) { struct xfs_buf *agfbp; - struct xfs_agf *agf; /* ag freelist header */ - struct xfs_perag *pag; /* per allocation group data */ + struct xfs_agf *agf; int error; int allocbt_blks; - trace_xfs_alloc_read_agf(mp, agno); + trace_xfs_alloc_read_agf(pag->pag_mount, pag->pag_agno); /* We don't support trylock when freeing. */ ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) != (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)); - ASSERT(agno != NULLAGNUMBER); - error = xfs_read_agf(mp, tp, agno, + error = xfs_read_agf(pag->pag_mount, tp, pag->pag_agno, (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, &agfbp); if (error) return error; agf = agfbp->b_addr; - pag = agfbp->b_pag; if (!pag->pagf_init) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); @@ -3103,7 +3099,7 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); pag->pagf_init = 1; - pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); + pag->pagf_agflreset = xfs_agfl_needs_reset(pag->pag_mount, agf); /* * Update the in-core allocbt counter. Filter out the rmapbt @@ -3113,13 +3109,13 @@ xfs_alloc_read_agf( * counter only tracks non-root blocks. */ allocbt_blks = pag->pagf_btreeblks; - if (xfs_has_rmapbt(mp)) + if (xfs_has_rmapbt(pag->pag_mount)) allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1; if (allocbt_blks > 0) - atomic64_add(allocbt_blks, &mp->m_allocbt_blks); + atomic64_add(allocbt_blks, &pag->pag_mount->m_allocbt_blks); } #ifdef DEBUG - else if (!xfs_is_shutdown(mp)) { + else if (!xfs_is_shutdown(pag->pag_mount)) { ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks)); ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks)); ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount)); diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 76dd3b8b6971..bdf7c1a75057 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -135,17 +135,6 @@ xfs_alloc_put_freelist( xfs_agblock_t bno, /* block being freed */ int btreeblk); /* owner was a AGF btree */ -/* - * Read in the allocation group header (free/alloc section). - */ -int /* error */ -xfs_alloc_read_agf( - struct xfs_mount *mp, /* mount point structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags, /* XFS_ALLOC_FLAG_... */ - struct xfs_buf **bpp); /* buffer for the ag freelist header */ - /* * Allocate an extent (variable-size). */ @@ -199,6 +188,8 @@ xfs_alloc_get_rec( int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); +int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, + struct xfs_buf **agfbpp); int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, struct xfs_buf **bpp); int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8924b3749e6a..ec856466ed40 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3187,7 +3187,7 @@ xfs_bmap_longest_free_extent( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK, + error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); if (error) { /* Couldn't lock the AGF, so skip this AG. */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 22edd49cfe81..f2d02231a9e4 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1621,7 +1621,7 @@ xfs_dialloc_good_ag( return false; if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, flags, NULL); + error = xfs_alloc_read_agf(pag, tp, flags, NULL); if (error) return false; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 327ba25e9e17..e90a02391906 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1173,8 +1173,8 @@ xfs_refcount_finish_one( *pcur = NULL; } if (rcur == NULL) { - error = xfs_alloc_read_agf(tp->t_mountp, tp, pag->pag_agno, - XFS_ALLOC_FLAG_FREEING, &agbp); + error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_FREEING, + &agbp); if (error) goto out_drop; @@ -1706,7 +1706,7 @@ xfs_refcount_recover_cow_leftovers( if (error) return error; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) goto out_trans; cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index d14c1720b0fb..1063234df34a 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -493,7 +493,7 @@ xfs_refcountbt_calc_reserves( if (!xfs_has_reflink(mp)) return 0; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 69e104d0277f..d6d45992fe7b 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -652,7 +652,7 @@ xfs_rmapbt_calc_reserves( if (!xfs_has_rmapbt(mp)) return 0; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index d7bfed52f4cd..24cc8c0a9d80 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -654,8 +654,7 @@ xrep_agfl( * nothing wrong with the AGF, but all the AG header repair functions * have this chicken-and-egg problem. */ - error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.pag->pag_agno, 0, - &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; @@ -730,8 +729,7 @@ xrep_agi_find_btrees( int error; /* Read the AGF. */ - error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.pag->pag_agno, 0, - &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index a4cbbc346f60..570f0076ef2e 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -556,7 +556,7 @@ xchk_bmap_check_ag_rmaps( struct xfs_buf *agf; int error; - error = xfs_alloc_read_agf(sc->mp, sc->tp, pag->pag_agno, 0, &agf); + error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf); if (error) return error; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 068489030bbb..73f3d729d7f5 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -418,7 +418,7 @@ xchk_ag_read_headers( if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI)) return error; - error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &sa->agf_bp); + error = xfs_alloc_read_agf(sa->pag, sc->tp, 0, &sa->agf_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF)) return error; diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index bd06a184c81c..6a6f8fe7f87c 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -81,7 +81,7 @@ xchk_fscount_warmup( error = xfs_ialloc_read_agi(pag, sc->tp, &agi_bp); if (error) break; - error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &agf_bp); + error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf_bp); if (error) break; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 333ee7d7b753..06b41321f425 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -206,7 +206,7 @@ xrep_calc_ag_resblks( } /* Now grab the block counters from the AGF. */ - error = xfs_alloc_read_agf(mp, NULL, sm->sm_agno, 0, &bp); + error = xfs_alloc_read_agf(pag, NULL, 0, &bp); if (error) { aglen = xfs_ag_block_count(mp, sm->sm_agno); freelen = aglen; @@ -542,6 +542,7 @@ xrep_reap_block( agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); + ASSERT(agno == sc->sa.pag->pag_agno); /* * If we are repairing per-inode metadata, we need to read in the AGF @@ -549,7 +550,7 @@ xrep_reap_block( * the AGF buffer that the setup functions already grabbed. */ if (sc->ip) { - error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0, &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; } else { diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 0191de8ce9ce..ccec28c914cd 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -45,7 +45,7 @@ xfs_trim_extents( */ xfs_log_force(mp, XFS_LOG_SYNC); - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, NULL, 0, &agbp); if (error) goto out_put_perag; agf = agbp->b_addr; diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 47ef9c9c5c17..4358ec6e2309 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -11,6 +11,7 @@ #include "xfs_bit.h" #include "xfs_shared.h" #include "xfs_mount.h" +#include "xfs_ag.h" #include "xfs_defer.h" #include "xfs_trans.h" #include "xfs_trans_priv.h" @@ -541,6 +542,7 @@ xfs_agfl_free_finish_item( xfs_agnumber_t agno; xfs_agblock_t agbno; uint next_extent; + struct xfs_perag *pag; free = container_of(item, struct xfs_extent_free_item, xefi_list); ASSERT(free->xefi_blockcount == 1); @@ -550,9 +552,11 @@ xfs_agfl_free_finish_item( trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount); - error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + pag = xfs_perag_get(mp, agno); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (!error) error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo); + xfs_perag_put(pag); /* * Mark the transaction dirty, even on error. This ensures the diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index e82185aa13f8..fe7a809e230c 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -126,7 +126,7 @@ xfs_filestream_pick_ag( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - err = xfs_alloc_read_agf(mp, NULL, ag, trylock, NULL); + err = xfs_alloc_read_agf(pag, NULL, trylock, NULL); if (err) { xfs_perag_put(pag); if (err != -EAGAIN) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 48287caad28b..9424b5a22d5e 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -642,8 +642,7 @@ __xfs_getfsmap_datadev( info->agf_bp = NULL; } - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, - &info->agf_bp); + error = xfs_alloc_read_agf(pag, tp, 0, &info->agf_bp); if (error) break; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index cb0edb1d68ef..d8281b002dff 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -127,9 +127,8 @@ */ int xfs_reflink_find_shared( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, @@ -140,11 +139,11 @@ xfs_reflink_find_shared( struct xfs_btree_cur *cur; int error; - error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; - cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agbp->b_pag); + cur = xfs_refcountbt_init_cursor(pag->pag_mount, tp, agbp, pag); error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen, find_end_of_shared); @@ -171,7 +170,8 @@ xfs_reflink_trim_around_shared( struct xfs_bmbt_irec *irec, bool *shared) { - xfs_agnumber_t agno; + struct xfs_mount *mp = ip->i_mount; + struct xfs_perag *pag; xfs_agblock_t agbno; xfs_extlen_t aglen; xfs_agblock_t fbno; @@ -186,12 +186,13 @@ xfs_reflink_trim_around_shared( trace_xfs_reflink_trim_around_shared(ip, irec); - agno = XFS_FSB_TO_AGNO(ip->i_mount, irec->br_startblock); - agbno = XFS_FSB_TO_AGBNO(ip->i_mount, irec->br_startblock); + pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, irec->br_startblock)); + agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock); aglen = irec->br_blockcount; - error = xfs_reflink_find_shared(ip->i_mount, NULL, agno, agbno, - aglen, &fbno, &flen, true); + error = xfs_reflink_find_shared(pag, NULL, agbno, aglen, &fbno, &flen, + true); + xfs_perag_put(pag); if (error) return error; @@ -1385,11 +1386,6 @@ xfs_reflink_inode_has_shared_extents( struct xfs_bmbt_irec got; struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_extlen_t aglen; - xfs_agblock_t rbno; - xfs_extlen_t rlen; struct xfs_iext_cursor icur; bool found; int error; @@ -1402,17 +1398,25 @@ xfs_reflink_inode_has_shared_extents( *has_shared = false; found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got); while (found) { + struct xfs_perag *pag; + xfs_agblock_t agbno; + xfs_extlen_t aglen; + xfs_agblock_t rbno; + xfs_extlen_t rlen; + if (isnullstartblock(got.br_startblock) || got.br_state != XFS_EXT_NORM) goto next; - agno = XFS_FSB_TO_AGNO(mp, got.br_startblock); + + pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, got.br_startblock)); agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock); aglen = got.br_blockcount; - - error = xfs_reflink_find_shared(mp, tp, agno, agbno, aglen, + error = xfs_reflink_find_shared(pag, tp, agbno, aglen, &rbno, &rlen, false); + xfs_perag_put(pag); if (error) return error; + /* Is there still a shared block here? */ if (rbno != NULLAGBLOCK) { *has_shared = true; diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index bea65f2fe657..65c5dfe17ecf 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -16,9 +16,6 @@ static inline bool xfs_is_cow_inode(struct xfs_inode *ip) return xfs_is_reflink_inode(ip) || xfs_is_always_cow_inode(ip); } -extern int xfs_reflink_find_shared(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen, - xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_maximal); extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip, struct xfs_bmbt_irec *irec, bool *shared); int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, From patchwork Fri Dec 3 00:00:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653887 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 F163FC433F5 for ; Fri, 3 Dec 2021 00:01:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377733AbhLCAEr (ORCPT ); Thu, 2 Dec 2021 19:04:47 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:55940 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377726AbhLCAEq (ORCPT ); Thu, 2 Dec 2021 19:04:46 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 8C4ED606AD5 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KC-Dw for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkgg-CO for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 06/36] xfs: pass perag to xfs_read_agi Date: Fri, 3 Dec 2021 11:00:41 +1100 Message-Id: <20211203000111.2800982-7-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=Ru3meIeGREELRzOxrq8A:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We have the perag in most palces we call xfs_read_agi, so pass the perag instead of a mount/agno pair. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc.c | 21 ++++++++++---------- fs/xfs/libxfs/xfs_ialloc.h | 10 +++------- fs/xfs/xfs_inode.c | 14 +++++++------ fs/xfs/xfs_log_recover.c | 40 +++++++++++++++++++------------------- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index f2d02231a9e4..b4fef0de2bb8 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2571,25 +2571,24 @@ const struct xfs_buf_ops xfs_agi_buf_ops = { */ int xfs_read_agi( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - struct xfs_buf **bpp) /* allocation group hdr buf */ + struct xfs_perag *pag, + struct xfs_trans *tp, + struct xfs_buf **agibpp) { + struct xfs_mount *mp = pag->pag_mount; int error; - trace_xfs_read_agi(mp, agno); + trace_xfs_read_agi(pag->pag_mount, pag->pag_agno); - ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, - XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops); + XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGI_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), 0, agibpp, &xfs_agi_buf_ops); if (error) return error; if (tp) - xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_AGI_BUF); + xfs_trans_buf_set_type(tp, *agibpp, XFS_BLFT_AGI_BUF); - xfs_buf_set_ref(*bpp, XFS_AGI_REF); + xfs_buf_set_ref(*agibpp, XFS_AGI_REF); return 0; } @@ -2609,7 +2608,7 @@ xfs_ialloc_read_agi( trace_xfs_ialloc_read_agi(pag->pag_mount, pag->pag_agno); - error = xfs_read_agi(pag->pag_mount, tp, pag->pag_agno, &agibp); + error = xfs_read_agi(pag, tp, &agibp); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 33cbae4c8ee9..c3907c268775 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -62,11 +62,9 @@ xfs_ialloc_log_agi( struct xfs_buf *bp, /* allocation group header buffer */ int fields); /* bitmask of fields to log */ -/* - * Read in the allocation group header (inode allocation section) - */ -int /* error */ -xfs_ialloc_read_agi(struct xfs_perag *pag, struct xfs_trans *tp, +int xfs_read_agi(struct xfs_perag *pag, struct xfs_trans *tp, + struct xfs_buf **agibpp); +int xfs_ialloc_read_agi(struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf **agibpp); /* @@ -89,8 +87,6 @@ int xfs_ialloc_inode_init(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_agblock_t length, unsigned int gen); -int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_agnumber_t agno, struct xfs_buf **bpp); union xfs_btree_rec; void xfs_inobt_btrec_to_irec(struct xfs_mount *mp, diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 64b9bf334806..c07043393643 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2169,7 +2169,7 @@ xfs_iunlink( pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); /* Get the agi buffer first. It ensures lock ordering on the list. */ - error = xfs_read_agi(mp, tp, pag->pag_agno, &agibp); + error = xfs_read_agi(pag, tp, &agibp); if (error) goto out; agi = agibp->b_addr; @@ -2354,7 +2354,7 @@ xfs_iunlink_remove( trace_xfs_iunlink_remove(ip); /* Get the agi buffer first. It ensures lock ordering on the list. */ - error = xfs_read_agi(mp, tp, pag->pag_agno, &agibp); + error = xfs_read_agi(pag, tp, &agibp); if (error) return error; agi = agibp->b_addr; @@ -3266,11 +3266,13 @@ xfs_rename( if (inodes[i] == wip || (inodes[i] == target_ip && (VFS_I(target_ip)->i_nlink == 1 || src_is_directory))) { - struct xfs_buf *bp; - xfs_agnumber_t agno; + struct xfs_perag *pag; + struct xfs_buf *bp; - agno = XFS_INO_TO_AGNO(mp, inodes[i]->i_ino); - error = xfs_read_agi(mp, tp, agno, &bp); + pag = xfs_perag_get(mp, + XFS_INO_TO_AGNO(mp, inodes[i]->i_ino)); + error = xfs_read_agi(pag, tp, &bp); + xfs_perag_put(pag); if (error) goto out_trans_cancel; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 53366cc0bc9e..08ea47ad3d9d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2650,21 +2650,21 @@ xlog_recover_cancel_intents( */ STATIC void xlog_recover_clear_agi_bucket( - xfs_mount_t *mp, - xfs_agnumber_t agno, - int bucket) + struct xfs_perag *pag, + int bucket) { - xfs_trans_t *tp; - xfs_agi_t *agi; - struct xfs_buf *agibp; - int offset; - int error; + struct xfs_mount *mp = pag->pag_mount; + struct xfs_trans *tp; + struct xfs_agi *agi; + struct xfs_buf *agibp; + int offset; + int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_clearagi, 0, 0, 0, &tp); if (error) goto out_error; - error = xfs_read_agi(mp, tp, agno, &agibp); + error = xfs_read_agi(pag, tp, &agibp); if (error) goto out_abort; @@ -2683,14 +2683,14 @@ xlog_recover_clear_agi_bucket( out_abort: xfs_trans_cancel(tp); out_error: - xfs_warn(mp, "%s: failed to clear agi %d. Continuing.", __func__, agno); + xfs_warn(mp, "%s: failed to clear agi %d. Continuing.", __func__, + pag->pag_agno); return; } STATIC xfs_agino_t xlog_recover_process_one_iunlink( - struct xfs_mount *mp, - xfs_agnumber_t agno, + struct xfs_perag *pag, xfs_agino_t agino, int bucket) { @@ -2700,15 +2700,15 @@ xlog_recover_process_one_iunlink( xfs_ino_t ino; int error; - ino = XFS_AGINO_TO_INO(mp, agno, agino); - error = xfs_iget(mp, NULL, ino, 0, 0, &ip); + ino = XFS_AGINO_TO_INO(pag->pag_mount, pag->pag_agno, agino); + error = xfs_iget(pag->pag_mount, NULL, ino, 0, 0, &ip); if (error) goto fail; /* * Get the on disk inode to find the next inode in the bucket. */ - error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &ibp); + error = xfs_imap_to_bp(pag->pag_mount, NULL, &ip->i_imap, &ibp); if (error) goto fail_iput; dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset); @@ -2735,7 +2735,7 @@ xlog_recover_process_one_iunlink( * Call xlog_recover_clear_agi_bucket() to perform a transaction to * clear the inode pointer in the bucket. */ - xlog_recover_clear_agi_bucket(mp, agno, bucket); + xlog_recover_clear_agi_bucket(pag, bucket); return NULLAGINO; } @@ -2776,7 +2776,7 @@ xlog_recover_process_iunlinks( int error; for_each_perag(mp, agno, pag) { - error = xfs_read_agi(mp, NULL, pag->pag_agno, &agibp); + error = xfs_read_agi(pag, NULL, &agibp); if (error) { /* * AGI is b0rked. Don't process it. @@ -2801,8 +2801,8 @@ xlog_recover_process_iunlinks( for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) { agino = be32_to_cpu(agi->agi_unlinked[bucket]); while (agino != NULLAGINO) { - agino = xlog_recover_process_one_iunlink(mp, - pag->pag_agno, agino, bucket); + agino = xlog_recover_process_one_iunlink(pag, + agino, bucket); cond_resched(); } } @@ -3546,7 +3546,7 @@ xlog_recover_check_summary( xfs_buf_relse(agfbp); } - error = xfs_read_agi(mp, NULL, pag->pag_agno, &agibp); + error = xfs_read_agi(pag, NULL, &agibp); if (error) { xfs_alert(mp, "%s agi read failed agno %d error %d", __func__, pag->pag_agno, error); From patchwork Fri Dec 3 00:00:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653917 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 B62B2C43219 for ; Fri, 3 Dec 2021 00:01:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349853AbhLCAFA (ORCPT ); Thu, 2 Dec 2021 19:05:00 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58518 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377752AbhLCAE5 (ORCPT ); Thu, 2 Dec 2021 19:04:57 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id D509F606CCF for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KF-Fe for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkgl-E2 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 07/36] xfs: pass perag to xfs_read_agf Date: Fri, 3 Dec 2021 11:00:42 +1100 Message-Id: <20211203000111.2800982-8-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e53 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=kP1XSlkOuOZPmVMylvYA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We have the perag in most places we call xfs_read_agf, so pass the perag instead of a mount/agno pair. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 26 ++++++++++++-------------- fs/xfs/libxfs/xfs_alloc.h | 4 ++-- fs/xfs/xfs_log_recover.c | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index a8f032e49fcd..d1a76b7f33b7 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3033,27 +3033,25 @@ const struct xfs_buf_ops xfs_agf_buf_ops = { /* * Read in the allocation group header (free/alloc section). */ -int /* error */ +int xfs_read_agf( - struct xfs_mount *mp, /* mount point structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags, /* XFS_BUF_ */ - struct xfs_buf **bpp) /* buffer for the ag freelist header */ + struct xfs_perag *pag, + struct xfs_trans *tp, + int flags, + struct xfs_buf **agfbpp) { - int error; + struct xfs_mount *mp = pag->pag_mount; + int error; - trace_xfs_read_agf(mp, agno); + trace_xfs_read_agf(pag->pag_mount, pag->pag_agno); - ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, - XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops); + XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGF_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), flags, agfbpp, &xfs_agf_buf_ops); if (error) return error; - ASSERT(!(*bpp)->b_error); - xfs_buf_set_ref(*bpp, XFS_AGF_REF); + xfs_buf_set_ref(*agfbpp, XFS_AGF_REF); return 0; } @@ -3079,7 +3077,7 @@ xfs_alloc_read_agf( /* We don't support trylock when freeing. */ ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) != (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)); - error = xfs_read_agf(pag->pag_mount, tp, pag->pag_agno, + error = xfs_read_agf(pag, tp, (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, &agfbp); if (error) diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index bdf7c1a75057..5efd52b3dd59 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -186,8 +186,8 @@ xfs_alloc_get_rec( xfs_extlen_t *len, /* output: length of extent */ int *stat); /* output: success/failure */ -int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); +int xfs_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, + struct xfs_buf **agfbpp); int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, struct xfs_buf **agfbpp); int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp, diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 08ea47ad3d9d..74f399ceddd9 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3534,7 +3534,7 @@ xlog_recover_check_summary( itotal = 0LL; ifree = 0LL; for_each_perag(mp, agno, pag) { - error = xfs_read_agf(mp, NULL, pag->pag_agno, 0, &agfbp); + error = xfs_read_agf(pag, NULL, 0, &agfbp); if (error) { xfs_alert(mp, "%s agf read failed agno %d error %d", __func__, pag->pag_agno, error); From patchwork Fri Dec 3 00:00:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653929 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 95B0BC433EF for ; Fri, 3 Dec 2021 00:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377754AbhLCAFE (ORCPT ); Thu, 2 Dec 2021 19:05:04 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:60302 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349987AbhLCAFE (ORCPT ); Thu, 2 Dec 2021 19:05:04 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id DA6786064A7 for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KH-Gx for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkgq-Fk for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 08/36] xfs: pass perag to xfs_alloc_get_freelist Date: Fri, 3 Dec 2021 11:00:43 +1100 Message-Id: <20211203000111.2800982-9-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=Hm9j3Q2J-9EBiYWz0l0A:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner It's available in all callers, so pass it in so that the perag can be passed further down the stack. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 8 ++++---- fs/xfs/libxfs/xfs_alloc.h | 13 ++----------- fs/xfs/libxfs/xfs_alloc_btree.c | 6 +++--- fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- fs/xfs/scrub/repair.c | 6 +++--- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index d1a76b7f33b7..081fdce5621a 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1057,7 +1057,8 @@ xfs_alloc_ag_vextent_small( be32_to_cpu(agf->agf_flcount) <= args->minleft) goto out; - error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); + error = xfs_alloc_get_freelist(args->pag, args->tp, args->agbp, + &fbno, 0); if (error) goto error; if (fbno == NULLAGBLOCK) @@ -2679,7 +2680,7 @@ xfs_alloc_fix_freelist( else targs.oinfo = XFS_RMAP_OINFO_AG; while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) { - error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); + error = xfs_alloc_get_freelist(pag, tp, agbp, &bno, 0); if (error) goto out_agbp_relse; @@ -2749,6 +2750,7 @@ xfs_alloc_fix_freelist( */ int xfs_alloc_get_freelist( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agblock_t *bnop, @@ -2761,7 +2763,6 @@ xfs_alloc_get_freelist( int error; int logflags; struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; /* * Freelist is empty, give up. @@ -2789,7 +2790,6 @@ xfs_alloc_get_freelist( if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp)) agf->agf_flfirst = 0; - pag = agbp->b_pag; ASSERT(!pag->pagf_agflreset); be32_add_cpu(&agf->agf_flcount, -1); pag->pagf_flcount--; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 5efd52b3dd59..2b3fb141b68c 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -96,6 +96,8 @@ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_perag *pag, xfs_extlen_t need, xfs_extlen_t reserved); unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, struct xfs_perag *pag); +int xfs_alloc_get_freelist(struct xfs_perag *pag, struct xfs_trans *tp, + struct xfs_buf *agfbp, xfs_agblock_t *bnop, int btreeblk); /* * Compute and fill in value of m_alloc_maxlevels. @@ -104,17 +106,6 @@ void xfs_alloc_compute_maxlevels( struct xfs_mount *mp); /* file system mount structure */ -/* - * Get a block from the freelist. - * Returns with the buffer for the block gotten. - */ -int /* error */ -xfs_alloc_get_freelist( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_buf *agbp, /* buffer containing the agf structure */ - xfs_agblock_t *bnop, /* block address retrieved from freelist */ - int btreeblk); /* destination is a AGF btree */ - /* * Log the given fields from the agf structure. */ diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 8c9f73cc0bee..a2ead80afb39 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -60,8 +60,8 @@ xfs_allocbt_alloc_block( xfs_agblock_t bno; /* Allocate the new block from the freelist. If we can't, give up. */ - error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_ag.agbp, - &bno, 1); + error = xfs_alloc_get_freelist(cur->bc_ag.pag, cur->bc_tp, + cur->bc_ag.agbp, &bno, 1); if (error) return error; @@ -71,7 +71,7 @@ xfs_allocbt_alloc_block( } atomic64_inc(&cur->bc_mp->m_allocbt_blks); - xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.agbp->b_pag, bno, 1, false); + xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.pag, bno, 1, false); new->s = cpu_to_be32(bno); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index d6d45992fe7b..fbbbeda1b06d 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -90,7 +90,7 @@ xfs_rmapbt_alloc_block( xfs_agblock_t bno; /* Allocate the new block from the freelist. If we can't, give up. */ - error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_ag.agbp, + error = xfs_alloc_get_freelist(pag, cur->bc_tp, cur->bc_ag.agbp, &bno, 1); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 06b41321f425..382449567090 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -299,13 +299,13 @@ xrep_alloc_ag_block( switch (resv) { case XFS_AG_RESV_AGFL: case XFS_AG_RESV_RMAPBT: - error = xfs_alloc_get_freelist(sc->tp, sc->sa.agf_bp, &bno, 1); + error = xfs_alloc_get_freelist(sc->sa.pag, sc->tp, + sc->sa.agf_bp, &bno, 1); if (error) return error; if (bno == NULLAGBLOCK) return -ENOSPC; - xfs_extent_busy_reuse(sc->mp, sc->sa.pag, bno, - 1, false); + xfs_extent_busy_reuse(sc->mp, sc->sa.pag, bno, 1, false); *fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.pag->pag_agno, bno); if (resv == XFS_AG_RESV_RMAPBT) xfs_ag_resv_rmapbt_alloc(sc->mp, sc->sa.pag->pag_agno); From patchwork Fri Dec 3 00:00:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653903 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 0825EC43219 for ; Fri, 3 Dec 2021 00:01:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377755AbhLCAEv (ORCPT ); Thu, 2 Dec 2021 19:04:51 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37481 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377742AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 527E8869B58 for ; Fri, 3 Dec 2021 11:01:25 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KK-Hy for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkgv-Gv for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 09/36] xfs: pass perag to xfs_alloc_put_freelist Date: Fri, 3 Dec 2021 11:00:44 +1100 Message-Id: <20211203000111.2800982-10-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e55 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=jutQHCjETx02lnyGB_AA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner It's available in all callers, so pass it in so that the perag can be passed further down the stack. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 5 ++--- fs/xfs/libxfs/xfs_alloc.h | 14 +++----------- fs/xfs/libxfs/xfs_alloc_btree.c | 3 ++- fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- fs/xfs/scrub/repair.c | 4 ++-- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 081fdce5621a..da14c16df92a 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2724,7 +2724,7 @@ xfs_alloc_fix_freelist( * Put each allocated block on the list. */ for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { - error = xfs_alloc_put_freelist(tp, agbp, + error = xfs_alloc_put_freelist(pag, tp, agbp, agflbp, bno, 0); if (error) goto out_agflbp_relse; @@ -2854,6 +2854,7 @@ xfs_alloc_log_agf( */ int xfs_alloc_put_freelist( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, struct xfs_buf *agflbp, @@ -2862,7 +2863,6 @@ xfs_alloc_put_freelist( { struct xfs_mount *mp = tp->t_mountp; struct xfs_agf *agf = agbp->b_addr; - struct xfs_perag *pag; __be32 *blockp; int error; int logflags; @@ -2876,7 +2876,6 @@ xfs_alloc_put_freelist( if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp)) agf->agf_fllast = 0; - pag = agbp->b_pag; ASSERT(!pag->pagf_agflreset); be32_add_cpu(&agf->agf_flcount, 1); pag->pagf_flcount++; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 2b3fb141b68c..e13b730c78f7 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -98,6 +98,9 @@ unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, struct xfs_perag *pag); int xfs_alloc_get_freelist(struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agfbp, xfs_agblock_t *bnop, int btreeblk); +int xfs_alloc_put_freelist(struct xfs_perag *pag, struct xfs_trans *tp, + struct xfs_buf *agfbp, struct xfs_buf *agflbp, + xfs_agblock_t bno, int btreeblk); /* * Compute and fill in value of m_alloc_maxlevels. @@ -115,17 +118,6 @@ xfs_alloc_log_agf( struct xfs_buf *bp, /* buffer for a.g. freelist header */ int fields);/* mask of fields to be logged (XFS_AGF_...) */ -/* - * Put the block on the freelist for the allocation group. - */ -int /* error */ -xfs_alloc_put_freelist( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_buf *agbp, /* buffer for a.g. freelist header */ - struct xfs_buf *agflbp,/* buffer for a.g. free block array */ - xfs_agblock_t bno, /* block being freed */ - int btreeblk); /* owner was a AGF btree */ - /* * Allocate an extent (variable-size). */ diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index a2ead80afb39..549a3cba0234 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -89,7 +89,8 @@ xfs_allocbt_free_block( int error; bno = xfs_daddr_to_agbno(cur->bc_mp, xfs_buf_daddr(bp)); - error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); + error = xfs_alloc_put_freelist(cur->bc_ag.pag, cur->bc_tp, agbp, NULL, + bno, 1); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index fbbbeda1b06d..1ae14d0c831c 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -129,7 +129,7 @@ xfs_rmapbt_free_block( bno, 1); be32_add_cpu(&agf->agf_rmap_blocks, -1); xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); - error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); + error = xfs_alloc_put_freelist(pag, cur->bc_tp, agbp, NULL, bno, 1); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 382449567090..7c519cebb362 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -515,8 +515,8 @@ xrep_put_freelist( return error; /* Put the block on the AGFL. */ - error = xfs_alloc_put_freelist(sc->tp, sc->sa.agf_bp, sc->sa.agfl_bp, - agbno, 0); + error = xfs_alloc_put_freelist(sc->sa.pag, sc->tp, sc->sa.agf_bp, + sc->sa.agfl_bp, agbno, 0); if (error) return error; xfs_extent_busy_insert(sc->tp, sc->sa.pag, agbno, 1, From patchwork Fri Dec 3 00:00:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653911 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 2C5DDC433F5 for ; Fri, 3 Dec 2021 00:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377666AbhLCAE7 (ORCPT ); Thu, 2 Dec 2021 19:04:59 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58448 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377751AbhLCAE5 (ORCPT ); Thu, 2 Dec 2021 19:04:57 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 709126068B8 for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KM-Iv for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkh0-Hy for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 10/36] xfs: pass perag to xfs_alloc_read_agfl Date: Fri, 3 Dec 2021 11:00:45 +1100 Message-Id: <20211203000111.2800982-11-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=SAILczb-qZbT2BScxn0A:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We have the perag in most places we call xfs_alloc_read_agfl, so pass the perag instead of a mount/agno pair. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 31 ++++++++++++++++--------------- fs/xfs/libxfs/xfs_alloc.h | 4 ++-- fs/xfs/scrub/agheader_repair.c | 2 +- fs/xfs/scrub/common.c | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index da14c16df92a..b81d62a4ed5b 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -685,20 +685,19 @@ const struct xfs_buf_ops xfs_agfl_buf_ops = { /* * Read in the allocation group free block array. */ -int /* error */ +int xfs_alloc_read_agfl( - xfs_mount_t *mp, /* mount point structure */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - struct xfs_buf **bpp) /* buffer for the ag free block array */ + struct xfs_perag *pag, + struct xfs_trans *tp, + struct xfs_buf **bpp) { - struct xfs_buf *bp; /* return value */ - int error; + struct xfs_mount *mp = pag->pag_mount; + struct xfs_buf *bp; + int error; - ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf( mp, tp, mp->m_ddev_targp, - XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), + XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops); if (error) return error; @@ -2695,7 +2694,7 @@ xfs_alloc_fix_freelist( targs.alignment = targs.minlen = targs.prod = 1; targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; - error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp); + error = xfs_alloc_read_agfl(pag, tp, &agflbp); if (error) goto out_agbp_relse; @@ -2774,8 +2773,7 @@ xfs_alloc_get_freelist( /* * Read the array of free blocks. */ - error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno), - &agflbp); + error = xfs_alloc_read_agfl(pag, tp, &agflbp); if (error) return error; @@ -2869,9 +2867,12 @@ xfs_alloc_put_freelist( __be32 *agfl_bno; int startoff; - if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp, - be32_to_cpu(agf->agf_seqno), &agflbp))) - return error; + if (!agflbp) { + error = xfs_alloc_read_agfl(pag, tp, &agflbp); + if (error) + return error; + } + be32_add_cpu(&agf->agf_fllast, 1); if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp)) agf->agf_fllast = 0; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index e13b730c78f7..aa4c8f866cd1 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -173,8 +173,8 @@ int xfs_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, struct xfs_buf **agfbpp); int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, struct xfs_buf **agfbpp); -int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_agnumber_t agno, struct xfs_buf **bpp); +int xfs_alloc_read_agfl(struct xfs_perag *pag, struct xfs_trans *tp, + struct xfs_buf **bpp); int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, struct xfs_buf *, struct xfs_owner_info *); int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 24cc8c0a9d80..66c33f9d8541 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -393,7 +393,7 @@ xrep_agf( * btrees rooted in the AGF. If the AGFL contents are obviously bad * then we'll bail out. */ - error = xfs_alloc_read_agfl(mp, sc->tp, sc->sa.pag->pag_agno, &agfl_bp); + error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp); if (error) return error; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 73f3d729d7f5..03e07c873964 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -422,7 +422,7 @@ xchk_ag_read_headers( if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF)) return error; - error = xfs_alloc_read_agfl(mp, sc->tp, agno, &sa->agfl_bp); + error = xfs_alloc_read_agfl(sa->pag, sc->tp, &sa->agfl_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGFL)) return error; From patchwork Fri Dec 3 00:00:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653893 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 1E3B1C4332F for ; Fri, 3 Dec 2021 00:01:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377745AbhLCAEt (ORCPT ); Thu, 2 Dec 2021 19:04:49 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:56446 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377736AbhLCAEs (ORCPT ); Thu, 2 Dec 2021 19:04:48 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 7B71E606ABA for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KR-KT for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkh5-It for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 11/36] xfs: Pre-calculate per-AG agbno geometry Date: Fri, 3 Dec 2021 11:00:46 +1100 Message-Id: <20211203000111.2800982-12-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=_Pyvntc1yrSeCOnvVKIA:9 a=W1BubcHRaAuuSv8Q:21 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There is a lot of overhead in functions like xfs_verify_agbno() that repeatedly calculate the geometry limits of an AG. These can be pre-calculated as they are static and the verification context has a per-ag context it can quickly reference. In the case of xfs_verify_agbno(), we now always have a perag context handy, so we can store the AG length and the minimum valid block in the AG in the perag. This means we don't have to calculate it on every call and it can be inlined in callers if we move it to xfs_ag.h. Move xfs_ag_block_count() to xfs_ag.c because it's really a per-ag function and not an XFS type function. We need a little bit of rework that is specific to xfs_initialise_perag() to allow growfs to calculate the new perag sizes before we've updated the primary superblock during the grow (chicken/egg situation). Note that we leave the original xfs_verify_agbno in place in xfs_types.c as a static function as other callers in that file do not have per-ag contexts so still need to go the long way. It's been renamed to xfs_verify_agno_agbno() to indicate it takes both an agno and an agbno to differentiate it from new function. Future commits will make similar changes for other per-ag geometry validation functions. Further: $ size --totals fs/xfs/built-in.a text data bss dec hex filename before 1137325 322835 484 1460644 1649a4 (TOTALS) after 1136681 322835 484 1460000 164720 (TOTALS) This rework reduces the binary size by ~650 bytes, indicating that much less work is being done to bounds check the agbno values against on per-ag geometry information. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 40 +++++++++++++++++++++++++++++++++- fs/xfs/libxfs/xfs_ag.h | 21 +++++++++++++++++- fs/xfs/libxfs/xfs_alloc.c | 9 ++++---- fs/xfs/libxfs/xfs_btree.c | 6 ++--- fs/xfs/libxfs/xfs_refcount.c | 13 +++++------ fs/xfs/libxfs/xfs_rmap.c | 8 +++---- fs/xfs/libxfs/xfs_types.c | 18 +++------------ fs/xfs/libxfs/xfs_types.h | 3 --- fs/xfs/scrub/agheader.c | 19 ++++++++-------- fs/xfs/scrub/agheader_repair.c | 7 ++---- fs/xfs/scrub/alloc.c | 7 +++--- fs/xfs/scrub/ialloc.c | 6 ++--- fs/xfs/scrub/refcount.c | 7 +++--- fs/xfs/scrub/rmap.c | 6 ++--- fs/xfs/xfs_fsops.c | 2 +- fs/xfs/xfs_log_recover.c | 3 ++- fs/xfs/xfs_mount.c | 3 ++- 17 files changed, 108 insertions(+), 70 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index a357ac6bc4ad..d6af12d2510b 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -202,10 +202,35 @@ xfs_free_perag( } } +/* Find the size of the AG, in blocks. */ +static xfs_agblock_t +__xfs_ag_block_count( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agnumber_t agcount, + xfs_rfsblock_t dblocks) +{ + ASSERT(agno < agcount); + + if (agno < agcount - 1) + return mp->m_sb.sb_agblocks; + return dblocks - (agno * mp->m_sb.sb_agblocks); +} + +xfs_agblock_t +xfs_ag_block_count( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + return __xfs_ag_block_count(mp, agno, mp->m_sb.sb_agcount, + mp->m_sb.sb_dblocks); +} + int xfs_initialize_perag( struct xfs_mount *mp, xfs_agnumber_t agcount, + xfs_rfsblock_t dblocks, xfs_agnumber_t *maxagi) { struct xfs_perag *pag; @@ -271,6 +296,13 @@ xfs_initialize_perag( /* first new pag is fully initialized */ if (first_initialised == NULLAGNUMBER) first_initialised = index; + + /* + * Pre-calculated geometry + */ + pag->block_count = __xfs_ag_block_count(mp, index, agcount, + dblocks); + pag->min_block = XFS_AGFL_BLOCK(mp); } index = xfs_set_inode_alloc(mp, agcount); @@ -927,10 +959,16 @@ xfs_ag_extend_space( if (error) return error; - return xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno, + error = xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno, be32_to_cpu(agf->agf_length) - len), len, &XFS_RMAP_OINFO_SKIP_UPDATE, XFS_AG_RESV_NONE); + if (error) + return error; + + /* Update perag geometry */ + pag->block_count = be32_to_cpu(agf->agf_length); + return 0; } /* Retrieve AG geometry. */ diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 1132cda9a92f..77640f1409fd 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -67,6 +67,10 @@ struct xfs_perag { /* for rcu-safe freeing */ struct rcu_head rcu_head; + /* Precalculated geometry info */ + xfs_agblock_t block_count; + xfs_agblock_t min_block; + #ifdef __KERNEL__ /* -- kernel only structures below this line -- */ @@ -107,7 +111,7 @@ struct xfs_perag { }; int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, - xfs_agnumber_t *maxagi); + xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi); int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); void xfs_free_perag(struct xfs_mount *mp); @@ -116,6 +120,21 @@ struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int tag); void xfs_perag_put(struct xfs_perag *pag); +/* + * Per-ag geometry infomation and validation + */ +xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno); + +static inline bool +xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno) +{ + if (agbno >= pag->block_count) + return false; + if (agbno <= pag->min_block) + return false; + return true; +} + /* * Perag iteration APIs */ diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index b81d62a4ed5b..c0f345ba198b 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -230,7 +230,7 @@ xfs_alloc_get_rec( int *stat) /* output: success/failure */ { struct xfs_mount *mp = cur->bc_mp; - xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; int error; @@ -245,11 +245,11 @@ xfs_alloc_get_rec( goto out_bad_rec; /* check for valid extent range, including overflow */ - if (!xfs_verify_agbno(mp, agno, *bno)) + if (!xfs_verify_agbno(pag, *bno)) goto out_bad_rec; if (*bno > *bno + *len) goto out_bad_rec; - if (!xfs_verify_agbno(mp, agno, *bno + *len - 1)) + if (!xfs_verify_agbno(pag, *bno + *len - 1)) goto out_bad_rec; return 0; @@ -257,7 +257,8 @@ xfs_alloc_get_rec( out_bad_rec: xfs_warn(mp, "%s Freespace BTree record corruption in AG %d detected!", - cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", agno); + cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", + pag->pag_agno); xfs_warn(mp, "start block 0x%x block count 0x%x", *bno, *len); return -EFSCORRUPTED; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index f18a875f51c6..956d895dd4b5 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -216,7 +216,7 @@ xfs_btree_check_sptr( { if (level <= 0) return false; - return xfs_verify_agbno(cur->bc_mp, cur->bc_ag.pag->pag_agno, agbno); + return xfs_verify_agbno(cur->bc_ag.pag, agbno); } /* @@ -4508,10 +4508,10 @@ xfs_btree_sblock_verify( /* sibling pointer verification */ agno = xfs_daddr_to_agno(mp, xfs_buf_daddr(bp)); if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) && - !xfs_verify_agbno(mp, agno, be32_to_cpu(block->bb_u.s.bb_leftsib))) + !xfs_verify_agbno(bp->b_pag, be32_to_cpu(block->bb_u.s.bb_leftsib))) return __this_address; if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) && - !xfs_verify_agbno(mp, agno, be32_to_cpu(block->bb_u.s.bb_rightsib))) + !xfs_verify_agbno(bp->b_pag, be32_to_cpu(block->bb_u.s.bb_rightsib))) return __this_address; return NULL; diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index e90a02391906..70795cefe645 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -111,7 +111,7 @@ xfs_refcount_get_rec( int *stat) { struct xfs_mount *mp = cur->bc_mp; - xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; int error; xfs_agblock_t realstart; @@ -121,8 +121,6 @@ xfs_refcount_get_rec( return error; xfs_refcount_btrec_to_irec(rec, irec); - - agno = cur->bc_ag.pag->pag_agno; if (irec->rc_blockcount == 0 || irec->rc_blockcount > MAXREFCEXTLEN) goto out_bad_rec; @@ -137,22 +135,23 @@ xfs_refcount_get_rec( } /* check for valid extent range, including overflow */ - if (!xfs_verify_agbno(mp, agno, realstart)) + if (!xfs_verify_agbno(pag, realstart)) goto out_bad_rec; if (realstart > realstart + irec->rc_blockcount) goto out_bad_rec; - if (!xfs_verify_agbno(mp, agno, realstart + irec->rc_blockcount - 1)) + if (!xfs_verify_agbno(pag, realstart + irec->rc_blockcount - 1)) goto out_bad_rec; if (irec->rc_refcount == 0 || irec->rc_refcount > MAXREFCOUNT) goto out_bad_rec; - trace_xfs_refcount_get(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec); + trace_xfs_refcount_get(cur->bc_mp, pag->pag_agno, irec); return 0; out_bad_rec: xfs_warn(mp, - "Refcount BTree record corruption in AG %d detected!", agno); + "Refcount BTree record corruption in AG %d detected!", + pag->pag_agno); xfs_warn(mp, "Start block 0x%x, block count 0x%x, references 0x%x", irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount); diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index cd322174dbff..acbfce36171e 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -201,7 +201,7 @@ xfs_rmap_get_rec( int *stat) { struct xfs_mount *mp = cur->bc_mp; - xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; int error; @@ -221,12 +221,12 @@ xfs_rmap_get_rec( goto out_bad_rec; } else { /* check for valid extent range, including overflow */ - if (!xfs_verify_agbno(mp, agno, irec->rm_startblock)) + if (!xfs_verify_agbno(pag, irec->rm_startblock)) goto out_bad_rec; if (irec->rm_startblock > irec->rm_startblock + irec->rm_blockcount) goto out_bad_rec; - if (!xfs_verify_agbno(mp, agno, + if (!xfs_verify_agbno(pag, irec->rm_startblock + irec->rm_blockcount - 1)) goto out_bad_rec; } @@ -240,7 +240,7 @@ xfs_rmap_get_rec( out_bad_rec: xfs_warn(mp, "Reverse Mapping BTree record corruption in AG %d detected!", - agno); + pag->pag_agno); xfs_warn(mp, "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x", irec->rm_owner, irec->rm_flags, irec->rm_startblock, diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index e810d23f2d97..b3c6b0274e95 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c @@ -13,25 +13,13 @@ #include "xfs_mount.h" #include "xfs_ag.h" -/* Find the size of the AG, in blocks. */ -inline xfs_agblock_t -xfs_ag_block_count( - struct xfs_mount *mp, - xfs_agnumber_t agno) -{ - ASSERT(agno < mp->m_sb.sb_agcount); - - if (agno < mp->m_sb.sb_agcount - 1) - return mp->m_sb.sb_agblocks; - return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks); -} /* * Verify that an AG block number pointer neither points outside the AG * nor points at static metadata. */ -inline bool -xfs_verify_agbno( +static inline bool +xfs_verify_agno_agbno( struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno) @@ -59,7 +47,7 @@ xfs_verify_fsbno( if (agno >= mp->m_sb.sb_agcount) return false; - return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); + return xfs_verify_agno_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); } /* diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index b6da06b40989..b417e8929235 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -186,9 +186,6 @@ enum xfs_ag_resv_type { */ struct xfs_mount; -xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno); -bool xfs_verify_agbno(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agblock_t agbno); bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno); bool xfs_verify_fsbext(struct xfs_mount *mp, xfs_fsblock_t fsbno, xfs_fsblock_t len); diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index bed798792226..60d7a7d5ea97 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -542,16 +542,16 @@ xchk_agf( /* Check the AG length */ eoag = be32_to_cpu(agf->agf_length); - if (eoag != xfs_ag_block_count(mp, agno)) + if (eoag != pag->block_count) xchk_block_set_corrupt(sc, sc->sa.agf_bp); /* Check the AGF btree roots and levels */ agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); @@ -564,7 +564,7 @@ xchk_agf( if (xfs_has_rmapbt(mp)) { agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); @@ -574,7 +574,7 @@ xchk_agf( if (xfs_has_reflink(mp)) { agbno = be32_to_cpu(agf->agf_refcount_root); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_refcount_level); @@ -640,9 +640,8 @@ xchk_agfl_block( { struct xchk_agfl_info *sai = priv; struct xfs_scrub *sc = sai->sc; - xfs_agnumber_t agno = sc->sa.pag->pag_agno; - if (xfs_verify_agbno(mp, agno, agbno) && + if (xfs_verify_agbno(sc->sa.pag, agbno) && sai->nr_entries < sai->sz_entries) sai->entries[sai->nr_entries++] = agbno; else @@ -872,12 +871,12 @@ xchk_agi( /* Check the AG length */ eoag = be32_to_cpu(agi->agi_length); - if (eoag != xfs_ag_block_count(mp, agno)) + if (eoag != pag->block_count) xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Check btree roots and levels */ agbno = be32_to_cpu(agi->agi_root); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); level = be32_to_cpu(agi->agi_level); @@ -886,7 +885,7 @@ xchk_agi( if (xfs_has_finobt(mp)) { agbno = be32_to_cpu(agi->agi_free_root); - if (!xfs_verify_agbno(mp, agno, agbno)) + if (!xfs_verify_agbno(pag, agbno)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); level = be32_to_cpu(agi->agi_free_level); diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 66c33f9d8541..b32bb6bb3bc5 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -94,7 +94,7 @@ xrep_agf_check_agfl_block( { struct xfs_scrub *sc = priv; - if (!xfs_verify_agbno(mp, sc->sa.pag->pag_agno, agbno)) + if (!xfs_verify_agbno(sc->sa.pag, agbno)) return -EFSCORRUPTED; return 0; } @@ -118,10 +118,7 @@ xrep_check_btree_root( struct xfs_scrub *sc, struct xrep_find_ag_btree *fab) { - struct xfs_mount *mp = sc->mp; - xfs_agnumber_t agno = sc->sm->sm_agno; - - return xfs_verify_agbno(mp, agno, fab->root) && + return xfs_verify_agbno(sc->sa.pag, fab->root) && fab->height <= fab->maxlevels; } diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c index 87518e1292f8..ab427b4d7fe0 100644 --- a/fs/xfs/scrub/alloc.c +++ b/fs/xfs/scrub/alloc.c @@ -93,8 +93,7 @@ xchk_allocbt_rec( struct xchk_btree *bs, const union xfs_btree_rec *rec) { - struct xfs_mount *mp = bs->cur->bc_mp; - xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = bs->cur->bc_ag.pag; xfs_agblock_t bno; xfs_extlen_t len; @@ -102,8 +101,8 @@ xchk_allocbt_rec( len = be32_to_cpu(rec->alloc.ar_blockcount); if (bno + len <= bno || - !xfs_verify_agbno(mp, agno, bno) || - !xfs_verify_agbno(mp, agno, bno + len - 1)) + !xfs_verify_agbno(pag, bno) || + !xfs_verify_agbno(pag, bno + len - 1)) xchk_btree_set_corrupt(bs->sc, bs->cur, 0); xchk_allocbt_xref(bs->sc, bno, len); diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index 00848ee542fb..b80a54be8634 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -104,13 +104,13 @@ xchk_iallocbt_chunk( xfs_extlen_t len) { struct xfs_mount *mp = bs->cur->bc_mp; - xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = bs->cur->bc_ag.pag; xfs_agblock_t bno; bno = XFS_AGINO_TO_AGBNO(mp, agino); if (bno + len <= bno || - !xfs_verify_agbno(mp, agno, bno) || - !xfs_verify_agbno(mp, agno, bno + len - 1)) + !xfs_verify_agbno(pag, bno) || + !xfs_verify_agbno(pag, bno + len - 1)) xchk_btree_set_corrupt(bs->sc, bs->cur, 0); xchk_iallocbt_chunk_xref(bs->sc, irec, agino, bno, len); diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index 2744eecdbaf0..3f82a1a1f390 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -332,9 +332,8 @@ xchk_refcountbt_rec( struct xchk_btree *bs, const union xfs_btree_rec *rec) { - struct xfs_mount *mp = bs->cur->bc_mp; xfs_agblock_t *cow_blocks = bs->private; - xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = bs->cur->bc_ag.pag; xfs_agblock_t bno; xfs_extlen_t len; xfs_nlink_t refcount; @@ -354,8 +353,8 @@ xchk_refcountbt_rec( /* Check the extent. */ bno &= ~XFS_REFC_COW_START; if (bno + len <= bno || - !xfs_verify_agbno(mp, agno, bno) || - !xfs_verify_agbno(mp, agno, bno + len - 1)) + !xfs_verify_agbno(pag, bno) || + !xfs_verify_agbno(pag, bno + len - 1)) xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (refcount == 0) diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index 8dae0345c7df..229826b2e1c0 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -92,7 +92,7 @@ xchk_rmapbt_rec( { struct xfs_mount *mp = bs->cur->bc_mp; struct xfs_rmap_irec irec; - xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; + struct xfs_perag *pag = bs->cur->bc_ag.pag; bool non_inode; bool is_unwritten; bool is_bmbt; @@ -121,8 +121,8 @@ xchk_rmapbt_rec( * Otherwise we must point somewhere past the static metadata * but before the end of the FS. Run the regular check. */ - if (!xfs_verify_agbno(mp, agno, irec.rm_startblock) || - !xfs_verify_agbno(mp, agno, irec.rm_startblock + + if (!xfs_verify_agbno(pag, irec.rm_startblock) || + !xfs_verify_agbno(pag, irec.rm_startblock + irec.rm_blockcount - 1)) xchk_btree_set_corrupt(bs->sc, bs->cur, 0); } diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 7a209fd9eec7..23f0794b8911 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -131,7 +131,7 @@ xfs_growfs_data_private( oagcount = mp->m_sb.sb_agcount; /* allocate the new per-ag structures */ if (nagcount > oagcount) { - error = xfs_initialize_perag(mp, nagcount, &nagimax); + error = xfs_initialize_perag(mp, nagcount, nb, &nagimax); if (error) return error; } else if (nagcount < oagcount) { diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 74f399ceddd9..e135f05f5b3f 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3346,7 +3346,8 @@ xlog_do_recover( /* re-initialise in-core superblock and geometry structures */ mp->m_features |= xfs_sb_version_to_features(sbp); xfs_reinit_percpu_counters(mp); - error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); + error = xfs_initialize_perag(mp, sbp->sb_agcount, sbp->sb_dblocks, + &mp->m_maxagi); if (error) { xfs_warn(mp, "Failed post-recovery per-ag init: %d", error); return error; diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 359109b6f0d3..992f438cb4d7 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -754,7 +754,8 @@ xfs_mountfs( /* * Allocate and initialize the per-ag data. */ - error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); + error = xfs_initialize_perag(mp, sbp->sb_agcount, mp->m_sb.sb_dblocks, + &mp->m_maxagi); if (error) { xfs_warn(mp, "Failed per-ag init: %d", error); goto out_free_dir; From patchwork Fri Dec 3 00:00:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653891 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 C2EA0C433FE for ; Fri, 3 Dec 2021 00:01:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377743AbhLCAEs (ORCPT ); Thu, 2 Dec 2021 19:04:48 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37189 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377734AbhLCAEs (ORCPT ); Thu, 2 Dec 2021 19:04:48 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id B75B8869DA1 for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KU-Ly for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhA-KT for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 12/36] xfs: Pre-calculate per-AG agino geometry Date: Fri, 3 Dec 2021 11:00:47 +1100 Message-Id: <20211203000111.2800982-13-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e53 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=bBAovAi8A5TlA2pvHlEA:9 a=zIcJ-Kr0tPI675qt:21 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There is a lot of overhead in functions like xfs_verify_agino() that repeatedly calculate the geometry limits of an AG. These can be pre-calculated as they are static and the verification context has a per-ag context it can quickly reference. In the case of xfs_verify_agino(), we now always have a perag context handy, so we can store the minimum and maximum agino values in the AG in the perag. This means we don't have to calculate it on every call and it can be inlined in callers if we move it to xfs_ag.h. xfs_verify_agino_or_null() gets the same perag treatment. xfs_agino_range() is moved to xfs_ag.c as it's not really a type function, and it's use is largely restricted as the first and last aginos can be grabbed straight from the perag in most cases. Note that we leave the original xfs_verify_agino in place in xfs_types.c as a static function as other callers in that file do not have per-ag contexts so still need to go the long way. It's been renamed to xfs_verify_agno_agino() to indicate it takes both an agno and an agino to differentiate it from new function. $ size --totals fs/xfs/built-in.a text data bss dec hex filename before 1136681 322835 484 1460000 164720 (TOTALS) after 1136315 322835 484 1459634 1645b2 (TOTALS) Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 39 +++++++++++++++++++++++++ fs/xfs/libxfs/xfs_ag.h | 30 +++++++++++++++++++ fs/xfs/libxfs/xfs_ialloc.c | 6 ++-- fs/xfs/libxfs/xfs_inode_buf.c | 3 +- fs/xfs/libxfs/xfs_sb.c | 9 ++++++ fs/xfs/libxfs/xfs_types.c | 55 ++++------------------------------- fs/xfs/libxfs/xfs_types.h | 6 ---- fs/xfs/scrub/agheader.c | 6 ++-- fs/xfs/scrub/ialloc.c | 6 ++-- fs/xfs/scrub/repair.c | 9 ++---- fs/xfs/xfs_inode.c | 14 ++++----- 11 files changed, 104 insertions(+), 79 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index d6af12d2510b..730170dc83a9 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -226,6 +226,41 @@ xfs_ag_block_count( mp->m_sb.sb_dblocks); } +/* Calculate the first and last possible inode number in an AG. */ +static void +__xfs_agino_range( + struct xfs_mount *mp, + xfs_agblock_t eoag, + xfs_agino_t *first, + xfs_agino_t *last) +{ + xfs_agblock_t bno; + + /* + * Calculate the first inode, which will be in the first + * cluster-aligned block after the AGFL. + */ + bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align); + *first = XFS_AGB_TO_AGINO(mp, bno); + + /* + * Calculate the last inode, which will be at the end of the + * last (aligned) cluster that can be allocated in the AG. + */ + bno = round_down(eoag, M_IGEO(mp)->cluster_align); + *last = XFS_AGB_TO_AGINO(mp, bno) - 1; +} + +void +xfs_agino_range( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agino_t *first, + xfs_agino_t *last) +{ + return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last); +} + int xfs_initialize_perag( struct xfs_mount *mp, @@ -303,6 +338,8 @@ xfs_initialize_perag( pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks); pag->min_block = XFS_AGFL_BLOCK(mp); + __xfs_agino_range(mp, pag->block_count, &pag->agino_min, + &pag->agino_max); } index = xfs_set_inode_alloc(mp, agcount); @@ -968,6 +1005,8 @@ xfs_ag_extend_space( /* Update perag geometry */ pag->block_count = be32_to_cpu(agf->agf_length); + __xfs_agino_range(pag->pag_mount, pag->block_count, &pag->agino_min, + &pag->agino_max); return 0; } diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 77640f1409fd..bb9e91bd38e2 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -70,6 +70,8 @@ struct xfs_perag { /* Precalculated geometry info */ xfs_agblock_t block_count; xfs_agblock_t min_block; + xfs_agino_t agino_min; + xfs_agino_t agino_max; #ifdef __KERNEL__ /* -- kernel only structures below this line -- */ @@ -124,6 +126,8 @@ void xfs_perag_put(struct xfs_perag *pag); * Per-ag geometry infomation and validation */ xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno); +void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agino_t *first, xfs_agino_t *last); static inline bool xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno) @@ -135,6 +139,32 @@ xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno) return true; } +/* + * Verify that an AG inode number pointer neither points outside the AG + * nor points at static metadata. + */ +static inline bool +xfs_verify_agino(struct xfs_perag *pag, xfs_agino_t agino) +{ + if (agino < pag->agino_min) + return false; + if (agino > pag->agino_max) + return false; + return true; +} + +/* + * Verify that an AG inode number pointer neither points outside the AG + * nor points at static metadata, or is NULLAGINO. + */ +static inline bool +xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino) +{ + if (agino == NULLAGINO) + return true; + return xfs_verify_agino(pag, agino); +} + /* * Perag iteration APIs */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index b4fef0de2bb8..459a352e1790 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -105,7 +105,6 @@ xfs_inobt_get_rec( int *stat) { struct xfs_mount *mp = cur->bc_mp; - xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno; union xfs_btree_rec *rec; int error; uint64_t realfree; @@ -116,7 +115,7 @@ xfs_inobt_get_rec( xfs_inobt_btrec_to_irec(mp, rec, irec); - if (!xfs_verify_agino(mp, agno, irec->ir_startino)) + if (!xfs_verify_agino(cur->bc_ag.pag, irec->ir_startino)) goto out_bad_rec; if (irec->ir_count < XFS_INODES_PER_HOLEMASK_BIT || irec->ir_count > XFS_INODES_PER_CHUNK) @@ -137,7 +136,8 @@ xfs_inobt_get_rec( out_bad_rec: xfs_warn(mp, "%s Inode BTree record corruption in AG %d detected!", - cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free", agno); + cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free", + cur->bc_ag.pag->pag_agno); xfs_warn(mp, "start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x", irec->ir_startino, irec->ir_count, irec->ir_freecount, diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index cae9708c8587..9bb1e785245c 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -10,6 +10,7 @@ #include "xfs_log_format.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" +#include "xfs_ag.h" #include "xfs_inode.h" #include "xfs_errortag.h" #include "xfs_error.h" @@ -59,7 +60,7 @@ xfs_inode_buf_verify( unlinked_ino = be32_to_cpu(dip->di_next_unlinked); di_ok = xfs_verify_magic16(bp, dip->di_magic) && xfs_dinode_good_version(mp, dip->di_version) && - xfs_verify_agino_or_null(mp, agno, unlinked_ino); + xfs_verify_agino_or_null(bp->b_pag, unlinked_ino); if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP))) { if (readahead) { diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index f4e84aa1d50a..96f06e11ce58 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -196,6 +196,15 @@ xfs_validate_sb_write( (sbp->sb_fdblocks > sbp->sb_dblocks || !xfs_verify_icount(mp, sbp->sb_icount) || sbp->sb_ifree > sbp->sb_icount)) { + /* + printk("pag blocks %d agblocks %d min_ino %d max_ino %d\n", + bp->b_pag->block_count, + xfs_ag_block_count(mp, bp->b_pag->pag_agno), + bp->b_pag->agino_min, bp->b_pag->agino_max); + */ + printk("sb dblocks %lld fdblocks %lld icount %lld, ifree %lld\n", + sbp->sb_dblocks, sbp->sb_fdblocks, sbp->sb_icount, + sbp->sb_ifree); xfs_warn(mp, "SB summary counter sanity check failed"); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index b3c6b0274e95..5c2765934732 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c @@ -73,40 +73,12 @@ xfs_verify_fsbext( XFS_FSB_TO_AGNO(mp, fsbno + len - 1); } -/* Calculate the first and last possible inode number in an AG. */ -inline void -xfs_agino_range( - struct xfs_mount *mp, - xfs_agnumber_t agno, - xfs_agino_t *first, - xfs_agino_t *last) -{ - xfs_agblock_t bno; - xfs_agblock_t eoag; - - eoag = xfs_ag_block_count(mp, agno); - - /* - * Calculate the first inode, which will be in the first - * cluster-aligned block after the AGFL. - */ - bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align); - *first = XFS_AGB_TO_AGINO(mp, bno); - - /* - * Calculate the last inode, which will be at the end of the - * last (aligned) cluster that can be allocated in the AG. - */ - bno = round_down(eoag, M_IGEO(mp)->cluster_align); - *last = XFS_AGB_TO_AGINO(mp, bno) - 1; -} - /* * Verify that an AG inode number pointer neither points outside the AG * nor points at static metadata. */ -inline bool -xfs_verify_agino( +static inline bool +xfs_verify_agno_agino( struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t agino) @@ -118,19 +90,6 @@ xfs_verify_agino( return agino >= first && agino <= last; } -/* - * Verify that an AG inode number pointer neither points outside the AG - * nor points at static metadata, or is NULLAGINO. - */ -bool -xfs_verify_agino_or_null( - struct xfs_mount *mp, - xfs_agnumber_t agno, - xfs_agino_t agino) -{ - return agino == NULLAGINO || xfs_verify_agino(mp, agno, agino); -} - /* * Verify that an FS inode number pointer neither points outside the * filesystem nor points at static AG metadata. @@ -147,7 +106,7 @@ xfs_verify_ino( return false; if (XFS_AGINO_TO_INO(mp, agno, agino) != ino) return false; - return xfs_verify_agino(mp, agno, agino); + return xfs_verify_agno_agino(mp, agno, agino); } /* Is this an internal inode number? */ @@ -217,12 +176,8 @@ xfs_icount_range( /* root, rtbitmap, rtsum all live in the first chunk */ *min = XFS_INODES_PER_CHUNK; - for_each_perag(mp, agno, pag) { - xfs_agino_t first, last; - - xfs_agino_range(mp, agno, &first, &last); - nr_inos += last - first + 1; - } + for_each_perag(mp, agno, pag) + nr_inos += pag->agino_max - pag->agino_min + 1; *max = nr_inos; } diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index b417e8929235..ebf07c99c1ba 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -190,12 +190,6 @@ bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno); bool xfs_verify_fsbext(struct xfs_mount *mp, xfs_fsblock_t fsbno, xfs_fsblock_t len); -void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agino_t *first, xfs_agino_t *last); -bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agino_t agino); -bool xfs_verify_agino_or_null(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agino_t agino); bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index 60d7a7d5ea97..94d000fd97b7 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -902,17 +902,17 @@ xchk_agi( /* Check inode pointers */ agino = be32_to_cpu(agi->agi_newino); - if (!xfs_verify_agino_or_null(mp, agno, agino)) + if (!xfs_verify_agino_or_null(pag, agino)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); agino = be32_to_cpu(agi->agi_dirino); - if (!xfs_verify_agino_or_null(mp, agno, agino)) + if (!xfs_verify_agino_or_null(pag, agino)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Check unlinked inode buckets */ for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { agino = be32_to_cpu(agi->agi_unlinked[i]); - if (!xfs_verify_agino_or_null(mp, agno, agino)) + if (!xfs_verify_agino_or_null(pag, agino)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); } diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index b80a54be8634..e1026e07bf94 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -421,10 +421,10 @@ xchk_iallocbt_rec( const union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; + struct xfs_perag *pag = bs->cur->bc_ag.pag; struct xchk_iallocbt *iabt = bs->private; struct xfs_inobt_rec_incore irec; uint64_t holes; - xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; xfs_agino_t agino; xfs_extlen_t len; int holecount; @@ -446,8 +446,8 @@ xchk_iallocbt_rec( agino = irec.ir_startino; /* Record has to be properly aligned within the AG. */ - if (!xfs_verify_agino(mp, agno, agino) || - !xfs_verify_agino(mp, agno, agino + XFS_INODES_PER_CHUNK - 1)) { + if (!xfs_verify_agino(pag, agino) || + !xfs_verify_agino(pag, agino + XFS_INODES_PER_CHUNK - 1)) { xchk_btree_set_corrupt(bs->sc, bs->cur, 0); goto out; } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 7c519cebb362..d8da7f994669 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -219,16 +219,13 @@ xrep_calc_ag_resblks( usedlen = aglen - freelen; xfs_buf_relse(bp); } - xfs_perag_put(pag); /* If the icount is impossible, make some worst-case assumptions. */ if (icount == NULLAGINO || - !xfs_verify_agino(mp, sm->sm_agno, icount)) { - xfs_agino_t first, last; - - xfs_agino_range(mp, sm->sm_agno, &first, &last); - icount = last - first + 1; + !xfs_verify_agino(pag, icount)) { + icount = pag->agino_max - pag->agino_min + 1; } + xfs_perag_put(pag); /* If the block counts are impossible, make worst-case assumptions. */ if (aglen == NULLAGBLOCK || diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c07043393643..52b296d76d11 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2034,7 +2034,7 @@ xfs_iunlink_update_bucket( xfs_agino_t old_value; int offset; - ASSERT(xfs_verify_agino_or_null(tp->t_mountp, pag->pag_agno, new_agino)); + ASSERT(xfs_verify_agino_or_null(pag, new_agino)); old_value = be32_to_cpu(agi->agi_unlinked[bucket_index]); trace_xfs_iunlink_update_bucket(tp->t_mountp, pag->pag_agno, bucket_index, @@ -2071,7 +2071,7 @@ xfs_iunlink_update_dinode( struct xfs_mount *mp = tp->t_mountp; int offset; - ASSERT(xfs_verify_agino_or_null(mp, pag->pag_agno, next_agino)); + ASSERT(xfs_verify_agino_or_null(pag, next_agino)); trace_xfs_iunlink_update_dinode(mp, pag->pag_agno, agino, be32_to_cpu(dip->di_next_unlinked), next_agino); @@ -2101,7 +2101,7 @@ xfs_iunlink_update_inode( xfs_agino_t old_value; int error; - ASSERT(xfs_verify_agino_or_null(mp, pag->pag_agno, next_agino)); + ASSERT(xfs_verify_agino_or_null(pag, next_agino)); error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp); if (error) @@ -2110,7 +2110,7 @@ xfs_iunlink_update_inode( /* Make sure the old pointer isn't garbage. */ old_value = be32_to_cpu(dip->di_next_unlinked); - if (!xfs_verify_agino_or_null(mp, pag->pag_agno, old_value)) { + if (!xfs_verify_agino_or_null(pag, old_value)) { xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); error = -EFSCORRUPTED; @@ -2181,7 +2181,7 @@ xfs_iunlink( */ next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); if (next_agino == agino || - !xfs_verify_agino_or_null(mp, pag->pag_agno, next_agino)) { + !xfs_verify_agino_or_null(pag, next_agino)) { xfs_buf_mark_corrupt(agibp); error = -EFSCORRUPTED; goto out; @@ -2317,7 +2317,7 @@ xfs_iunlink_map_prev( * Make sure this pointer is valid and isn't an obvious * infinite loop. */ - if (!xfs_verify_agino(mp, pag->pag_agno, unlinked_agino) || + if (!xfs_verify_agino(pag, unlinked_agino) || next_agino == unlinked_agino) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, @@ -2364,7 +2364,7 @@ xfs_iunlink_remove( * go on. Make sure the head pointer isn't garbage. */ head_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); - if (!xfs_verify_agino(mp, pag->pag_agno, head_agino)) { + if (!xfs_verify_agino(pag, head_agino)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, agi, sizeof(*agi)); return -EFSCORRUPTED; From patchwork Fri Dec 3 00:00:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653919 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 A6C26C433F5 for ; Fri, 3 Dec 2021 00:01:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377741AbhLCAFB (ORCPT ); Thu, 2 Dec 2021 19:05:01 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58518 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377767AbhLCAE7 (ORCPT ); Thu, 2 Dec 2021 19:04:59 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 8AC47606A14 for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KV-Mu for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhF-Lv for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 13/36] xfs: replace xfs_ag_block_count() with perag accesses Date: Fri, 3 Dec 2021 11:00:48 +1100 Message-Id: <20211203000111.2800982-14-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=lvI39o05NRYNU6UdGCYA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Many of the places that call xfs_ag_block_count() have a perag available. These places can just read pag->block_count directly instead of calculating the AG block count from first principles. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc_btree.c | 10 +++++----- fs/xfs/scrub/agheader_repair.c | 6 ++---- fs/xfs/scrub/repair.c | 8 ++++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index aa4367a0a0de..2e0ff99d9f0b 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -683,10 +683,10 @@ xfs_inobt_rec_check_count( static xfs_extlen_t xfs_inobt_max_size( - struct xfs_mount *mp, - xfs_agnumber_t agno) + struct xfs_perag *pag) { - xfs_agblock_t agblocks = xfs_ag_block_count(mp, agno); + struct xfs_mount *mp = pag->pag_mount; + xfs_agblock_t agblocks = pag->block_count; /* Bail out if we're uninitialized, which can happen in mkfs. */ if (M_IGEO(mp)->inobt_mxr[0] == 0) @@ -698,7 +698,7 @@ xfs_inobt_max_size( * expansion. We therefore can pretend the space isn't there. */ if (mp->m_sb.sb_logstart && - XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno) + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == pag->pag_agno) agblocks -= mp->m_sb.sb_logblocks; return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, @@ -800,7 +800,7 @@ xfs_finobt_calc_reserves( if (error) return error; - *ask += xfs_inobt_max_size(mp, pag->pag_agno); + *ask += xfs_inobt_max_size(pag); *used += tree_len; return 0; } diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index b32bb6bb3bc5..384fbef097e8 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -186,8 +186,7 @@ xrep_agf_init_header( agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); agf->agf_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agf->agf_length = cpu_to_be32(xfs_ag_block_count(mp, - sc->sa.pag->pag_agno)); + agf->agf_length = cpu_to_be32(sc->sa.pag->block_count); agf->agf_flfirst = old_agf->agf_flfirst; agf->agf_fllast = old_agf->agf_fllast; agf->agf_flcount = old_agf->agf_flcount; @@ -765,8 +764,7 @@ xrep_agi_init_header( agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); agi->agi_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agi->agi_length = cpu_to_be32(xfs_ag_block_count(mp, - sc->sa.pag->pag_agno)); + agi->agi_length = cpu_to_be32(sc->sa.pag->block_count); agi->agi_newino = cpu_to_be32(NULLAGINO); agi->agi_dirino = cpu_to_be32(NULLAGINO); if (xfs_has_crc(mp)) diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index d8da7f994669..992d66453264 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -208,7 +208,7 @@ xrep_calc_ag_resblks( /* Now grab the block counters from the AGF. */ error = xfs_alloc_read_agf(pag, NULL, 0, &bp); if (error) { - aglen = xfs_ag_block_count(mp, sm->sm_agno); + aglen = pag->block_count; freelen = aglen; usedlen = aglen; } else { @@ -225,16 +225,16 @@ xrep_calc_ag_resblks( !xfs_verify_agino(pag, icount)) { icount = pag->agino_max - pag->agino_min + 1; } - xfs_perag_put(pag); /* If the block counts are impossible, make worst-case assumptions. */ if (aglen == NULLAGBLOCK || - aglen != xfs_ag_block_count(mp, sm->sm_agno) || + aglen != pag->block_count || freelen >= aglen) { - aglen = xfs_ag_block_count(mp, sm->sm_agno); + aglen = pag->block_count; freelen = aglen; usedlen = aglen; } + xfs_perag_put(pag); trace_xrep_calc_ag_resblks(mp, sm->sm_agno, icount, aglen, freelen, usedlen); From patchwork Fri Dec 3 00:00:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653921 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 075AAC4321E for ; Fri, 3 Dec 2021 00:01:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377758AbhLCAFC (ORCPT ); Thu, 2 Dec 2021 19:05:02 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58186 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377775AbhLCAFA (ORCPT ); Thu, 2 Dec 2021 19:05:00 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 8AD30606BBB for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1KZ-O8 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhK-Ms for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 14/36] xfs: make is_log_ag() a first class helper Date: Fri, 3 Dec 2021 11:00:49 +1100 Message-Id: <20211203000111.2800982-15-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=mae3UHUuaFR5lmlHqFUA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We check if an ag contains the log in many places, so make this a first class XFS helper by lifting it to fs/xfs/libxfs/xfs_ag.h and renaming it xfs_ag_contains_log(). The convert all the places that check if the AG contains the log to use this helper. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 12 +++--------- fs/xfs/libxfs/xfs_ag.h | 7 +++++++ fs/xfs/libxfs/xfs_ialloc.c | 3 +-- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 +-- fs/xfs/libxfs/xfs_refcount_btree.c | 3 +-- fs/xfs/libxfs/xfs_rmap_btree.c | 3 +-- fs/xfs/scrub/health.c | 2 ++ fs/xfs/scrub/refcount.c | 2 ++ 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 730170dc83a9..712d274012d0 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -391,12 +391,6 @@ xfs_get_aghdr_buf( return 0; } -static inline bool is_log_ag(struct xfs_mount *mp, struct aghdr_init_data *id) -{ - return mp->m_sb.sb_logstart > 0 && - id->agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart); -} - /* * Generic btree root block init function */ @@ -422,7 +416,7 @@ xfs_freesp_init_recs( arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks); - if (is_log_ag(mp, id)) { + if (xfs_ag_contains_log(mp, id->agno)) { struct xfs_alloc_rec *nrec; xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart); @@ -549,7 +543,7 @@ xfs_rmaproot_init( } /* account for the log space */ - if (is_log_ag(mp, id)) { + if (xfs_ag_contains_log(mp, id->agno)) { rrec = XFS_RMAP_REC_ADDR(block, be16_to_cpu(block->bb_numrecs) + 1); rrec->rm_startblock = cpu_to_be32( @@ -620,7 +614,7 @@ xfs_agfblock_init( agf->agf_refcount_blocks = cpu_to_be32(1); } - if (is_log_ag(mp, id)) { + if (xfs_ag_contains_log(mp, id->agno)) { int64_t logblocks = mp->m_sb.sb_logblocks; be32_add_cpu(&agf->agf_freeblks, -logblocks); diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index bb9e91bd38e2..75f7c10c110a 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -165,6 +165,13 @@ xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino) return xfs_verify_agino(pag, agino); } +static inline bool +xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno) +{ + return mp->m_sb.sb_logstart > 0 && + agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart); +} + /* * Perag iteration APIs */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 459a352e1790..538e9dda1346 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2895,8 +2895,7 @@ xfs_ialloc_calc_rootino( * allocation group, or very odd geometries created by old mkfs * versions on very small filesystems. */ - if (mp->m_sb.sb_logstart && - XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0) + if (xfs_ag_contains_log(mp, 0)) first_bno += mp->m_sb.sb_logblocks; /* diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 2e0ff99d9f0b..8c83e265770c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -697,8 +697,7 @@ xfs_inobt_max_size( * never be available for the kinds of things that would require btree * expansion. We therefore can pretend the space isn't there. */ - if (mp->m_sb.sb_logstart && - XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == pag->pag_agno) + if (xfs_ag_contains_log(mp, pag->pag_agno)) agblocks -= mp->m_sb.sb_logblocks; return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 1063234df34a..316c1ec0c3c2 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -507,8 +507,7 @@ xfs_refcountbt_calc_reserves( * never be available for the kinds of things that would require btree * expansion. We therefore can pretend the space isn't there. */ - if (mp->m_sb.sb_logstart && - XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == pag->pag_agno) + if (xfs_ag_contains_log(mp, pag->pag_agno)) agblocks -= mp->m_sb.sb_logblocks; *ask += xfs_refcountbt_max_size(mp, agblocks); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 1ae14d0c831c..7f83f62e51e0 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -666,8 +666,7 @@ xfs_rmapbt_calc_reserves( * never be available for the kinds of things that would require btree * expansion. We therefore can pretend the space isn't there. */ - if (mp->m_sb.sb_logstart && - XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == pag->pag_agno) + if (xfs_ag_contains_log(mp, pag->pag_agno)) agblocks -= mp->m_sb.sb_logblocks; /* Reserve 1% of the AG or enough for 1 block per record. */ diff --git a/fs/xfs/scrub/health.c b/fs/xfs/scrub/health.c index 2e61df3bca83..aa65ec88a0c0 100644 --- a/fs/xfs/scrub/health.c +++ b/fs/xfs/scrub/health.c @@ -8,6 +8,8 @@ #include "xfs_shared.h" #include "xfs_format.h" #include "xfs_btree.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" #include "xfs_ag.h" #include "xfs_health.h" #include "scrub/scrub.h" diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index 3f82a1a1f390..c68b767dc08f 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -13,6 +13,8 @@ #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/btree.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" #include "xfs_ag.h" /* From patchwork Fri Dec 3 00:00:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653925 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 555BFC43217 for ; Fri, 3 Dec 2021 00:01:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349680AbhLCAFB (ORCPT ); Thu, 2 Dec 2021 19:05:01 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58448 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377764AbhLCAE7 (ORCPT ); Thu, 2 Dec 2021 19:04:59 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id C68A7606B09 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Kc-PH for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhP-O6 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 15/36] xfs: active perag reference counting Date: Fri, 3 Dec 2021 11:00:50 +1100 Message-Id: <20211203000111.2800982-16-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=3hNUpj73OeyeJCLC4wsA:9 a=hXW4HXavTKGUmkWl:21 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We need to be able to dynamically remove instantiated AGs from memory safely, either for shrinking the filesystem or paging AG state in and out of memory (e.g. supporting millions of AGs). This means we need to be able to safely exclude operations from accessing perags while dynamic removal is in progress. To do this, introduce the concept of active and passive references. Active references are required for high level operations that make use of an AG for a given operation (e.g. allocation) and pin the perag in memory for the duration of the operation that is operating on the perag (e.g. transaction scope). This means we can fail to get an active reference to an AG, hence callers of the new active reference API must be able to handle lookup failure gracefully. Passive references are used in low level code, where we might need to access the perag structure for the purposes of completing high level operations. For example, buffers need to use passive references because: - we need to be able to do metadata IO during operations like grow and shrink transactions where high level active references to the AG have already been blocked - buffers need to pin the perag until they are reclaimed from memory, something that high level code has no direct control over. - unused cached buffers should not prevent a shrink from being started. Hence we have active references that will form exclusion barriers for operations to be performed on an AG, and passive references that will prevent reclaim of the perag until all objects with passive references have been reclaimed themselves. This patch introduce xfs_perag_grab()/xfs_perag_rele() as the API for active AG reference functionality. We also need to convert the for_each_perag*() iterators to use active references, which will start the process of converting high level code over to using active references. Conversion of non-iterator based code to active references will be done in followup patches. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 72 ++++++++++++++++++++++++++++++++++++++- fs/xfs/libxfs/xfs_ag.h | 31 ++++++++++++----- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/fscounters.c | 4 +-- fs/xfs/xfs_fsmap.c | 4 +-- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_iwalk.c | 6 ++-- fs/xfs/xfs_reflink.c | 2 +- fs/xfs/xfs_trace.h | 3 ++ 9 files changed, 106 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 712d274012d0..02155220c613 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -94,6 +94,68 @@ xfs_perag_put( trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); } +/* + * Active references for perag structures. This is for short term access to the + * per ag structures for walking trees or accessing state. If an AG is being + * shrunk or is offline, then this will fail to find that AG and return NULL + * instead. + */ +struct xfs_perag * +xfs_perag_grab( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_perag *pag; + + rcu_read_lock(); + pag = radix_tree_lookup(&mp->m_perag_tree, agno); + if (pag) { + trace_xfs_perag_grab(mp, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (!atomic_inc_not_zero(&pag->pag_active_ref)) + pag = NULL; + } + rcu_read_unlock(); + return pag; +} + +/* + * search from @first to find the next perag with the given tag set. + */ +struct xfs_perag * +xfs_perag_grab_tag( + struct xfs_mount *mp, + xfs_agnumber_t first, + int tag) +{ + struct xfs_perag *pag; + int found; + + rcu_read_lock(); + found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, + (void **)&pag, first, 1, tag); + if (found <= 0) { + rcu_read_unlock(); + return NULL; + } + trace_xfs_perag_grab_tag(mp, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (!atomic_inc_not_zero(&pag->pag_active_ref)) + pag = NULL; + rcu_read_unlock(); + return pag; +} + +void +xfs_perag_rele( + struct xfs_perag *pag) +{ + trace_xfs_perag_rele(pag->pag_mount, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (atomic_dec_and_test(&pag->pag_active_ref)) + wake_up(&pag->pag_active_wq); +} + /* * xfs_initialize_perag_data * @@ -173,6 +235,7 @@ __xfs_free_perag( struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head); ASSERT(!delayed_work_pending(&pag->pag_blockgc_work)); + ASSERT(atomic_read(&pag->pag_active_ref) == 0); ASSERT(atomic_read(&pag->pag_ref) == 0); kmem_free(pag); } @@ -198,6 +261,8 @@ xfs_free_perag( xfs_iunlink_destroy(pag); xfs_buf_hash_destroy(pag); + /* drop the mount's active reference */ + xfs_perag_rele(pag); call_rcu(&pag->rcu_head, __xfs_free_perag); } } @@ -316,6 +381,7 @@ xfs_initialize_perag( INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker); INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); init_waitqueue_head(&pag->pagb_wait); + init_waitqueue_head(&pag->pag_active_wq); pag->pagb_count = 0; pag->pagb_tree = RB_ROOT; #endif /* __KERNEL__ */ @@ -328,6 +394,9 @@ xfs_initialize_perag( if (error) goto out_hash_destroy; + /* Active ref owned by mount indicates AG is online. */ + atomic_set(&pag->pag_active_ref, 1); + /* first new pag is fully initialized */ if (first_initialised == NULLAGNUMBER) first_initialised = index; @@ -364,7 +433,8 @@ xfs_initialize_perag( break; xfs_buf_hash_destroy(pag); xfs_iunlink_destroy(pag); - kmem_free(pag); + xfs_perag_rele(pag); + __xfs_free_perag(&pag->rcu_head); } return error; } diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 75f7c10c110a..b36d5725c91c 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -32,7 +32,9 @@ struct xfs_ag_resv { struct xfs_perag { struct xfs_mount *pag_mount; /* owner filesystem */ xfs_agnumber_t pag_agno; /* AG this structure belongs to */ - atomic_t pag_ref; /* perag reference count */ + atomic_t pag_ref; /* passive reference count */ + atomic_t pag_active_ref; /* active reference count */ + wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */ char pagf_init; /* this agf's entry is initialized */ char pagi_init; /* this agi's entry is initialized */ char pagf_metadata; /* the agf is preferred to be metadata */ @@ -117,11 +119,18 @@ int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); void xfs_free_perag(struct xfs_mount *mp); +/* Passive AG references */ struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int tag); void xfs_perag_put(struct xfs_perag *pag); +/* Active AG references */ +struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t); +struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t, + int tag); +void xfs_perag_rele(struct xfs_perag *pag); + /* * Per-ag geometry infomation and validation */ @@ -184,14 +193,18 @@ xfs_perag_next( struct xfs_mount *mp = pag->pag_mount; *agno = pag->pag_agno + 1; - xfs_perag_put(pag); - if (*agno > end_agno) - return NULL; - return xfs_perag_get(mp, *agno); + xfs_perag_rele(pag); + while (*agno <= end_agno) { + pag = xfs_perag_grab(mp, *agno); + if (pag) + return pag; + (*agno)++; + } + return NULL; } #define for_each_perag_range(mp, agno, end_agno, pag) \ - for ((pag) = xfs_perag_get((mp), (agno)); \ + for ((pag) = xfs_perag_grab((mp), (agno)); \ (pag) != NULL; \ (pag) = xfs_perag_next((pag), &(agno), (end_agno))) @@ -204,11 +217,11 @@ xfs_perag_next( for_each_perag_from((mp), (agno), (pag)) #define for_each_perag_tag(mp, agno, pag, tag) \ - for ((agno) = 0, (pag) = xfs_perag_get_tag((mp), 0, (tag)); \ + for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \ (pag) != NULL; \ (agno) = (pag)->pag_agno + 1, \ - xfs_perag_put(pag), \ - (pag) = xfs_perag_get_tag((mp), (agno), (tag))) + xfs_perag_rele(pag), \ + (pag) = xfs_perag_grab_tag((mp), (agno), (tag))) struct aghdr_init_data { /* per ag data */ diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 570f0076ef2e..ec6ca623fe0b 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -621,7 +621,7 @@ xchk_bmap_check_rmaps( break; } if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 6a6f8fe7f87c..3706296c61b6 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -105,7 +105,7 @@ xchk_fscount_warmup( if (agi_bp) xfs_buf_relse(agi_bp); if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } @@ -224,7 +224,7 @@ xchk_fscount_aggregate_agcounts( } if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); if (error) return error; diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 9424b5a22d5e..aee98cdcad75 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -688,11 +688,11 @@ __xfs_getfsmap_datadev( info->agf_bp = NULL; } if (info->pag) { - xfs_perag_put(info->pag); + xfs_perag_rele(info->pag); info->pag = NULL; } else if (pag) { /* loop termination case */ - xfs_perag_put(pag); + xfs_perag_rele(pag); } return error; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index da4af2142a2b..7a0dde055a0d 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1748,7 +1748,7 @@ xfs_icwalk( if (error) { last_error = error; if (error == -EFSCORRUPTED) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } } diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index 7558486f4937..c31857d903a4 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -591,7 +591,7 @@ xfs_iwalk( } if (iwag.pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); xfs_iwalk_free(&iwag); return error; } @@ -683,7 +683,7 @@ xfs_iwalk_threaded( break; } if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); if (polled) xfs_pwork_poll(&pctl); return xfs_pwork_destroy(&pctl); @@ -776,7 +776,7 @@ xfs_inobt_walk( } if (iwag.pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); xfs_iwalk_free(&iwag); return error; } diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index d8281b002dff..0074a3a5edcc 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -766,7 +766,7 @@ xfs_reflink_recover_cow( for_each_perag(mp, agno, pag) { error = xfs_refcount_recover_cow_leftovers(mp, pag); if (error) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 4a8076ef8cb4..83782d5cc9c3 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -189,6 +189,9 @@ DEFINE_EVENT(xfs_perag_class, name, \ DEFINE_PERAG_REF_EVENT(xfs_perag_get); DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_put); +DEFINE_PERAG_REF_EVENT(xfs_perag_grab); +DEFINE_PERAG_REF_EVENT(xfs_perag_grab_tag); +DEFINE_PERAG_REF_EVENT(xfs_perag_rele); DEFINE_PERAG_REF_EVENT(xfs_perag_set_inode_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_clear_inode_tag); From patchwork Fri Dec 3 00:00:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653895 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 CF7C3C433F5 for ; Fri, 3 Dec 2021 00:01:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377746AbhLCAEt (ORCPT ); Thu, 2 Dec 2021 19:04:49 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37481 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377737AbhLCAEt (ORCPT ); Thu, 2 Dec 2021 19:04:49 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id E2FD4869E43 for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Ke-QD for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhU-PG for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 16/36] xfs: rework the perag trace points to be perag centric Date: Fri, 3 Dec 2021 11:00:51 +1100 Message-Id: <20211203000111.2800982-17-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=y0MLRB0vTC7IaxJqomAA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner So that they all output the same information in the traces to make debugging refcount issues easier. This means that all the lookup/drop functions no longer need to use the full memory barrier atomic operations (atomic*_return()) so will have less overhead when tracing is off. The set/clear tag tracepoints no longer abuse the reference count to pass the tag - the tag being cleared is obvious from the _RET_IP_ that is recorded in the trace point. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 25 +++++++++---------------- fs/xfs/xfs_icache.c | 4 ++-- fs/xfs/xfs_trace.h | 21 +++++++++++---------- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 02155220c613..3b68706a0691 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -44,16 +44,15 @@ xfs_perag_get( xfs_agnumber_t agno) { struct xfs_perag *pag; - int ref = 0; rcu_read_lock(); pag = radix_tree_lookup(&mp->m_perag_tree, agno); if (pag) { + trace_xfs_perag_get(pag, _RET_IP_); ASSERT(atomic_read(&pag->pag_ref) >= 0); - ref = atomic_inc_return(&pag->pag_ref); + atomic_inc(&pag->pag_ref); } rcu_read_unlock(); - trace_xfs_perag_get(mp, agno, ref, _RET_IP_); return pag; } @@ -68,7 +67,6 @@ xfs_perag_get_tag( { struct xfs_perag *pag; int found; - int ref; rcu_read_lock(); found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, @@ -77,9 +75,9 @@ xfs_perag_get_tag( rcu_read_unlock(); return NULL; } - ref = atomic_inc_return(&pag->pag_ref); + trace_xfs_perag_get_tag(pag, _RET_IP_); + atomic_inc(&pag->pag_ref); rcu_read_unlock(); - trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_); return pag; } @@ -87,11 +85,9 @@ void xfs_perag_put( struct xfs_perag *pag) { - int ref; - + trace_xfs_perag_put(pag, _RET_IP_); ASSERT(atomic_read(&pag->pag_ref) > 0); - ref = atomic_dec_return(&pag->pag_ref); - trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); + atomic_dec(&pag->pag_ref); } /* @@ -110,8 +106,7 @@ xfs_perag_grab( rcu_read_lock(); pag = radix_tree_lookup(&mp->m_perag_tree, agno); if (pag) { - trace_xfs_perag_grab(mp, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_grab(pag, _RET_IP_); if (!atomic_inc_not_zero(&pag->pag_active_ref)) pag = NULL; } @@ -138,8 +133,7 @@ xfs_perag_grab_tag( rcu_read_unlock(); return NULL; } - trace_xfs_perag_grab_tag(mp, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_grab_tag(pag, _RET_IP_); if (!atomic_inc_not_zero(&pag->pag_active_ref)) pag = NULL; rcu_read_unlock(); @@ -150,8 +144,7 @@ void xfs_perag_rele( struct xfs_perag *pag) { - trace_xfs_perag_rele(pag->pag_mount, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_rele(pag, _RET_IP_); if (atomic_dec_and_test(&pag->pag_active_ref)) wake_up(&pag->pag_active_wq); } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 7a0dde055a0d..20759414192c 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -252,7 +252,7 @@ xfs_perag_set_inode_tag( break; } - trace_xfs_perag_set_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); + trace_xfs_perag_set_inode_tag(pag, _RET_IP_); } /* Clear a tag on both the AG incore inode tree and the AG radix tree. */ @@ -286,7 +286,7 @@ xfs_perag_clear_inode_tag( radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno, tag); spin_unlock(&mp->m_perag_lock); - trace_xfs_perag_clear_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); + trace_xfs_perag_clear_inode_tag(pag, _RET_IP_); } /* diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 83782d5cc9c3..40ee3bc33cd4 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -159,33 +159,34 @@ TRACE_EVENT(xlog_intent_recovery_failed, ); DECLARE_EVENT_CLASS(xfs_perag_class, - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, - unsigned long caller_ip), - TP_ARGS(mp, agno, refcount, caller_ip), + TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), + TP_ARGS(pag, caller_ip), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_agnumber_t, agno) __field(int, refcount) + __field(int, active_refcount) __field(unsigned long, caller_ip) ), TP_fast_assign( - __entry->dev = mp->m_super->s_dev; - __entry->agno = agno; - __entry->refcount = refcount; + __entry->dev = pag->pag_mount->m_super->s_dev; + __entry->agno = pag->pag_agno; + __entry->refcount = atomic_read(&pag->pag_ref); + __entry->active_refcount = atomic_read(&pag->pag_active_ref); __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d agno 0x%x refcount %d caller %pS", + TP_printk("dev %d:%d agno 0x%x passive refs %d active refs %d caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, __entry->refcount, + __entry->active_refcount, (char *)__entry->caller_ip) ); #define DEFINE_PERAG_REF_EVENT(name) \ DEFINE_EVENT(xfs_perag_class, name, \ - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ - unsigned long caller_ip), \ - TP_ARGS(mp, agno, refcount, caller_ip)) + TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), \ + TP_ARGS(pag, caller_ip)) DEFINE_PERAG_REF_EVENT(xfs_perag_get); DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_put); From patchwork Fri Dec 3 00:00:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653863 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 86332C43217 for ; Fri, 3 Dec 2021 00:01:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349761AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35727 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243809AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id BEA8E869D42 for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Ki-Rd for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00BkhZ-QA for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 17/36] xfs: convert xfs_imap() to take a perag Date: Fri, 3 Dec 2021 11:00:52 +1100 Message-Id: <20211203000111.2800982-18-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=rChGdRRAqzpzq4-x-fMA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Callers have referenced perags but they don't pass it into xfs_imap() so it takes it's own reference. Fix that so we can change inode allocation over to using active references. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc.c | 43 +++++++++++++------------------------- fs/xfs/libxfs/xfs_ialloc.h | 3 ++- fs/xfs/scrub/common.c | 13 ++++++++---- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_inode.c | 9 ++++---- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 538e9dda1346..b444fa68213b 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2200,15 +2200,15 @@ xfs_difree( STATIC int xfs_imap_lookup( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_agino_t agino, xfs_agblock_t agbno, xfs_agblock_t *chunk_agbno, xfs_agblock_t *offset_agbno, int flags) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; struct xfs_buf *agbp; @@ -2263,12 +2263,13 @@ xfs_imap_lookup( */ int xfs_imap( - struct xfs_mount *mp, /* file system mount structure */ + struct xfs_perag *pag, struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ uint flags) /* flags for inode btree lookup */ { + struct xfs_mount *mp = pag->pag_mount; xfs_agblock_t agbno; /* block number of inode in the alloc group */ xfs_agino_t agino; /* inode number within alloc group */ xfs_agblock_t chunk_agbno; /* first block in inode chunk */ @@ -2276,17 +2277,15 @@ xfs_imap( int error; /* error code */ int offset; /* index of inode in its buffer */ xfs_agblock_t offset_agbno; /* blks from chunk start to inode */ - struct xfs_perag *pag; ASSERT(ino != NULLFSINO); /* * Split up the inode number into its parts. */ - pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); - if (!pag || agbno >= mp->m_sb.sb_agblocks || + if (agbno >= mp->m_sb.sb_agblocks || ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { error = -EINVAL; #ifdef DEBUG @@ -2295,20 +2294,14 @@ xfs_imap( * as they can be invalid without implying corruption. */ if (flags & XFS_IGET_UNTRUSTED) - goto out_drop; - if (!pag) { - xfs_alert(mp, - "%s: agno (%d) >= mp->m_sb.sb_agcount (%d)", - __func__, XFS_INO_TO_AGNO(mp, ino), - mp->m_sb.sb_agcount); - } + return error; if (agbno >= mp->m_sb.sb_agblocks) { xfs_alert(mp, "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)", __func__, (unsigned long long)agbno, (unsigned long)mp->m_sb.sb_agblocks); } - if (pag && ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { + if (ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { xfs_alert(mp, "%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)", __func__, ino, @@ -2316,7 +2309,7 @@ xfs_imap( } xfs_stack_trace(); #endif /* DEBUG */ - goto out_drop; + return error; } /* @@ -2327,10 +2320,10 @@ xfs_imap( * in all cases where an untrusted inode number is passed. */ if (flags & XFS_IGET_UNTRUSTED) { - error = xfs_imap_lookup(mp, tp, pag, agino, agbno, + error = xfs_imap_lookup(pag, tp, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) - goto out_drop; + return error; goto out_map; } @@ -2346,8 +2339,7 @@ xfs_imap( imap->im_len = XFS_FSB_TO_BB(mp, 1); imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog); - error = 0; - goto out_drop; + return 0; } /* @@ -2359,10 +2351,10 @@ xfs_imap( offset_agbno = agbno & M_IGEO(mp)->inoalign_mask; chunk_agbno = agbno - offset_agbno; } else { - error = xfs_imap_lookup(mp, tp, pag, agino, agbno, + error = xfs_imap_lookup(pag, tp, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) - goto out_drop; + return error; } out_map: @@ -2390,14 +2382,9 @@ xfs_imap( __func__, (unsigned long long) imap->im_blkno, (unsigned long long) imap->im_len, XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); - error = -EINVAL; - goto out_drop; + return -EINVAL; } - error = 0; -out_drop: - if (pag) - xfs_perag_put(pag); - return error; + return 0; } /* diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index c3907c268775..85462e466029 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -12,6 +12,7 @@ struct xfs_imap; struct xfs_mount; struct xfs_trans; struct xfs_btree_cur; +struct xfs_perag; /* Move inodes in clusters of this size */ #define XFS_INODE_BIG_CLUSTER_SIZE 8192 @@ -47,7 +48,7 @@ int xfs_difree(struct xfs_trans *tp, struct xfs_perag *pag, */ int xfs_imap( - struct xfs_mount *mp, /* file system mount structure */ + struct xfs_perag *pag, struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 03e07c873964..d56ce408d4d2 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -642,6 +642,7 @@ xchk_get_inode( { struct xfs_imap imap; struct xfs_mount *mp = sc->mp; + struct xfs_perag *pag; struct xfs_inode *ip_in = XFS_I(file_inode(sc->file)); struct xfs_inode *ip = NULL; int error; @@ -677,10 +678,14 @@ xchk_get_inode( * Otherwise, we really couldn't find it so tell userspace * that it no longer exists. */ - error = xfs_imap(sc->mp, sc->tp, sc->sm->sm_ino, &imap, - XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE); - if (error) - return -ENOENT; + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, sc->sm->sm_ino)); + if (pag) { + error = xfs_imap(pag, sc->tp, sc->sm->sm_ino, &imap, + XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE); + xfs_perag_put(pag); + if (error) + return -ENOENT; + } error = -EFSCORRUPTED; fallthrough; default: diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 20759414192c..2265673677ca 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -576,7 +576,7 @@ xfs_iget_cache_miss( if (!ip) return -ENOMEM; - error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, flags); + error = xfs_imap(pag, tp, ip->i_ino, &ip->i_imap, flags); if (error) goto out_destroy; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 52b296d76d11..72c35f03069c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2219,8 +2219,8 @@ xfs_iunlink( /* Return the imap, dinode pointer, and buffer for an inode. */ STATIC int xfs_iunlink_map_ino( + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t agno, xfs_agino_t agino, struct xfs_imap *imap, struct xfs_dinode **dipp, @@ -2230,7 +2230,8 @@ xfs_iunlink_map_ino( int error; imap->im_blkno = 0; - error = xfs_imap(mp, tp, XFS_AGINO_TO_INO(mp, agno, agino), imap, 0); + error = xfs_imap(pag, tp, XFS_AGINO_TO_INO(mp, pag->pag_agno, agino), + imap, 0); if (error) { xfs_warn(mp, "%s: xfs_imap returned error %d.", __func__, error); @@ -2279,7 +2280,7 @@ xfs_iunlink_map_prev( /* See if our backref cache can find it faster. */ *agino = xfs_iunlink_lookup_backref(pag, target_agino); if (*agino != NULLAGINO) { - error = xfs_iunlink_map_ino(tp, pag->pag_agno, *agino, imap, + error = xfs_iunlink_map_ino(pag, tp, *agino, imap, dipp, bpp); if (error) return error; @@ -2307,7 +2308,7 @@ xfs_iunlink_map_prev( xfs_trans_brelse(tp, *bpp); *agino = next_agino; - error = xfs_iunlink_map_ino(tp, pag->pag_agno, next_agino, imap, + error = xfs_iunlink_map_ino(pag, tp, next_agino, imap, dipp, bpp); if (error) return error; From patchwork Fri Dec 3 00:00:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653865 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 B4686C433EF for ; Fri, 3 Dec 2021 00:01:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377716AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35759 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349677AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id CC959869D48 for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Km-TV for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkhe-Rj for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 18/36] xfs: use active perag references for inode allocation Date: Fri, 3 Dec 2021 11:00:53 +1100 Message-Id: <20211203000111.2800982-19-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=hyD8EJl_wcQEvN-__RsA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Convert the inode allocation routines to use active perag references or references held by callers rather than grab their own. Also drive the perag further inwards to replace xfs_mounts when doing operations on a specific AG. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 63 +++++++++++++++++++------------------- fs/xfs/libxfs/xfs_ialloc.h | 2 +- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 3b68706a0691..c866274cb8ce 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -934,7 +934,7 @@ xfs_ag_shrink_space( * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. */ - error = xfs_ialloc_check_shrink(*tpp, pag->pag_agno, agibp, aglen - delta); + error = xfs_ialloc_check_shrink(pag, *tpp, agibp, aglen - delta); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index b444fa68213b..894810fece4f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -169,14 +169,14 @@ xfs_inobt_insert_rec( */ STATIC int xfs_inobt_insert( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t newino, xfs_agino_t newlen, xfs_btnum_t btnum) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; xfs_agino_t thisino; int i; @@ -514,14 +514,14 @@ __xfs_inobt_rec_merge( */ STATIC int xfs_inobt_insert_sprec( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, int btnum, struct xfs_inobt_rec_incore *nrec, /* in/out: new/merged rec. */ bool merge) /* merge or replace */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; int error; int i; @@ -609,9 +609,9 @@ xfs_inobt_insert_sprec( */ STATIC int xfs_ialloc_ag_alloc( + struct xfs_perag *pag, struct xfs_trans *tp, - struct xfs_buf *agbp, - struct xfs_perag *pag) + struct xfs_buf *agbp) { struct xfs_agi *agi; struct xfs_alloc_arg args; @@ -831,7 +831,7 @@ xfs_ialloc_ag_alloc( * if necessary. If a merge does occur, rec is updated to the * merged record. */ - error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag, + error = xfs_inobt_insert_sprec(pag, tp, agbp, XFS_BTNUM_INO, &rec, true); if (error == -EFSCORRUPTED) { xfs_alert(args.mp, @@ -856,20 +856,20 @@ xfs_ialloc_ag_alloc( * existing record with this one. */ if (xfs_has_finobt(args.mp)) { - error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag, + error = xfs_inobt_insert_sprec(pag, tp, agbp, XFS_BTNUM_FINO, &rec, false); if (error) return error; } } else { /* full chunk - insert new records to both btrees */ - error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, newlen, + error = xfs_inobt_insert(pag, tp, agbp, newino, newlen, XFS_BTNUM_INO); if (error) return error; if (xfs_has_finobt(args.mp)) { - error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, + error = xfs_inobt_insert(pag, tp, agbp, newino, newlen, XFS_BTNUM_FINO); if (error) return error; @@ -981,9 +981,9 @@ xfs_inobt_first_free_inode( */ STATIC int xfs_dialloc_ag_inobt( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_ino_t parent, xfs_ino_t *inop) { @@ -1429,9 +1429,9 @@ xfs_dialloc_ag_update_inobt( */ static int xfs_dialloc_ag( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_ino_t parent, xfs_ino_t *inop) { @@ -1448,7 +1448,7 @@ xfs_dialloc_ag( int i; if (!xfs_has_finobt(mp)) - return xfs_dialloc_ag_inobt(tp, agbp, pag, parent, inop); + return xfs_dialloc_ag_inobt(pag, tp, agbp, parent, inop); /* * If pagino is 0 (this is the root inode allocation) use newino. @@ -1594,8 +1594,8 @@ xfs_ialloc_next_ag( static bool xfs_dialloc_good_ag( - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, umode_t mode, int flags, bool ok_alloc) @@ -1606,6 +1606,8 @@ xfs_dialloc_good_ag( int needspace; int error; + if (!pag) + return false; if (!pag->pagi_inodeok) return false; @@ -1665,8 +1667,8 @@ xfs_dialloc_good_ag( static int xfs_dialloc_try_ag( - struct xfs_trans **tpp, struct xfs_perag *pag, + struct xfs_trans **tpp, xfs_ino_t parent, xfs_ino_t *new_ino, bool ok_alloc) @@ -1689,7 +1691,7 @@ xfs_dialloc_try_ag( goto out_release; } - error = xfs_ialloc_ag_alloc(*tpp, agbp, pag); + error = xfs_ialloc_ag_alloc(pag, *tpp, agbp); if (error < 0) goto out_release; @@ -1705,7 +1707,7 @@ xfs_dialloc_try_ag( } /* Allocate an inode in the found AG */ - error = xfs_dialloc_ag(*tpp, agbp, pag, parent, &ino); + error = xfs_dialloc_ag(pag, *tpp, agbp, parent, &ino); if (!error) *new_ino = ino; return error; @@ -1775,9 +1777,9 @@ xfs_dialloc( agno = start_agno; flags = XFS_ALLOC_FLAG_TRYLOCK; for (;;) { - pag = xfs_perag_get(mp, agno); - if (xfs_dialloc_good_ag(*tpp, pag, mode, flags, ok_alloc)) { - error = xfs_dialloc_try_ag(tpp, pag, parent, + pag = xfs_perag_grab(mp, agno); + if (xfs_dialloc_good_ag(pag, *tpp, mode, flags, ok_alloc)) { + error = xfs_dialloc_try_ag(pag, tpp, parent, &ino, ok_alloc); if (error != -EAGAIN) break; @@ -1796,12 +1798,12 @@ xfs_dialloc( } flags = 0; } - xfs_perag_put(pag); + xfs_perag_rele(pag); } if (!error) *new_ino = ino; - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } @@ -1885,14 +1887,14 @@ xfs_difree_inode_chunk( STATIC int xfs_difree_inobt( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t agino, struct xfs_icluster *xic, struct xfs_inobt_rec_incore *orec) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_agi *agi = agbp->b_addr; struct xfs_btree_cur *cur; struct xfs_inobt_rec_incore rec; @@ -2019,13 +2021,13 @@ xfs_difree_inobt( */ STATIC int xfs_difree_finobt( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t agino, struct xfs_inobt_rec_incore *ibtrec) /* inobt record */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; struct xfs_inobt_rec_incore rec; int offset = agino - ibtrec->ir_startino; @@ -2179,7 +2181,7 @@ xfs_difree( /* * Fix up the inode allocation btree. */ - error = xfs_difree_inobt(mp, tp, agbp, pag, agino, xic, &rec); + error = xfs_difree_inobt(pag, tp, agbp, agino, xic, &rec); if (error) goto error0; @@ -2187,7 +2189,7 @@ xfs_difree( * Fix up the free inode btree. */ if (xfs_has_finobt(mp)) { - error = xfs_difree_finobt(mp, tp, agbp, pag, agino, &rec); + error = xfs_difree_finobt(pag, tp, agbp, agino, &rec); if (error) goto error0; } @@ -2909,15 +2911,14 @@ xfs_ialloc_calc_rootino( */ int xfs_ialloc_check_shrink( + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t agno, struct xfs_buf *agibp, xfs_agblock_t new_length) { struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; xfs_agino_t agino = XFS_AGB_TO_AGINO(mp, new_length); int has; int error; @@ -2925,7 +2926,6 @@ xfs_ialloc_check_shrink( if (!xfs_has_sparseinodes(mp)) return 0; - pag = xfs_perag_get(mp, agno); cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO); /* Look up the inobt record that would correspond to the new EOFS. */ @@ -2949,6 +2949,5 @@ xfs_ialloc_check_shrink( } out: xfs_btree_del_cursor(cur, error); - xfs_perag_put(pag); return error; } diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 85462e466029..6cab50e1c3d7 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -107,7 +107,7 @@ int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); void xfs_ialloc_setup_geometry(struct xfs_mount *mp); xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit); -int xfs_ialloc_check_shrink(struct xfs_trans *tp, xfs_agnumber_t agno, +int xfs_ialloc_check_shrink(struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agibp, xfs_agblock_t new_length); #endif /* __XFS_IALLOC_H__ */ From patchwork Fri Dec 3 00:00:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653909 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 35EC2C433F5 for ; Fri, 3 Dec 2021 00:01:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377747AbhLCAEy (ORCPT ); Thu, 2 Dec 2021 19:04:54 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:57888 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377734AbhLCAEx (ORCPT ); Thu, 2 Dec 2021 19:04:53 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id F155F606BFE for ; Fri, 3 Dec 2021 11:01:23 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Ko-Um for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkhj-TV for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 19/36] xfs: inobt can use perags in many more places than it does Date: Fri, 3 Dec 2021 11:00:54 +1100 Message-Id: <20211203000111.2800982-20-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=0ge8BwLW4vw9qPQq:21 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=vkg8fwN_WJCJDa3EOIkA:9 a=_ocrC5ktTllhZKVzGroH:22 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Lots of code in the inobt infrastructure is passed both xfs_mount and perags. We only need perags for the per-ag inode allocation code, so reduce the duplication by passing only the perags as the primary object. This ends up reducing the code size by a bit: text data bss dec hex filename orig 1138878 323979 548 1463405 16546d (TOTALS) patched 1138709 323979 548 1463236 1653c4 (TOTALS) Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag_resv.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 25 +++++++++++---------- fs/xfs/libxfs/xfs_ialloc_btree.c | 37 ++++++++++++++------------------ fs/xfs/libxfs/xfs_ialloc_btree.h | 20 ++++++++--------- fs/xfs/scrub/agheader_repair.c | 7 +++--- fs/xfs/scrub/common.c | 8 +++---- fs/xfs/xfs_iwalk.c | 4 ++-- 7 files changed, 47 insertions(+), 56 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index 5af123d13a63..7fd1fea95552 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -264,7 +264,7 @@ xfs_ag_resv_init( if (error) goto out; - error = xfs_finobt_calc_reserves(mp, tp, pag, &ask, &used); + error = xfs_finobt_calc_reserves(pag, tp, &ask, &used); if (error) goto out; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 894810fece4f..f163531c6756 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -176,13 +176,12 @@ xfs_inobt_insert( xfs_agino_t newlen, xfs_btnum_t btnum) { - struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; xfs_agino_t thisino; int i; int error; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum); + cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum); for (thisino = newino; thisino < newino + newlen; @@ -527,7 +526,7 @@ xfs_inobt_insert_sprec( int i; struct xfs_inobt_rec_incore rec; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum); + cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum); /* the new record is pre-aligned so we know where to look */ error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i); @@ -1004,7 +1003,7 @@ xfs_dialloc_ag_inobt( ASSERT(pag->pagi_freecount > 0); restart_pagno: - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); /* * If pagino is 0 (this is the root inode allocation) use newino. * This must work because we've just allocated some. @@ -1457,7 +1456,7 @@ xfs_dialloc_ag( if (!pagino) pagino = be32_to_cpu(agi->agi_newino); - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO); error = xfs_check_agi_freecount(cur); if (error) @@ -1500,7 +1499,7 @@ xfs_dialloc_ag( * the original freecount. If all is well, make the equivalent update to * the inobt using the finobt record and offset information. */ - icur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + icur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_check_agi_freecount(icur); if (error) @@ -1909,7 +1908,7 @@ xfs_difree_inobt( /* * Initialize the cursor. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_check_agi_freecount(cur); if (error) @@ -2034,7 +2033,7 @@ xfs_difree_finobt( int error; int i; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO); error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i); if (error) @@ -2231,7 +2230,7 @@ xfs_imap_lookup( * we have a record, we need to ensure it contains the inode number * we are looking up. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); if (!error) { if (i) @@ -2918,17 +2917,17 @@ xfs_ialloc_check_shrink( { struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; - struct xfs_mount *mp = tp->t_mountp; - xfs_agino_t agino = XFS_AGB_TO_AGINO(mp, new_length); + xfs_agino_t agino; int has; int error; - if (!xfs_has_sparseinodes(mp)) + if (!xfs_has_sparseinodes(pag->pag_mount)) return 0; - cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agibp, XFS_BTNUM_INO); /* Look up the inobt record that would correspond to the new EOFS. */ + agino = XFS_AGB_TO_AGINO(pag->pag_mount, new_length); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has); if (error || !has) goto out; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 8c83e265770c..d657af2ec350 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -36,8 +36,8 @@ STATIC struct xfs_btree_cur * xfs_inobt_dup_cursor( struct xfs_btree_cur *cur) { - return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, - cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum); + return xfs_inobt_init_cursor(cur->bc_ag.pag, cur->bc_tp, + cur->bc_ag.agbp, cur->bc_btnum); } STATIC void @@ -427,11 +427,11 @@ static const struct xfs_btree_ops xfs_finobt_ops = { */ static struct xfs_btree_cur * xfs_inobt_init_common( - struct xfs_mount *mp, /* file system mount point */ - struct xfs_trans *tp, /* transaction pointer */ struct xfs_perag *pag, + struct xfs_trans *tp, /* transaction pointer */ xfs_btnum_t btnum) /* ialloc or free ino btree */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; cur = xfs_btree_alloc_cursor(mp, tp, btnum, @@ -456,16 +456,15 @@ xfs_inobt_init_common( /* Create an inode btree cursor. */ struct xfs_btree_cur * xfs_inobt_init_cursor( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_btnum_t btnum) { struct xfs_btree_cur *cur; struct xfs_agi *agi = agbp->b_addr; - cur = xfs_inobt_init_common(mp, tp, pag, btnum); + cur = xfs_inobt_init_common(pag, tp, btnum); if (btnum == XFS_BTNUM_INO) cur->bc_nlevels = be32_to_cpu(agi->agi_level); else @@ -477,14 +476,13 @@ xfs_inobt_init_cursor( /* Create an inode btree cursor with a fake root for staging. */ struct xfs_btree_cur * xfs_inobt_stage_cursor( - struct xfs_mount *mp, - struct xbtree_afakeroot *afake, struct xfs_perag *pag, + struct xbtree_afakeroot *afake, xfs_btnum_t btnum) { struct xfs_btree_cur *cur; - cur = xfs_inobt_init_common(mp, NULL, pag, btnum); + cur = xfs_inobt_init_common(pag, NULL, btnum); xfs_btree_stage_afakeroot(cur, afake); return cur; } @@ -708,9 +706,8 @@ xfs_inobt_max_size( /* Read AGI and create inobt cursor. */ int xfs_inobt_cur( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_btnum_t which, struct xfs_btree_cur **curpp, struct xfs_buf **agi_bpp) @@ -725,16 +722,15 @@ xfs_inobt_cur( if (error) return error; - cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, pag, which); + cur = xfs_inobt_init_cursor(pag, tp, *agi_bpp, which); *curpp = cur; return 0; } static int xfs_inobt_count_blocks( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_btnum_t btnum, xfs_extlen_t *tree_blocks) { @@ -742,7 +738,7 @@ xfs_inobt_count_blocks( struct xfs_btree_cur *cur = NULL; int error; - error = xfs_inobt_cur(mp, tp, pag, btnum, &cur, &agbp); + error = xfs_inobt_cur(pag, tp, btnum, &cur, &agbp); if (error) return error; @@ -779,22 +775,21 @@ xfs_finobt_read_blocks( */ int xfs_finobt_calc_reserves( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_extlen_t *ask, xfs_extlen_t *used) { xfs_extlen_t tree_len = 0; int error; - if (!xfs_has_finobt(mp)) + if (!xfs_has_finobt(pag->pag_mount)) return 0; - if (xfs_has_inobtcounts(mp)) + if (xfs_has_inobtcounts(pag->pag_mount)) error = xfs_finobt_read_blocks(pag, tp, &tree_len); else - error = xfs_inobt_count_blocks(mp, tp, pag, XFS_BTNUM_FINO, + error = xfs_inobt_count_blocks(pag, tp, XFS_BTNUM_FINO, &tree_len); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index 26451cb76b98..e859a6e05230 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -46,12 +46,10 @@ struct xfs_perag; (maxrecs) * sizeof(xfs_inobt_key_t) + \ ((index) - 1) * sizeof(xfs_inobt_ptr_t))) -extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_btnum_t btnum); -struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_mount *mp, - struct xbtree_afakeroot *afake, struct xfs_perag *pag, - xfs_btnum_t btnum); +extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_perag *pag, + struct xfs_trans *tp, struct xfs_buf *agbp, xfs_btnum_t btnum); +struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_perag *pag, + struct xbtree_afakeroot *afake, xfs_btnum_t btnum); extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); /* ir_holemask to inode allocation bitmap conversion */ @@ -64,13 +62,13 @@ int xfs_inobt_rec_check_count(struct xfs_mount *, #define xfs_inobt_rec_check_count(mp, rec) 0 #endif /* DEBUG */ -int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, - struct xfs_perag *pag, xfs_extlen_t *ask, xfs_extlen_t *used); +int xfs_finobt_calc_reserves(struct xfs_perag *perag, struct xfs_trans *tp, + xfs_extlen_t *ask, xfs_extlen_t *used); extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, unsigned long long len); -int xfs_inobt_cur(struct xfs_mount *mp, struct xfs_trans *tp, - struct xfs_perag *pag, xfs_btnum_t btnum, - struct xfs_btree_cur **curpp, struct xfs_buf **agi_bpp); +int xfs_inobt_cur(struct xfs_perag *pag, struct xfs_trans *tp, + xfs_btnum_t btnum, struct xfs_btree_cur **curpp, + struct xfs_buf **agi_bpp); void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 384fbef097e8..1f1947b7cd45 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -808,8 +808,7 @@ xrep_agi_calc_from_btrees( xfs_agino_t freecount; int error; - cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, - sc->sa.pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, XFS_BTNUM_INO); error = xfs_ialloc_count_inodes(cur, &count, &freecount); if (error) goto err; @@ -829,8 +828,8 @@ xrep_agi_calc_from_btrees( if (xfs_has_finobt(mp) && xfs_has_inobtcounts(mp)) { xfs_agblock_t blocks; - cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, - sc->sa.pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, + XFS_BTNUM_FINO); error = xfs_btree_count_blocks(cur, &blocks); if (error) goto err; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index d56ce408d4d2..bd6faa508c2b 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -480,15 +480,15 @@ xchk_ag_btcur_init( /* Set up a inobt cursor for cross-referencing. */ if (sa->agi_bp && xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) { - sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - sa->pag, XFS_BTNUM_INO); + sa->ino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp, + XFS_BTNUM_INO); } /* Set up a finobt cursor for cross-referencing. */ if (sa->agi_bp && xfs_has_finobt(mp) && xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) { - sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - sa->pag, XFS_BTNUM_FINO); + sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp, + XFS_BTNUM_FINO); } /* Set up a rmapbt cursor for cross-referencing. */ diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index c31857d903a4..21be93bf006d 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -275,7 +275,7 @@ xfs_iwalk_ag_start( /* Set up a fresh cursor and empty the inobt cache. */ iwag->nr_recs = 0; - error = xfs_inobt_cur(mp, tp, pag, XFS_BTNUM_INO, curpp, agi_bpp); + error = xfs_inobt_cur(pag, tp, XFS_BTNUM_INO, curpp, agi_bpp); if (error) return error; @@ -390,7 +390,7 @@ xfs_iwalk_run_callbacks( } /* ...and recreate the cursor just past where we left off. */ - error = xfs_inobt_cur(mp, iwag->tp, iwag->pag, XFS_BTNUM_INO, curpp, + error = xfs_inobt_cur(iwag->pag, iwag->tp, XFS_BTNUM_INO, curpp, agi_bpp); if (error) return error; From patchwork Fri Dec 3 00:00:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653867 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 0E537C4321E for ; Fri, 3 Dec 2021 00:01:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377730AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35761 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349732AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id CB537869D47 for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0o-00G1Kq-Ve for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkho-Uj for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:14 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 20/36] xfs: convert xfs_ialloc_next_ag() to an atomic Date: Fri, 3 Dec 2021 11:00:55 +1100 Message-Id: <20211203000111.2800982-21-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4c a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=7GaMYM1hFZgjFW6SNswA:9 a=7Zwj6sZBwVKJAoWSPKxL6X1jA+E=:19 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner This is currently a spinlock lock protected rotor which can be implemented with a single atomic operation. Change it to be more efficient and get rid of the m_agirotor_lock. Noticed while converting the inode allocation AG selection loop to active perag references. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc.c | 17 +---------------- fs/xfs/libxfs/xfs_sb.c | 3 ++- fs/xfs/xfs_mount.h | 3 +-- fs/xfs/xfs_super.c | 1 - 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index f163531c6756..71af060daa53 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1576,21 +1576,6 @@ xfs_dialloc_roll( return error; } -static xfs_agnumber_t -xfs_ialloc_next_ag( - xfs_mount_t *mp) -{ - xfs_agnumber_t agno; - - spin_lock(&mp->m_agirotor_lock); - agno = mp->m_agirotor; - if (++mp->m_agirotor >= mp->m_maxagi) - mp->m_agirotor = 0; - spin_unlock(&mp->m_agirotor_lock); - - return agno; -} - static bool xfs_dialloc_good_ag( struct xfs_perag *pag, @@ -1747,7 +1732,7 @@ xfs_dialloc( * an AG has enough space for file creation. */ if (S_ISDIR(mode)) - start_agno = xfs_ialloc_next_ag(mp); + start_agno = atomic_inc_return(&mp->m_agirotor) % mp->m_maxagi; else { start_agno = XFS_INO_TO_AGNO(mp, parent); if (start_agno >= mp->m_maxagi) diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 96f06e11ce58..0ba76faae00a 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -865,7 +865,8 @@ xfs_sb_mount_common( struct xfs_mount *mp, struct xfs_sb *sbp) { - mp->m_agfrotor = mp->m_agirotor = 0; + mp->m_agfrotor = 0; + atomic_set(&mp->m_agirotor, 0); mp->m_maxagi = mp->m_sb.sb_agcount; mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 00720a02e761..09033a30c79f 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -208,8 +208,7 @@ typedef struct xfs_mount { struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX]; struct xstats m_stats; /* per-fs stats */ xfs_agnumber_t m_agfrotor; /* last ag where space found */ - xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ - spinlock_t m_agirotor_lock;/* .. and lock protecting it */ + atomic_t m_agirotor; /* last ag dir inode alloced */ /* Memory shrinker to throttle and reprioritize inodegc */ struct shrinker m_inodegc_shrinker; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e21459f9923a..53f6cb337fa3 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1903,7 +1903,6 @@ static int xfs_init_fs_context( return -ENOMEM; spin_lock_init(&mp->m_sb_lock); - spin_lock_init(&mp->m_agirotor_lock); INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); spin_lock_init(&mp->m_perag_lock); mutex_init(&mp->m_growlock); From patchwork Fri Dec 3 00:00:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653923 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 E1CD9C4332F for ; Fri, 3 Dec 2021 00:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377756AbhLCAFA (ORCPT ); Thu, 2 Dec 2021 19:05:00 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:58768 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377754AbhLCAE6 (ORCPT ); Thu, 2 Dec 2021 19:04:58 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id C5B34606A5C for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1Kv-0x for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0o-00Bkht-Vd for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 21/36] xfs: perags need atomic operational state Date: Fri, 3 Dec 2021 11:00:56 +1100 Message-Id: <20211203000111.2800982-22-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4e a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=hQBwmWMCgzfmfVEtOkMA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We currently don't have any flags or operational state in the xfs_perag except for the pagf_init and pagi_init flags. And the agflreset flag. Oh, there's also the pagf_metadata and pagi_inodeok flags, too. For controlling per-ag operations, we are going to need some atomic state flags. Hence add an opstate field similar to what we already have in the mount and log, and convert all these state flags across to atomic bit operations. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.h | 27 ++++++++++++++---- fs/xfs/libxfs/xfs_alloc.c | 23 ++++++++------- fs/xfs/libxfs/xfs_alloc_btree.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 14 ++++----- fs/xfs/libxfs/xfs_ialloc_btree.c | 4 +-- fs/xfs/libxfs/xfs_refcount_btree.c | 2 +- fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- fs/xfs/scrub/agheader_repair.c | 28 +++++++++--------- fs/xfs/scrub/fscounters.c | 9 ++++-- fs/xfs/scrub/repair.c | 2 +- fs/xfs/xfs_filestream.c | 5 ++-- fs/xfs/xfs_super.c | 46 ++++++++++++++++++------------ 13 files changed, 101 insertions(+), 65 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index b36d5725c91c..3b5e9c5f737b 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -35,13 +35,9 @@ struct xfs_perag { atomic_t pag_ref; /* passive reference count */ atomic_t pag_active_ref; /* active reference count */ wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */ - char pagf_init; /* this agf's entry is initialized */ - char pagi_init; /* this agi's entry is initialized */ - char pagf_metadata; /* the agf is preferred to be metadata */ - char pagi_inodeok; /* The agi is ok for inodes */ + unsigned long pag_opstate; uint8_t pagf_levels[XFS_BTNUM_AGF]; /* # of levels in bno & cnt btree */ - bool pagf_agflreset; /* agfl requires reset before use */ uint32_t pagf_flcount; /* count of blocks in freelist */ xfs_extlen_t pagf_freeblks; /* total free blocks */ xfs_extlen_t pagf_longest; /* longest free space */ @@ -114,6 +110,27 @@ struct xfs_perag { #endif /* __KERNEL__ */ }; +/* + * Per-AG operational state. These are atomic flag bits. + */ +#define XFS_AGSTATE_AGF_INIT 0 +#define XFS_AGSTATE_AGI_INIT 1 +#define XFS_AGSTATE_PREFERS_METADATA 2 +#define XFS_AGSTATE_ALLOWS_INODES 3 +#define XFS_AGSTATE_AGFL_NEEDS_RESET 4 + +#define __XFS_AG_OPSTATE(name, NAME) \ +static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \ +{ \ + return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \ +} + +__XFS_AG_OPSTATE(initialised_agf, AGF_INIT) +__XFS_AG_OPSTATE(initialised_agi, AGI_INIT) +__XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA) +__XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES) +__XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET) + int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi); int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index c0f345ba198b..34a3df5f85b7 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2421,7 +2421,7 @@ xfs_agfl_reset( struct xfs_mount *mp = tp->t_mountp; struct xfs_agf *agf = agbp->b_addr; - ASSERT(pag->pagf_agflreset); + ASSERT(xfs_perag_agfl_needs_reset(pag)); trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_); xfs_warn(mp, @@ -2436,7 +2436,7 @@ xfs_agfl_reset( XFS_AGF_FLCOUNT); pag->pagf_flcount = 0; - pag->pagf_agflreset = false; + clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate); } /* @@ -2591,7 +2591,7 @@ xfs_alloc_fix_freelist( /* deferred ops (AGFL block frees) require permanent transactions */ ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ @@ -2606,7 +2606,8 @@ xfs_alloc_fix_freelist( * somewhere else if we are not being asked to try harder at this * point */ - if (pag->pagf_metadata && (args->datatype & XFS_ALLOC_USERDATA) && + if (xfs_perag_prefers_metadata(pag) && + (args->datatype & XFS_ALLOC_USERDATA) && (flags & XFS_ALLOC_FLAG_TRYLOCK)) { ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); goto out_agbp_relse; @@ -2632,7 +2633,7 @@ xfs_alloc_fix_freelist( } /* reset a padding mismatched agfl before final free space check */ - if (pag->pagf_agflreset) + if (xfs_perag_agfl_needs_reset(pag)) xfs_agfl_reset(tp, agbp, pag); /* If there isn't enough total space or single-extent, reject it. */ @@ -2789,7 +2790,7 @@ xfs_alloc_get_freelist( if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp)) agf->agf_flfirst = 0; - ASSERT(!pag->pagf_agflreset); + ASSERT(!xfs_perag_agfl_needs_reset(pag)); be32_add_cpu(&agf->agf_flcount, -1); pag->pagf_flcount--; @@ -2878,7 +2879,7 @@ xfs_alloc_put_freelist( if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp)) agf->agf_fllast = 0; - ASSERT(!pag->pagf_agflreset); + ASSERT(!xfs_perag_agfl_needs_reset(pag)); be32_add_cpu(&agf->agf_flcount, 1); pag->pagf_flcount++; @@ -3085,7 +3086,7 @@ xfs_alloc_read_agf( return error; agf = agfbp->b_addr; - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); @@ -3097,8 +3098,8 @@ xfs_alloc_read_agf( pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); - pag->pagf_init = 1; - pag->pagf_agflreset = xfs_agfl_needs_reset(pag->pag_mount, agf); + if (xfs_agfl_needs_reset(pag->pag_mount, agf)) + set_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate); /* * Update the in-core allocbt counter. Filter out the rmapbt @@ -3112,6 +3113,8 @@ xfs_alloc_read_agf( allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1; if (allocbt_blks > 0) atomic64_add(allocbt_blks, &pag->pag_mount->m_allocbt_blks); + + set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); } #ifdef DEBUG else if (!xfs_is_shutdown(pag->pag_mount)) { diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 549a3cba0234..0f29c7b1b39f 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -315,7 +315,7 @@ xfs_allocbt_verify( level = be16_to_cpu(block->bb_level); if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) btnum = XFS_BTNUM_CNTi; - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_levels[btnum]) return __this_address; } else if (level >= mp->m_alloc_maxlevels) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ec856466ed40..3369cbfbb9f1 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3186,7 +3186,7 @@ xfs_bmap_longest_free_extent( int error = 0; pag = xfs_perag_get(mp, ag); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); if (error) { diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 71af060daa53..c98fffef891e 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -998,8 +998,8 @@ xfs_dialloc_ag_inobt( int i, j; int searchdistance = 10; - ASSERT(pag->pagi_init); - ASSERT(pag->pagi_inodeok); + ASSERT(xfs_perag_initialised_agi(pag)); + ASSERT(xfs_perag_allows_inodes(pag)); ASSERT(pag->pagi_freecount > 0); restart_pagno: @@ -1592,10 +1592,10 @@ xfs_dialloc_good_ag( if (!pag) return false; - if (!pag->pagi_inodeok) + if (!xfs_perag_allows_inodes(pag)) return false; - if (!pag->pagi_init) { + if (!xfs_perag_initialised_agi(pag)) { error = xfs_ialloc_read_agi(pag, tp, NULL); if (error) return false; @@ -1606,7 +1606,7 @@ xfs_dialloc_good_ag( if (!ok_alloc) return false; - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, flags, NULL); if (error) return false; @@ -2586,10 +2586,10 @@ xfs_ialloc_read_agi( return error; agi = agibp->b_addr; - if (!pag->pagi_init) { + if (!xfs_perag_initialised_agi(pag)) { pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); pag->pagi_count = be32_to_cpu(agi->agi_count); - pag->pagi_init = 1; + set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); } /* diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index d657af2ec350..3675a0d29310 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -291,8 +291,8 @@ xfs_inobt_verify( * Similarly, during log recovery we will have a perag structure * attached, but the agi information will not yet have been initialised * from the on disk AGI. We don't currently use any of this information, - * but beware of the landmine (i.e. need to check pag->pagi_init) if we - * ever do. + * but beware of the landmine (i.e. need to check + * xfs_perag_initialised_agi(pag)) if we ever do. */ if (xfs_has_crc(mp)) { fa = xfs_btree_sblock_v5hdr_verify(bp); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 316c1ec0c3c2..938e804d420f 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -218,7 +218,7 @@ xfs_refcountbt_verify( return fa; level = be16_to_cpu(block->bb_level); - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_refcount_level) return __this_address; } else if (level >= mp->m_refc_maxlevels) diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 7f83f62e51e0..d3285684bb5e 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -313,7 +313,7 @@ xfs_rmapbt_verify( return fa; level = be16_to_cpu(block->bb_level); - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) return __this_address; } else if (level >= mp->m_rmap_maxlevels) diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 1f1947b7cd45..839ef878b227 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -179,14 +179,15 @@ xrep_agf_init_header( struct xfs_agf *old_agf) { struct xfs_mount *mp = sc->mp; + struct xfs_perag *pag = sc->sa.pag; struct xfs_agf *agf = agf_bp->b_addr; memcpy(old_agf, agf, sizeof(*old_agf)); memset(agf, 0, BBTOB(agf_bp->b_length)); agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); - agf->agf_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agf->agf_length = cpu_to_be32(sc->sa.pag->block_count); + agf->agf_seqno = cpu_to_be32(pag->pag_agno); + agf->agf_length = cpu_to_be32(pag->block_count); agf->agf_flfirst = old_agf->agf_flfirst; agf->agf_fllast = old_agf->agf_fllast; agf->agf_flcount = old_agf->agf_flcount; @@ -194,8 +195,8 @@ xrep_agf_init_header( uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); /* Mark the incore AGF data stale until we're done fixing things. */ - ASSERT(sc->sa.pag->pagf_init); - sc->sa.pag->pagf_init = 0; + ASSERT(xfs_perag_initialised_agf(pag)); + clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); } /* Set btree root information in an AGF. */ @@ -321,7 +322,7 @@ xrep_agf_commit_new( pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); - pag->pagf_init = 1; + set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); return 0; } @@ -422,7 +423,7 @@ xrep_agf( out_revert: /* Mark the incore AGF state stale and revert the AGF. */ - sc->sa.pag->pagf_init = 0; + clear_bit(XFS_AGSTATE_AGF_INIT, &sc->sa.pag->pag_opstate); memcpy(agf, &old_agf, sizeof(old_agf)); return error; } @@ -552,7 +553,7 @@ xrep_agfl_update_agf( xfs_force_summary_recalc(sc->mp); /* Update the AGF counters. */ - if (sc->sa.pag->pagf_init) + if (xfs_perag_initialised_agf(sc->sa.pag)) sc->sa.pag->pagf_flcount = flcount; agf->agf_flfirst = cpu_to_be32(0); agf->agf_flcount = cpu_to_be32(flcount); @@ -757,14 +758,15 @@ xrep_agi_init_header( struct xfs_agi *old_agi) { struct xfs_agi *agi = agi_bp->b_addr; + struct xfs_perag *pag = sc->sa.pag; struct xfs_mount *mp = sc->mp; memcpy(old_agi, agi, sizeof(*old_agi)); memset(agi, 0, BBTOB(agi_bp->b_length)); agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); - agi->agi_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agi->agi_length = cpu_to_be32(sc->sa.pag->block_count); + agi->agi_seqno = cpu_to_be32(pag->pag_agno); + agi->agi_length = cpu_to_be32(pag->block_count); agi->agi_newino = cpu_to_be32(NULLAGINO); agi->agi_dirino = cpu_to_be32(NULLAGINO); if (xfs_has_crc(mp)) @@ -775,8 +777,8 @@ xrep_agi_init_header( sizeof(agi->agi_unlinked)); /* Mark the incore AGF data stale until we're done fixing things. */ - ASSERT(sc->sa.pag->pagi_init); - sc->sa.pag->pagi_init = 0; + ASSERT(xfs_perag_initialised_agi(pag)); + clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); } /* Set btree root information in an AGI. */ @@ -863,7 +865,7 @@ xrep_agi_commit_new( pag = sc->sa.pag; pag->pagi_count = be32_to_cpu(agi->agi_count); pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); - pag->pagi_init = 1; + set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); return 0; } @@ -928,7 +930,7 @@ xrep_agi( out_revert: /* Mark the incore AGI state stale and revert the AGI. */ - sc->sa.pag->pagi_init = 0; + clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate); memcpy(agi, &old_agi, sizeof(old_agi)); return error; } diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 3706296c61b6..9412a70b7922 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -74,7 +74,8 @@ xchk_fscount_warmup( for_each_perag(mp, agno, pag) { if (xchk_should_terminate(sc, &error)) break; - if (pag->pagi_init && pag->pagf_init) + if (xfs_perag_initialised_agi(pag) && + xfs_perag_initialised_agf(pag)) continue; /* Lock both AG headers. */ @@ -89,7 +90,8 @@ xchk_fscount_warmup( * These are supposed to be initialized by the header read * function. */ - if (!pag->pagi_init || !pag->pagf_init) { + if (!xfs_perag_initialised_agi(pag) || + !xfs_perag_initialised_agf(pag)) { error = -EFSCORRUPTED; break; } @@ -195,7 +197,8 @@ xchk_fscount_aggregate_agcounts( break; /* This somehow got unset since the warmup? */ - if (!pag->pagi_init || !pag->pagf_init) { + if (!xfs_perag_initialised_agi(pag) || + !xfs_perag_initialised_agf(pag)) { error = -EFSCORRUPTED; break; } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 992d66453264..d2331d515758 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -193,7 +193,7 @@ xrep_calc_ag_resblks( return 0; pag = xfs_perag_get(mp, sm->sm_agno); - if (pag->pagi_init) { + if (xfs_perag_initialised_agi(pag)) { /* Use in-core icount if possible. */ icount = pag->pagi_count; } else { diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index fe7a809e230c..e83e297d1b75 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -125,7 +125,7 @@ xfs_filestream_pick_ag( pag = xfs_perag_get(mp, ag); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { err = xfs_alloc_read_agf(pag, NULL, trylock, NULL); if (err) { xfs_perag_put(pag); @@ -158,7 +158,8 @@ xfs_filestream_pick_ag( xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE)); if (((minlen && longest >= minlen) || (!minlen && pag->pagf_freeblks >= minfree)) && - (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) || + (!xfs_perag_prefers_metadata(pag) || + !(flags & XFS_PICK_USERDATA) || (flags & XFS_PICK_LOWSPACE))) { /* Break out, retaining the reference on the AG. */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 53f6cb337fa3..ad6eadc90be7 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -244,6 +244,32 @@ xfs_fs_show_options( return 0; } +static bool +xfs_set_inode_alloc_perag( + struct xfs_perag *pag, + xfs_ino_t ino, + xfs_agnumber_t max_metadata) +{ + if (!xfs_is_inode32(pag->pag_mount)) { + set_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return false; + } + + if (ino > XFS_MAXINUMBER_32) { + clear_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return false; + } + + set_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + if (pag->pag_agno < max_metadata) + set_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + else + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return true; +} + /* * Set parameters for inode allocation heuristics, taking into account * filesystem size and inode32/inode64 mount options; i.e. specifically @@ -307,24 +333,8 @@ xfs_set_inode_alloc( ino = XFS_AGINO_TO_INO(mp, index, agino); pag = xfs_perag_get(mp, index); - - if (xfs_is_inode32(mp)) { - if (ino > XFS_MAXINUMBER_32) { - pag->pagi_inodeok = 0; - pag->pagf_metadata = 0; - } else { - pag->pagi_inodeok = 1; - maxagi++; - if (index < max_metadata) - pag->pagf_metadata = 1; - else - pag->pagf_metadata = 0; - } - } else { - pag->pagi_inodeok = 1; - pag->pagf_metadata = 0; - } - + if (xfs_set_inode_alloc_perag(pag, ino, max_metadata)) + maxagi++; xfs_perag_put(pag); } From patchwork Fri Dec 3 00:00:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653877 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 255CEC4167E for ; Fri, 3 Dec 2021 00:01:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349732AbhLCAEp (ORCPT ); Thu, 2 Dec 2021 19:04:45 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:36169 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377732AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id C5472869D6F for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1Kx-22 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkhy-0w for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 22/36] xfs: introduce xfs_for_each_perag_wrap() Date: Fri, 3 Dec 2021 11:00:57 +1100 Message-Id: <20211203000111.2800982-23-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4e a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=MV_ybV5dVvQxcgh8FT0A:9 a=7Zwj6sZBwVKJAoWSPKxL6X1jA+E=:19 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner In several places we iterate every AG from a specific start agno and wrap back to the first AG when we reach the end of the filesystem to continue searching. We don't have a primitive for this iteration yet, so add one for conversion of these algorithms to per-ag based iteration. The filestream AG select code is a mess, and this initially makes it worse. The per-ag selection needs to be driven completely into the filesystem code to clean this up and it will be done in a future patch that makes the filestream allocator use active per-ag references correctly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.h | 45 +++++++++++++++++++++- fs/xfs/libxfs/xfs_bmap.c | 76 ++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_ialloc.c | 32 ++++++++-------- 3 files changed, 104 insertions(+), 49 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 3b5e9c5f737b..23040a1094b9 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -228,7 +228,6 @@ xfs_perag_next( #define for_each_perag_from(mp, agno, pag) \ for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag)) - #define for_each_perag(mp, agno, pag) \ (agno) = 0; \ for_each_perag_from((mp), (agno), (pag)) @@ -240,6 +239,50 @@ xfs_perag_next( xfs_perag_rele(pag), \ (pag) = xfs_perag_grab_tag((mp), (agno), (tag))) +static inline struct xfs_perag * +xfs_perag_next_wrap( + struct xfs_perag *pag, + xfs_agnumber_t *agno, + xfs_agnumber_t stop_agno, + xfs_agnumber_t wrap_agno) +{ + struct xfs_mount *mp = pag->pag_mount; + + *agno = pag->pag_agno + 1; + xfs_perag_rele(pag); + while (*agno != stop_agno) { + if (*agno >= wrap_agno) + *agno = 0; + if (*agno == stop_agno) + break; + + pag = xfs_perag_grab(mp, *agno); + if (pag) + return pag; + (*agno)++; + } + return NULL; +} + +/* + * Iterate all AGs from start_agno through wrap_agno, then 0 through + * (start_agno - 1). + */ +#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ + for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \ + (pag) != NULL; \ + (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \ + (wrap_agno))) + +/* + * Iterate all AGs from start_agno through to the end of the filesystem, then 0 + * through (start_agno - 1). + */ +#define for_each_perag_wrap(mp, start_agno, agno, pag) \ + for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \ + (agno), (pag)) + + struct aghdr_init_data { /* per ag data */ xfs_agblock_t agno; /* ag to init */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 3369cbfbb9f1..e9e039d8ba62 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3175,17 +3175,14 @@ xfs_bmap_adjacent( static int xfs_bmap_longest_free_extent( + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t ag, xfs_extlen_t *blen, int *notinit) { - struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; xfs_extlen_t longest; int error = 0; - pag = xfs_perag_get(mp, ag); if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); @@ -3195,19 +3192,17 @@ xfs_bmap_longest_free_extent( *notinit = 1; error = 0; } - goto out; + return error; } } longest = xfs_alloc_longest_free_extent(pag, - xfs_alloc_min_freelist(mp, pag), + xfs_alloc_min_freelist(pag->pag_mount, pag), xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE)); if (*blen < longest) *blen = longest; -out: - xfs_perag_put(pag); - return error; + return 0; } static void @@ -3245,28 +3240,29 @@ xfs_bmap_btalloc_nullfb( xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; - xfs_agnumber_t ag, startag; + struct xfs_perag *pag; + xfs_agnumber_t agno, startag; int notinit = 0; - int error; + int error = 0; args->type = XFS_ALLOCTYPE_START_BNO; args->total = ap->total; - startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); + startag = XFS_FSB_TO_AGNO(mp, args->fsbno); if (startag == NULLAGNUMBER) - startag = ag = 0; + startag = 0; - while (*blen < args->maxlen) { - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, + *blen = 0; + for_each_perag_wrap(mp, startag, agno, pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen, ¬init); if (error) - return error; - - if (++ag == mp->m_sb.sb_agcount) - ag = 0; - if (ag == startag) + break; + if (*blen >= args->maxlen) break; } + if (pag) + xfs_perag_rele(pag); xfs_bmap_select_minlen(ap, args, blen, notinit); return 0; @@ -3279,40 +3275,58 @@ xfs_bmap_btalloc_filestreams( xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; - xfs_agnumber_t ag; + struct xfs_perag *pag; + xfs_agnumber_t start_agno; int notinit = 0; int error; args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; - ag = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (ag == NULLAGNUMBER) - ag = 0; + start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (start_agno == NULLAGNUMBER) + start_agno = 0; - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, ¬init); - if (error) - return error; + pag = xfs_perag_grab(mp, start_agno); + if (pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen, + ¬init); + xfs_perag_rele(pag); + if (error) + return error; + } if (*blen < args->maxlen) { - error = xfs_filestream_new_ag(ap, &ag); + xfs_agnumber_t agno = start_agno; + + error = xfs_filestream_new_ag(ap, &agno); if (error) return error; + if (agno == NULLAGNUMBER) + goto out_select; - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, - ¬init); + pag = xfs_perag_grab(mp, agno); + if (!pag) + goto out_select; + + error = xfs_bmap_longest_free_extent(pag, args->tp, + blen, ¬init); + xfs_perag_rele(pag); if (error) return error; + start_agno = agno; + } +out_select: xfs_bmap_select_minlen(ap, args, blen, notinit); /* * Set the failure fallback case to look in the selected AG as stream * may have moved. */ - ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); + ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0); return 0; } diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c98fffef891e..a155b3cc1e14 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1724,7 +1724,7 @@ xfs_dialloc( struct xfs_ino_geometry *igeo = M_IGEO(mp); bool ok_alloc = true; int flags; - xfs_ino_t ino; + xfs_ino_t ino = NULLFSINO; /* * Directories, symlinks, and regular files frequently allocate at least @@ -1758,37 +1758,35 @@ xfs_dialloc( * or in which we can allocate some inodes. Iterate through the * allocation groups upward, wrapping at the end. */ - agno = start_agno; flags = XFS_ALLOC_FLAG_TRYLOCK; - for (;;) { - pag = xfs_perag_grab(mp, agno); +retry: + for_each_perag_wrap_at(mp, start_agno, mp->m_maxagi, agno, pag) { if (xfs_dialloc_good_ag(pag, *tpp, mode, flags, ok_alloc)) { error = xfs_dialloc_try_ag(pag, tpp, parent, &ino, ok_alloc); if (error != -EAGAIN) break; + error = 0; } if (xfs_is_shutdown(mp)) { error = -EFSCORRUPTED; break; } - if (++agno == mp->m_maxagi) - agno = 0; - if (agno == start_agno) { - if (!flags) { - error = -ENOSPC; - break; - } + } + if (pag) + xfs_perag_rele(pag); + if (error) + return error; + if (ino == NULLFSINO) { + if (flags) { flags = 0; + goto retry; } - xfs_perag_rele(pag); + return -ENOSPC; } - - if (!error) - *new_ino = ino; - xfs_perag_rele(pag); - return error; + *new_ino = ino; + return 0; } /* From patchwork Fri Dec 3 00:00:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653879 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 9E885C4167D for ; Fri, 3 Dec 2021 00:01:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243809AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:36109 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349796AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id E5F10869BBB for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1L0-3D for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bki3-20 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 23/36] xfs: rework xfs_alloc_vextent() Date: Fri, 3 Dec 2021 11:00:58 +1100 Message-Id: <20211203000111.2800982-24-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=xH7Vk06bEwDpKNwPjcgA:9 a=7Zwj6sZBwVKJAoWSPKxL6X1jA+E=:19 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner It's a multiplexing mess that can be greatly simplified, and really needs to be simplified to allow active per-ag references to propagate from initial AG selection code the the bmapi code. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 398 ++++++++++++++++++++++++-------------- 1 file changed, 255 insertions(+), 143 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 34a3df5f85b7..0e259786d522 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3136,26 +3136,20 @@ xfs_alloc_read_agf( } /* - * Allocate an extent (variable-size). - * Depending on the allocation type, we either look in a single allocation - * group or loop over the allocation groups to find the result. + * Pre-proces allocation arguments to set initial state that we don't require + * callers to set up correctly, as well as bounds check the allocation args + * that are set up. */ -int /* error */ -xfs_alloc_vextent( - struct xfs_alloc_arg *args) /* allocation argument structure */ +static int +xfs_alloc_vextent_check_args( + struct xfs_alloc_arg *args) { - xfs_agblock_t agsize; /* allocation group size */ - int error; - int flags; /* XFS_ALLOC_FLAG_... locking flags */ - struct xfs_mount *mp; /* mount structure pointer */ - xfs_agnumber_t sagno; /* starting allocation group number */ - xfs_alloctype_t type; /* input allocation type */ - int bump_rotor = 0; - xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ - - mp = args->mp; - type = args->otype = args->type; + struct xfs_mount *mp = args->mp; + xfs_agblock_t agsize; + + args->otype = args->type; args->agbno = NULLAGBLOCK; + /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure @@ -3177,157 +3171,275 @@ xfs_alloc_vextent( args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; trace_xfs_alloc_vextent_badargs(args); - return 0; + return -ENOSPC; } + return 0; +} +/* + * Post-process allocation results to set the allocated block number correctly + * for the caller. + * + * XXX: xfs_alloc_vextent() should really be returning ENOSPC for ENOSPC, not + * hiding it behind a "successful" NULLFSBLOCK allocation. + */ +static void +xfs_alloc_vextent_set_fsbno( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; - switch (type) { - case XFS_ALLOCTYPE_THIS_AG: - case XFS_ALLOCTYPE_NEAR_BNO: - case XFS_ALLOCTYPE_THIS_BNO: - /* - * These three force us into a single a.g. - */ - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + /* Allocation failed with ENOSPC if NULLAGBLOCK was returned. */ + if (args->agbno == NULLAGBLOCK) { + args->fsbno = NULLFSBLOCK; + return; + } + + args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); +#ifdef DEBUG + ASSERT(args->len >= args->minlen); + ASSERT(args->len <= args->maxlen); + ASSERT(args->agbno % args->alignment == 0); + XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); +#endif +} + +/* + * Allocate within a single AG only. + */ +static int +xfs_alloc_vextent_this_ag( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + args->pag = xfs_perag_get(mp, args->agno); + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + goto out_error; + } + if (!args->agbp) { + trace_xfs_alloc_vextent_noagbp(args); + goto out_error; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + error = xfs_alloc_ag_vextent(args); + if (error) + goto out_error; + + xfs_alloc_vextent_set_fsbno(args); +out_error: + xfs_perag_put(args->pag); + return error; +} + +/* + * Iterate all AGs trying to allocate an extent starting from @start_ag. + * + * If the + * incoming allocation type is XFS_ALLOCTYPE_NEAR_BNO, it means the allocation + * attempts in @start_agno have locality information. If we fail to allocate in + * that AG, then we revert to anywhere-in-AG for all the other AGs we attempt to + * allocation in as there is no locality optimisation possible for those + * allocations. + * + * When we wrap the AG iteration at the end of the filesystem, we have to be + * careful not to wrap into AGs below ones we already have locked in the + * transaction. This will result in an out-of-order locking of AGFs and hence + * can cause deadlocks. + * + * XXX(dgc): when wrapping in potential deadlock scenarios, we could use + * try-locks on the AGFs below the critical AG rather than skip them entirely. + * We won't deadlock in that case, we'll just skip the AGFs we can't lock. + */ +static int +xfs_alloc_vextent_iterate_ags( + struct xfs_alloc_arg *args, + xfs_agnumber_t start_agno, + uint32_t flags) +{ + struct xfs_mount *mp = args->mp; + int error = 0; + + /* + * Loop over allocation groups twice; first time with + * trylock set, second time without. + */ + args->agno = start_agno; + for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, 0); + error = xfs_alloc_fix_freelist(args, flags); if (error) { trace_xfs_alloc_vextent_nofix(args); - goto error0; - } - if (!args->agbp) { - trace_xfs_alloc_vextent_noagbp(args); break; } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - if ((error = xfs_alloc_ag_vextent(args))) - goto error0; - break; - case XFS_ALLOCTYPE_START_BNO: /* - * Try near allocation first, then anywhere-in-ag after - * the first a.g. fails. + * If we get a buffer back then the allocation will fly. */ - if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && - xfs_is_inode32(mp)) { - args->fsbno = XFS_AGB_TO_FSB(mp, - ((mp->m_agfrotor / rotorstep) % - mp->m_sb.sb_agcount), 0); - bump_rotor = 1; + if (args->agbp) { + error = xfs_alloc_ag_vextent(args); + break; } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - fallthrough; - case XFS_ALLOCTYPE_FIRST_AG: + + trace_xfs_alloc_vextent_loopfailed(args); + /* - * Rotate through the allocation groups looking for a winner. + * Didn't work, figure out the next iteration. */ - if (type == XFS_ALLOCTYPE_FIRST_AG) { - /* - * Start with allocation group given by bno. - */ - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (args->agno == start_agno && + args->otype == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; - sagno = 0; - flags = 0; - } else { - /* - * Start with the given allocation group. - */ - args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno); - flags = XFS_ALLOC_FLAG_TRYLOCK; + /* + * For the first allocation, we can try any AG to get + * space. However, if we already have allocated a + * block, we don't want to try AGs whose number is below + * sagno. Otherwise, we may end up with out-of-order + * locking of AGF, which might cause deadlock. + */ + if (++(args->agno) == mp->m_sb.sb_agcount) { + if (args->tp->t_firstblock != NULLFSBLOCK) + args->agno = start_agno; + else + args->agno = 0; } /* - * Loop over allocation groups twice; first time with - * trylock set, second time without. + * Reached the starting a.g., must either be done + * or switch to non-trylock mode. */ - for (;;) { - args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, flags); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - goto error0; - } - /* - * If we get a buffer back then the allocation will fly. - */ - if (args->agbp) { - if ((error = xfs_alloc_ag_vextent(args))) - goto error0; + if (args->agno == start_agno) { + if (flags == 0) { + args->agbno = NULLAGBLOCK; + trace_xfs_alloc_vextent_allfailed(args); break; } - trace_xfs_alloc_vextent_loopfailed(args); - - /* - * Didn't work, figure out the next iteration. - */ - if (args->agno == sagno && - type == XFS_ALLOCTYPE_START_BNO) - args->type = XFS_ALLOCTYPE_THIS_AG; - /* - * For the first allocation, we can try any AG to get - * space. However, if we already have allocated a - * block, we don't want to try AGs whose number is below - * sagno. Otherwise, we may end up with out-of-order - * locking of AGF, which might cause deadlock. - */ - if (++(args->agno) == mp->m_sb.sb_agcount) { - if (args->tp->t_firstblock != NULLFSBLOCK) - args->agno = sagno; - else - args->agno = 0; - } - /* - * Reached the starting a.g., must either be done - * or switch to non-trylock mode. - */ - if (args->agno == sagno) { - if (flags == 0) { - args->agbno = NULLAGBLOCK; - trace_xfs_alloc_vextent_allfailed(args); - break; - } - - flags = 0; - if (type == XFS_ALLOCTYPE_START_BNO) { - args->agbno = XFS_FSB_TO_AGBNO(mp, - args->fsbno); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - } + flags = 0; + if (args->otype == XFS_ALLOCTYPE_START_BNO) { + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->type = XFS_ALLOCTYPE_NEAR_BNO; } - xfs_perag_put(args->pag); - } - if (bump_rotor) { - if (args->agno == sagno) - mp->m_agfrotor = (mp->m_agfrotor + 1) % - (mp->m_sb.sb_agcount * rotorstep); - else - mp->m_agfrotor = (args->agno * rotorstep + 1) % - (mp->m_sb.sb_agcount * rotorstep); } - break; - default: - ASSERT(0); - /* NOTREACHED */ + xfs_perag_put(args->pag); } - if (args->agbno == NULLAGBLOCK) - args->fsbno = NULLFSBLOCK; - else { - args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); -#ifdef DEBUG - ASSERT(args->len >= args->minlen); - ASSERT(args->len <= args->maxlen); - ASSERT(args->agbno % args->alignment == 0); - XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), - args->len); -#endif + xfs_perag_put(args->pag); + return error; +} + +/* + * Iterate from the AGs from the start AG to the end of the filesystem, trying + * to allocate blocks. It starts with a near allocation attempt in the initial + * AG, then falls back to anywhere-in-ag after the first AG fails. It will wrap + * back to zero if allowed by previous allocations in this transaction, + * otherwise will wrap back to the start AG and run a second blocking pass to + * the end of the filesystem. + */ +static int +xfs_alloc_vextent_start_ag( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t start_agno; + xfs_agnumber_t rotorstep = xfs_rotorstep; + bool bump_rotor = false; + int error; + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; } - xfs_perag_put(args->pag); + + if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && + xfs_is_inode32(mp)) { + args->fsbno = XFS_AGB_TO_FSB(mp, + ((mp->m_agfrotor / rotorstep) % + mp->m_sb.sb_agcount), 0); + bump_rotor = 1; + } + start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->type = XFS_ALLOCTYPE_NEAR_BNO; + + error = xfs_alloc_vextent_iterate_ags(args, start_agno, + XFS_ALLOC_FLAG_TRYLOCK); + if (error) + return error; + + if (bump_rotor) { + if (args->agno == start_agno) + mp->m_agfrotor = (mp->m_agfrotor + 1) % + (mp->m_sb.sb_agcount * rotorstep); + else + mp->m_agfrotor = (args->agno * rotorstep + 1) % + (mp->m_sb.sb_agcount * rotorstep); + } + + xfs_alloc_vextent_set_fsbno(args); return 0; -error0: - xfs_perag_put(args->pag); - return error; +} + +/* + * Iterate from the agno indicated from args->fsbno through to the end of the + * filesystem attempting blocking allocation. This does not wrap or try a second + * pass, so will not recurse into AGs lower than indicated by fsbno. + */ +static int +xfs_alloc_vextent_first_ag( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->type = XFS_ALLOCTYPE_THIS_AG; + error = xfs_alloc_vextent_iterate_ags(args, + XFS_FSB_TO_AGNO(mp, args->fsbno), 0); + if (error) + return error; + xfs_alloc_vextent_set_fsbno(args); + return 0; +} + +/* + * Allocate an extent (variable-size). + * Depending on the allocation type, we either look in a single allocation + * group or loop over the allocation groups to find the result. + */ +int +xfs_alloc_vextent( + struct xfs_alloc_arg *args) +{ + switch (args->type) { + case XFS_ALLOCTYPE_THIS_AG: + case XFS_ALLOCTYPE_NEAR_BNO: + case XFS_ALLOCTYPE_THIS_BNO: + return xfs_alloc_vextent_this_ag(args); + case XFS_ALLOCTYPE_START_BNO: + return xfs_alloc_vextent_start_ag(args); + case XFS_ALLOCTYPE_FIRST_AG: + return xfs_alloc_vextent_first_ag(args); + default: + ASSERT(0); + /* NOTREACHED */ + } + /* Should never get here */ + return -EFSCORRUPTED; } /* Ensure that the freelist is at full capacity. */ From patchwork Fri Dec 3 00:00:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653861 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 433ACC4332F for ; Fri, 3 Dec 2021 00:01:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349734AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35729 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349676AbhLCAEm (ORCPT ); Thu, 2 Dec 2021 19:04:42 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id E2BE9869D4E for ; Fri, 3 Dec 2021 11:01:16 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1L2-44 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bki8-3A for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 24/36] xfs: use xfs_alloc_vextent_this_ag() in _iterate_ags() Date: Fri, 3 Dec 2021 11:00:59 +1100 Message-Id: <20211203000111.2800982-25-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=x_O8MFN3wK5gYPUfcAwA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Because the core of the per-ag iteration is calling "this ag" allocation on one AG at a time. This brings the number of callers of xfs_alloc_ag_vextent() down to 1. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 57 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 0e259786d522..9ff6772ee019 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3206,6 +3206,28 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ +static int +__xfs_alloc_vextent_this_ag( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + return xfs_alloc_ag_vextent(args); +} + static int xfs_alloc_vextent_this_ag( struct xfs_alloc_arg *args) @@ -3222,24 +3244,13 @@ xfs_alloc_vextent_this_ag( args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - goto out_error; - } - if (!args->agbp) { - trace_xfs_alloc_vextent_noagbp(args); - goto out_error; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - error = xfs_alloc_ag_vextent(args); + error = __xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); if (error) - goto out_error; + return error; xfs_alloc_vextent_set_fsbno(args); -out_error: - xfs_perag_put(args->pag); - return error; + return 0; } /* @@ -3277,24 +3288,12 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, flags); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - break; - } - /* - * If we get a buffer back then the allocation will fly. - */ - if (args->agbp) { - error = xfs_alloc_ag_vextent(args); + error = __xfs_alloc_vextent_this_ag(args); + if (error || args->agbp) break; - } trace_xfs_alloc_vextent_loopfailed(args); - /* - * Didn't work, figure out the next iteration. - */ if (args->agno == start_agno && args->otype == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; From patchwork Fri Dec 3 00:01:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653905 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 14F77C433F5 for ; Fri, 3 Dec 2021 00:01:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377757AbhLCAEw (ORCPT ); Thu, 2 Dec 2021 19:04:52 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37879 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377751AbhLCAEv (ORCPT ); Thu, 2 Dec 2021 19:04:51 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 5AA23869D90 for ; Fri, 3 Dec 2021 11:01:25 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1L6-50 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00BkiC-3y for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 25/36] xfs: combine __xfs_alloc_vextent_this_ag and xfs_alloc_ag_vextent Date: Fri, 3 Dec 2021 11:01:00 +1100 Message-Id: <20211203000111.2800982-26-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e55 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=1RbyEdk7UIs8VECVR1gA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner THere's a bit of a recursive conundrum around xfs_alloc_ag_vextent(). We can't first call xfs_alloc_ag_vextent() without preparing the AGFL for the allocation, and preparing the AGFL call xfs_alloc_ag_vextent() to prepare the AGFL for the allocation. This "double allocation" requirement is not really clear from the current xfs_alloc_fix_freelist() calls that are sprinkled through the allocation code. It's not helped that xfs_alloc_ag_vextent() can actually allocate from the AGFL itself, but there's special code to prevent AGFL prep allocations from allocating from the free list it's trying to prep. The naming is not clear (args->wasfromfl is true when allocated from the free list, but the indication that we are allocating for the free list is via (args->resv == XFS_AG_RESV_AGFL). So, lets make this "allocation required for allocation" situation clear by moving it all inside xfs_alloc_ag_vextent(). The freelist allocation is a specific XFS_ALLOCTYPE_THIS_AG allocation, which translated directly to xfs_alloc_ag_vextent_size() allocation. This enables us to replace __xfs_alloc_vextent_this_ag() with a call to xfs_alloc_ag_vextent(), and we drive the freelist fixing further into the per-ag allocation algrothim. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 65 +++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 9ff6772ee019..7082f77c38e9 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1126,22 +1126,38 @@ xfs_alloc_ag_vextent_small( * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. */ -STATIC int /* error */ +static int xfs_alloc_ag_vextent( - xfs_alloc_arg_t *args) /* argument structure for allocation */ + struct xfs_alloc_arg *args) { - int error=0; + struct xfs_mount *mp = args->mp; + int error = 0; ASSERT(args->minlen > 0); ASSERT(args->maxlen > 0); ASSERT(args->minlen <= args->maxlen); ASSERT(args->mod < args->prod); ASSERT(args->alignment > 0); + ASSERT(args->resv != XFS_AG_RESV_AGFL); + + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->wasfromfl = 0; /* * Branch to correct routine based on the type. */ - args->wasfromfl = 0; switch (args->type) { case XFS_ALLOCTYPE_THIS_AG: error = xfs_alloc_ag_vextent_size(args); @@ -1162,7 +1178,6 @@ xfs_alloc_ag_vextent( ASSERT(args->len >= args->minlen); ASSERT(args->len <= args->maxlen); - ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL); ASSERT(args->agbno % args->alignment == 0); /* if not file data, insert new block into the reverse map btree */ @@ -2707,7 +2722,7 @@ xfs_alloc_fix_freelist( targs.resv = XFS_AG_RESV_AGFL; /* Allocate as many blocks as possible at once. */ - error = xfs_alloc_ag_vextent(&targs); + error = xfs_alloc_ag_vextent_size(&targs); if (error) goto out_agflbp_relse; @@ -2721,6 +2736,18 @@ xfs_alloc_fix_freelist( break; goto out_agflbp_relse; } + + if (!xfs_rmap_should_skip_owner_update(&targs.oinfo)) { + error = xfs_rmap_alloc(tp, agbp, pag, + targs.agbno, targs.len, &targs.oinfo); + if (error) + goto out_agflbp_relse; + } + error = xfs_alloc_update_counters(tp, agbp, + -((long)(targs.len))); + if (error) + goto out_agflbp_relse; + /* * Put each allocated block on the list. */ @@ -3206,28 +3233,6 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ -static int -__xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) -{ - struct xfs_mount *mp = args->mp; - int error; - - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - return error; - } - if (!args->agbp) { - /* cannot allocate in this AG at all */ - trace_xfs_alloc_vextent_noagbp(args); - args->agbno = NULLAGBLOCK; - return 0; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - return xfs_alloc_ag_vextent(args); -} - static int xfs_alloc_vextent_this_ag( struct xfs_alloc_arg *args) @@ -3244,7 +3249,7 @@ xfs_alloc_vextent_this_ag( args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->pag = xfs_perag_get(mp, args->agno); - error = __xfs_alloc_vextent_this_ag(args); + error = xfs_alloc_ag_vextent(args); xfs_perag_put(args->pag); if (error) return error; @@ -3288,7 +3293,7 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = __xfs_alloc_vextent_this_ag(args); + error = xfs_alloc_ag_vextent(args); if (error || args->agbp) break; From patchwork Fri Dec 3 00:01:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653871 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 15343C43219 for ; Fri, 3 Dec 2021 00:01:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349763AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35729 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349676AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 14900869D54 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1L9-6N for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00BkiH-52 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 26/36] xfs: use xfs_alloc_vextent_this_ag() where appropriate Date: Fri, 3 Dec 2021 11:01:01 +1100 Message-Id: <20211203000111.2800982-27-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=LTYJ9dsPWdyigA4p4SUA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_this_ag(). Drive the per-ag grabbing out to the callers, too, so that callers with active references don't need to do new lookups just for an allocation in a context that already has a perag reference. The only remaining caller that does single AG allocation through xfs_alloc_vextent() is xfs_bmap_btalloc() with XFS_ALLOCTYPE_NEAR_BNO. That is going to need more untangling before it can be converted cleanly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 3 +- fs/xfs/libxfs/xfs_alloc.c | 15 ++++--- fs/xfs/libxfs/xfs_alloc.h | 6 +++ fs/xfs/libxfs/xfs_bmap.c | 71 ++++++++++++++++++------------ fs/xfs/libxfs/xfs_bmap_btree.c | 48 +++++++++++--------- fs/xfs/libxfs/xfs_ialloc.c | 9 ++-- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 +- fs/xfs/libxfs/xfs_refcount_btree.c | 3 +- fs/xfs/scrub/repair.c | 3 +- 9 files changed, 98 insertions(+), 63 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index c866274cb8ce..f210f438db84 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -896,6 +896,7 @@ xfs_ag_shrink_space( struct xfs_alloc_arg args = { .tp = *tpp, .mp = mp, + .pag = pag, .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, @@ -947,7 +948,7 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 7082f77c38e9..78a9cd543a2d 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2709,7 +2709,6 @@ xfs_alloc_fix_freelist( targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = 1; - targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; error = xfs_alloc_read_agfl(pag, tp, &agflbp); if (error) @@ -3233,7 +3232,7 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ -static int +int xfs_alloc_vextent_this_ag( struct xfs_alloc_arg *args) { @@ -3248,9 +3247,7 @@ xfs_alloc_vextent_this_ag( } args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - args->pag = xfs_perag_get(mp, args->agno); error = xfs_alloc_ag_vextent(args); - xfs_perag_put(args->pag); if (error) return error; @@ -3429,11 +3426,15 @@ int xfs_alloc_vextent( struct xfs_alloc_arg *args) { + int error; + switch (args->type) { - case XFS_ALLOCTYPE_THIS_AG: case XFS_ALLOCTYPE_NEAR_BNO: - case XFS_ALLOCTYPE_THIS_BNO: - return xfs_alloc_vextent_this_ag(args); + args->pag = xfs_perag_get(args->mp, + XFS_FSB_TO_AGNO(args->mp, args->fsbno)); + error = xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); + return error; case XFS_ALLOCTYPE_START_BNO: return xfs_alloc_vextent_start_ag(args); case XFS_ALLOCTYPE_FIRST_AG: diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index aa4c8f866cd1..7baf65a23e6e 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -125,6 +125,12 @@ int /* error */ xfs_alloc_vextent( xfs_alloc_arg_t *args); /* allocation argument structure */ +/* + * Allocate an extent in the specific AG defined by args->fsbno. If there is no + * space in that AG, then the allocation will fail. + */ +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); + /* * Free an extent. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e9e039d8ba62..304a0e8cedc8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -646,21 +646,25 @@ xfs_bmap_extents_to_btree( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; + args.minlen = args.maxlen = args.prod = 1; + args.wasdel = wasdel; + *logflagsp = 0; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); if (tp->t_firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); + error = xfs_alloc_vextent(&args); } else if (tp->t_flags & XFS_TRANS_LOWMODE) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = tp->t_firstblock; + error = xfs_alloc_vextent(&args); } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = tp->t_firstblock; + args.pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); } - args.minlen = args.maxlen = args.prod = 1; - args.wasdel = wasdel; - *logflagsp = 0; - error = xfs_alloc_vextent(&args); if (error) goto out_root_realloc; @@ -801,6 +805,8 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; + args.total = total; + args.minlen = args.maxlen = args.prod = 1; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); /* * Allocate a block. We know we need only one, since the @@ -809,13 +815,15 @@ xfs_bmap_local_to_extents( if (tp->t_firstblock == NULLFSBLOCK) { args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); args.type = XFS_ALLOCTYPE_START_BNO; + error = xfs_alloc_vextent(&args); } else { args.fsbno = tp->t_firstblock; args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.pag = xfs_perag_get(args.mp, + XFS_FSB_TO_AGNO(args.mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); } - args.total = total; - args.minlen = args.maxlen = args.prod = 1; - error = xfs_alloc_vextent(&args); if (error) goto done; @@ -3554,7 +3562,6 @@ xfs_bmap_btalloc( xfs_extlen_t nextminlen = 0; int nullfb; /* true if ap->firstblock isn't set */ int isaligned; - int tryagain; int error; int stripe_align; @@ -3592,7 +3599,7 @@ xfs_bmap_btalloc( /* * Normal allocation, done through xfs_alloc_vextent. */ - tryagain = isaligned = 0; + isaligned = 0; args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3623,6 +3630,10 @@ xfs_bmap_btalloc( args.total = ap->total; args.minlen = ap->minlen; } + args.minleft = ap->minleft; + args.wasdel = ap->wasdel; + args.resv = XFS_AG_RESV_NONE; + args.datatype = ap->datatype; /* * If we are not low on available data blocks, and the underlying @@ -3651,9 +3662,9 @@ xfs_bmap_btalloc( * allocation with alignment turned on. */ atype = args.type; - tryagain = 1; args.type = XFS_ALLOCTYPE_THIS_BNO; args.alignment = 1; + /* * Compute the minlen+alignment for the * next case. Set slop so that the value @@ -3670,34 +3681,37 @@ xfs_bmap_btalloc( args.minlen - 1; else args.minalignslop = 0; + + args.pag = xfs_perag_get(mp, + XFS_FSB_TO_AGNO(mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); + if (error) + return error; + + if (args.fsbno != NULLFSBLOCK) + goto out_success; + /* + * Exact allocation failed. Now try with alignment + * turned on. + */ + args.pag = NULL; + args.type = atype; + args.fsbno = ap->blkno; + args.alignment = stripe_align; + args.minlen = nextminlen; + args.minalignslop = 0; + isaligned = 1; } } else { args.alignment = 1; args.minalignslop = 0; } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.resv = XFS_AG_RESV_NONE; - args.datatype = ap->datatype; error = xfs_alloc_vextent(&args); if (error) return error; - if (tryagain && args.fsbno == NULLFSBLOCK) { - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = stripe_align; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } if (isaligned && args.fsbno == NULLFSBLOCK) { /* * allocation failed, so turn off alignment and @@ -3727,6 +3741,7 @@ xfs_bmap_btalloc( } if (args.fsbno != NULLFSBLOCK) { +out_success: xfs_bmap_process_allocated_extent(ap, &args, orig_offset, orig_length); } else { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 453309fc85f2..d7b1016355de 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -21,6 +21,7 @@ #include "xfs_quota.h" #include "xfs_trace.h" #include "xfs_rmap.h" +#include "xfs_ag.h" static struct kmem_cache *xfs_bmbt_cur_cache; @@ -209,6 +210,10 @@ xfs_bmbt_alloc_block( args.fsbno = cur->bc_tp->t_firstblock; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino, cur->bc_ino.whichfork); + args.minlen = args.maxlen = args.prod = 1; + args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; + if (!args.wasdel && args.tp->t_blk_res == 0) + return -ENOSPC; if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); @@ -225,35 +230,36 @@ xfs_bmbt_alloc_block( * block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; + error = xfs_alloc_vextent(&args); + if (error) + goto error0; + + if (args.fsbno == NULLFSBLOCK) { + /* + * Could not find an AG with enough free space to + * satisfy a full btree split. Try again and if + * successful activate the lowspace algorithm. + */ + args.fsbno = 0; + args.type = XFS_ALLOCTYPE_FIRST_AG; + error = xfs_alloc_vextent(&args); + if (error) + goto error0; + cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; + } } else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) { args.type = XFS_ALLOCTYPE_START_BNO; + error = xfs_alloc_vextent(&args); } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.pag = xfs_perag_get(args.mp, + XFS_FSB_TO_AGNO(args.mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); } - - args.minlen = args.maxlen = args.prod = 1; - args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; - if (!args.wasdel && args.tp->t_blk_res == 0) { - error = -ENOSPC; - goto error0; - } - error = xfs_alloc_vextent(&args); if (error) goto error0; - if (args.fsbno == NULLFSBLOCK && args.minleft) { - /* - * Could not find an AG with enough free space to satisfy - * a full btree split. Try again and if - * successful activate the lowspace algorithm. - */ - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - error = xfs_alloc_vextent(&args); - if (error) - goto error0; - cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; - } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { *stat = 0; return 0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index a155b3cc1e14..27f5951ae087 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -630,6 +630,7 @@ xfs_ialloc_ag_alloc( args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; args.oinfo = XFS_RMAP_OINFO_INODES; + args.pag = pag; #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -683,7 +684,8 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; /* @@ -731,7 +733,8 @@ xfs_ialloc_ag_alloc( * Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; } @@ -780,7 +783,7 @@ xfs_ialloc_ag_alloc( args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 3675a0d29310..fa6cd2502970 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -103,6 +103,7 @@ __xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.oinfo = XFS_RMAP_OINFO_INOBT; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno); args.minlen = 1; @@ -111,7 +112,7 @@ __xfs_inobt_alloc_block( args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 938e804d420f..bf4049b42f7d 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -66,6 +66,7 @@ xfs_refcountbt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, xfs_refc_block(args.mp)); @@ -73,7 +74,7 @@ xfs_refcountbt_alloc_block( args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) goto out_error; trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno, diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index d2331d515758..0fd7ec7461a5 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -313,6 +313,7 @@ xrep_alloc_ag_block( args.tp = sc->tp; args.mp = sc->mp; + args.pag = sc->sa.pag; args.oinfo = *oinfo; args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; @@ -321,7 +322,7 @@ xrep_alloc_ag_block( args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; if (args.fsbno == NULLFSBLOCK) From patchwork Fri Dec 3 00:01:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653897 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 E1617C433EF for ; Fri, 3 Dec 2021 00:01:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377748AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37483 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377739AbhLCAEt (ORCPT ); Thu, 2 Dec 2021 19:04:49 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 2F078869E53 for ; Fri, 3 Dec 2021 11:01:24 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LC-7i for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00BkiN-6N for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 27/36] xfs: factor xfs_bmap_btalloc() Date: Fri, 3 Dec 2021 11:01:02 +1100 Message-Id: <20211203000111.2800982-28-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=_SQKL7Lu6c1vmibDrAoA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There are several different contexts xfs_bmap_btalloc() handles, and large chunks of the code execute individual contexts. For example, "nullfb" and "low mode" are mutually exclusive, but the code that handles them is deeply intertwined. Try to untangle this mess a bit. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 474 +++++++++++++++++++++++---------------- 1 file changed, 276 insertions(+), 198 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 304a0e8cedc8..5bf3f0856d2a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3241,41 +3241,6 @@ xfs_bmap_select_minlen( } } -STATIC int -xfs_bmap_btalloc_nullfb( - struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t *blen) -{ - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_perag *pag; - xfs_agnumber_t agno, startag; - int notinit = 0; - int error = 0; - - args->type = XFS_ALLOCTYPE_START_BNO; - args->total = ap->total; - - startag = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (startag == NULLAGNUMBER) - startag = 0; - - *blen = 0; - for_each_perag_wrap(mp, startag, agno, pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen, - ¬init); - if (error) - break; - if (*blen >= args->maxlen) - break; - } - if (pag) - xfs_perag_rele(pag); - - xfs_bmap_select_minlen(ap, args, blen, notinit); - return 0; -} - STATIC int xfs_bmap_btalloc_filestreams( struct xfs_bmalloca *ap, @@ -3546,202 +3511,315 @@ xfs_bmap_exact_minlen_extent_alloc( #define xfs_bmap_exact_minlen_extent_alloc(bma) (-EFSCORRUPTED) #endif - -STATIC int -xfs_bmap_btalloc( - struct xfs_bmalloca *ap) +/* + * If we are not low on available data blocks and we are allocating at + * EOF, optimise allocation for contiguous file extension and/or stripe + * alignment of the new extent. + * + * NOTE: ap->aeof is only set if the allocation length is >= the + * stripe unit and the allocation offset is at the end of file. + */ +static int +xfs_btalloc_at_eof( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t blen, + int stripe_align) { - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_alloc_arg args = { .tp = ap->tp, .mp = mp }; - xfs_alloctype_t atype = 0; - xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ - xfs_agnumber_t ag; - xfs_fileoff_t orig_offset; - xfs_extlen_t orig_length; - xfs_extlen_t blen; - xfs_extlen_t nextminlen = 0; - int nullfb; /* true if ap->firstblock isn't set */ - int isaligned; + struct xfs_mount *mp = args->mp; + xfs_alloctype_t atype; int error; - int stripe_align; - - ASSERT(ap->length); - orig_offset = ap->offset; - orig_length = ap->length; - - stripe_align = xfs_bmap_compute_alignments(ap, &args); - - nullfb = ap->tp->t_firstblock == NULLFSBLOCK; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, - ap->tp->t_firstblock); - if (nullfb) { - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) { - ag = xfs_filestream_lookup_ag(ap->ip); - ag = (ag != NULLAGNUMBER) ? ag : 0; - ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); - } else { - ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); - } - } else - ap->blkno = ap->tp->t_firstblock; - - xfs_bmap_adjacent(ap); /* - * If allowed, use ap->blkno; otherwise must use firstblock since - * it's in the right allocation group. + * If there are already extents in the file, try an exact EOF block + * allocation to extend the file as a contiguous extent. If that fails, + * or it's the first allocation in a file, just try for a stripe aligned + * allocation. */ - if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno) - ; - else - ap->blkno = ap->tp->t_firstblock; - /* - * Normal allocation, done through xfs_alloc_vextent. - */ - isaligned = 0; - args.fsbno = ap->blkno; - args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; + if (ap->offset) { + xfs_extlen_t nextminlen = 0; + + atype = args->type; + args->type = XFS_ALLOCTYPE_THIS_BNO; + args->alignment = 1; - /* Trim the allocation back to the maximum an AG can fit. */ - args.maxlen = min(ap->length, mp->m_ag_max_usable); - blen = 0; - if (nullfb) { /* - * Search for an allocation group with a single extent large - * enough for the request. If one isn't found, then adjust - * the minimum allocation size to the largest space found. + * Compute the minlen+alignment for the next case. Set slop so + * that the value of minlen+alignment+slop doesn't go up between + * the calls. */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) - error = xfs_bmap_btalloc_filestreams(ap, &args, &blen); + if (blen > stripe_align && blen <= args->maxlen) + nextminlen = blen - stripe_align; else - error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); + nextminlen = args->minlen; + if (nextminlen + stripe_align > args->minlen + 1) + args->minalignslop = nextminlen + stripe_align - + args->minlen - 1; + else + args->minalignslop = 0; + + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); + error = xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); if (error) return error; - } else if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { - if (xfs_inode_is_filestream(ap->ip)) - args.type = XFS_ALLOCTYPE_FIRST_AG; - else - args.type = XFS_ALLOCTYPE_START_BNO; - args.total = args.minlen = ap->minlen; + + if (args->fsbno != NULLFSBLOCK) + return 0; + /* + * Exact allocation failed. Reset to try an aligned allocation + * according to the original allocation specification. + */ + args->pag = NULL; + args->type = atype; + args->fsbno = ap->blkno; + args->alignment = stripe_align; + args->minlen = nextminlen; + args->minalignslop = 0; } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.total = ap->total; - args.minlen = ap->minlen; + args->alignment = stripe_align; + atype = args->type; + /* + * Adjust minlen to try and preserve alignment if we + * can't guarantee an aligned maxlen extent. + */ + if (blen > args->alignment && + blen <= args->maxlen + args->alignment) + args->minlen = blen - args->alignment; + args->minalignslop = 0; } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.resv = XFS_AG_RESV_NONE; - args.datatype = ap->datatype; + + error = xfs_alloc_vextent(args); + if (error) + return error; + + if (args->fsbno != NULLFSBLOCK) + return 0; /* - * If we are not low on available data blocks, and the underlying - * logical volume manager is a stripe, and the file offset is zero then - * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof - * is only set if the allocation length is >= the stripe unit and the - * allocation offset is at the end of file. + * Allocation failed, so turn return the allocation args to their + * original non-aligned state so the caller can proceed on allocation + * failure as if this function was never called. */ - if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) { - if (!ap->offset) { - args.alignment = stripe_align; - atype = args.type; - isaligned = 1; - /* - * Adjust minlen to try and preserve alignment if we - * can't guarantee an aligned maxlen extent. - */ - if (blen > args.alignment && - blen <= args.maxlen + args.alignment) - args.minlen = blen - args.alignment; - args.minalignslop = 0; - } else { - /* - * First try an exact bno allocation. - * If it fails then do a near or start bno - * allocation with alignment turned on. - */ - atype = args.type; - args.type = XFS_ALLOCTYPE_THIS_BNO; - args.alignment = 1; + args->type = atype; + args->fsbno = ap->blkno; + args->alignment = 1; + return 0; +} - /* - * Compute the minlen+alignment for the - * next case. Set slop so that the value - * of minlen+alignment+slop doesn't go up - * between the calls. - */ - if (blen > stripe_align && blen <= args.maxlen) - nextminlen = blen - stripe_align; - else - nextminlen = args.minlen; - if (nextminlen + stripe_align > args.minlen + 1) - args.minalignslop = - nextminlen + stripe_align - - args.minlen - 1; - else - args.minalignslop = 0; +static int +xfs_btalloc_nullfb_bestlen( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t *blen) +{ + struct xfs_mount *mp = args->mp; + struct xfs_perag *pag; + xfs_agnumber_t agno, startag; + int notinit = 0; + int error = 0; - args.pag = xfs_perag_get(mp, - XFS_FSB_TO_AGNO(mp, args.fsbno)); - error = xfs_alloc_vextent_this_ag(&args); - xfs_perag_put(args.pag); - if (error) - return error; + args->type = XFS_ALLOCTYPE_START_BNO; + args->total = ap->total; - if (args.fsbno != NULLFSBLOCK) - goto out_success; - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.pag = NULL; - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = stripe_align; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - } + startag = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (startag == NULLAGNUMBER) + startag = 0; + + *blen = 0; + for_each_perag_wrap(mp, startag, agno, pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen, + ¬init); + if (error) + break; + if (*blen >= args->maxlen) + break; + } + if (pag) + xfs_perag_rele(pag); + + xfs_bmap_select_minlen(ap, args, blen, notinit); + return 0; +} + +static int +xfs_btalloc_nullfb( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + int stripe_align) +{ + struct xfs_mount *mp = args->mp; + xfs_extlen_t blen = 0; + int error; + + /* + * Determine the initial block number we will target for allocation. + */ + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) { + xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); + if (agno == NULLAGNUMBER) + agno = 0; + ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); } else { - args.alignment = 1; - args.minalignslop = 0; + ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } + xfs_bmap_adjacent(ap); + args->fsbno = ap->blkno; - error = xfs_alloc_vextent(&args); + /* + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then adjust the minimum allocation + * size to the largest space found. + */ + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) + error = xfs_bmap_btalloc_filestreams(ap, args, &blen); + else + error = xfs_btalloc_nullfb_bestlen(ap, args, &blen); if (error) return error; - if (isaligned && args.fsbno == NULLFSBLOCK) { - /* - * allocation failed, so turn off alignment and - * try again. - */ - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = 0; - if ((error = xfs_alloc_vextent(&args))) + if (ap->aeof) { + error = xfs_btalloc_at_eof(ap, args, blen, stripe_align); + if (error) return error; + if (args->fsbno != NULLFSBLOCK) + return 0; } - if (args.fsbno == NULLFSBLOCK && nullfb && - args.minlen > ap->minlen) { - args.minlen = ap->minlen; - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = ap->blkno; - if ((error = xfs_alloc_vextent(&args))) + + error = xfs_alloc_vextent(args); + if (error) + return error; + if (args->fsbno != NULLFSBLOCK) + return 0; + + /* + * Try a locality first full filesystem minimum length allocation whilst + * still maintaining necessary total block reservation requirements. + */ + if (args->minlen > ap->minlen) { + args->minlen = ap->minlen; + args->type = XFS_ALLOCTYPE_START_BNO; + args->fsbno = ap->blkno; + error = xfs_alloc_vextent(args); + if (error) return error; } - if (args.fsbno == NULLFSBLOCK && nullfb) { - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - args.total = ap->minlen; - if ((error = xfs_alloc_vextent(&args))) + if (args->fsbno != NULLFSBLOCK) + return 0; + + /* + * We are now critically low on space, so this is a last resort + * allocation attempt: no reserve, no locality, blocking, minimum + * length, full filesystem free space scan. We also indicate to future + * allocations in this transaction that we are critically low on space + * so they don't waste time on allocation modes that are unlikely to + * succeed. + */ + args->fsbno = 0; + args->type = XFS_ALLOCTYPE_FIRST_AG; + args->total = ap->minlen; + error = xfs_alloc_vextent(args); + if (error) + return error; + ap->tp->t_flags |= XFS_TRANS_LOWMODE; + return 0; +} + +/* + * We are near ENOSPC, so try an exhaustive minimum length allocation. If this + * fails, we really are at ENOSPC. + */ +static int +xfs_btalloc_low_mode( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args) +{ + ap->blkno = ap->tp->t_firstblock; + xfs_bmap_adjacent(ap); + args->fsbno = ap->blkno; + args->total = args->minlen = ap->minlen; + if (xfs_inode_is_filestream(ap->ip)) + args->type = XFS_ALLOCTYPE_FIRST_AG; + else + args->type = XFS_ALLOCTYPE_START_BNO; + + return xfs_alloc_vextent(args); +} + +/* + * Attempt to allocate near the current target. We attempt optimal EOF + * allocation, but then if that fails we simply try somewhere near in the same + * AG. If we can't get a block in the same AG, then we fail the allocation. + */ +static int +xfs_btalloc_near( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + int stripe_align) +{ + xfs_extlen_t blen = 0; + int error; + + ap->blkno = ap->tp->t_firstblock; + xfs_bmap_adjacent(ap); + args->fsbno = ap->blkno; + args->type = XFS_ALLOCTYPE_NEAR_BNO; + args->total = ap->total; + args->minlen = ap->minlen; + + if (ap->aeof) { + error = xfs_btalloc_at_eof(ap, args, blen, stripe_align); + if (error) return error; - ap->tp->t_flags |= XFS_TRANS_LOWMODE; + if (args->fsbno != NULLFSBLOCK) + return 0; } + return xfs_alloc_vextent(args); +} + +STATIC int +xfs_bmap_btalloc( + struct xfs_bmalloca *ap) +{ + struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_alloc_arg args = { + .tp = ap->tp, + .mp = mp, + .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, + .minleft = ap->minleft, + .wasdel = ap->wasdel, + .resv = XFS_AG_RESV_NONE, + .datatype = ap->datatype, + .alignment = 1, + .minalignslop = 0, + }; + xfs_fileoff_t orig_offset; + xfs_extlen_t orig_length; + int error; + int stripe_align; + + ASSERT(ap->length); + orig_offset = ap->offset; + orig_length = ap->length; + + stripe_align = xfs_bmap_compute_alignments(ap, &args); + + /* Trim the allocation back to the maximum an AG can fit. */ + args.maxlen = min(ap->length, mp->m_ag_max_usable); + + if (ap->tp->t_firstblock == NULLFSBLOCK) { + error = xfs_btalloc_nullfb(ap, &args, stripe_align); + } else if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + error = xfs_btalloc_low_mode(ap, &args); + } else { + error = xfs_btalloc_near(ap, &args, stripe_align); + } + if (error) + return error; if (args.fsbno != NULLFSBLOCK) { -out_success: xfs_bmap_process_allocated_extent(ap, &args, orig_offset, orig_length); } else { From patchwork Fri Dec 3 00:01:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653927 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 53F38C4167D for ; Fri, 3 Dec 2021 00:01:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377751AbhLCAFD (ORCPT ); Thu, 2 Dec 2021 19:05:03 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:60014 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377754AbhLCAFC (ORCPT ); Thu, 2 Dec 2021 19:05:02 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 408DA606877 for ; Fri, 3 Dec 2021 11:01:25 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LF-8j for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00BkiS-7f for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 28/36] xfs: use xfs_alloc_vextent_first_ag() where appropriate Date: Fri, 3 Dec 2021 11:01:03 +1100 Message-Id: <20211203000111.2800982-29-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e55 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=ZYJNKcoVrom5moMyh1QA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_first_ag(). This gets rid of XFS_ALLOCTYPE_FIRST_AG as the type used within xfs_alloc_vextent_first_ag() during iteration is _THIS_AG. Hence we can remove the setting of args->type from all the callers of _first_ag() and remove the alloctype. While doing this, pass the allocation target fsb as a parameter rather than encoding it in args->fsbno. This starts the process of making args->fsbno an output only variable rather than input/output. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 26 ++++++++++++++------------ fs/xfs/libxfs/xfs_alloc.h | 10 ++++++++-- fs/xfs/libxfs/xfs_bmap.c | 15 +++++---------- fs/xfs/libxfs/xfs_bmap_btree.c | 4 +--- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 78a9cd543a2d..946899a5e3cb 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3168,7 +3168,8 @@ xfs_alloc_read_agf( */ static int xfs_alloc_vextent_check_args( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; xfs_agblock_t agsize; @@ -3186,13 +3187,13 @@ xfs_alloc_vextent_check_args( args->maxlen = agsize; if (args->alignment == 0) args->alignment = 1; - ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize); + ASSERT(XFS_FSB_TO_AGNO(mp, target) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, target) < agsize); ASSERT(args->minlen <= args->maxlen); ASSERT(args->minlen <= agsize); ASSERT(args->mod < args->prod); - if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount || - XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize || + if (XFS_FSB_TO_AGNO(mp, target) >= mp->m_sb.sb_agcount || + XFS_FSB_TO_AGBNO(mp, target) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; @@ -3201,6 +3202,7 @@ xfs_alloc_vextent_check_args( } return 0; } + /* * Post-process allocation results to set the allocated block number correctly * for the caller. @@ -3239,7 +3241,7 @@ xfs_alloc_vextent_this_ag( struct xfs_mount *mp = args->mp; int error; - error = xfs_alloc_vextent_check_args(args); + error = xfs_alloc_vextent_check_args(args, args->fsbno); if (error) { if (error == -ENOSPC) return 0; @@ -3353,7 +3355,7 @@ xfs_alloc_vextent_start_ag( bool bump_rotor = false; int error; - error = xfs_alloc_vextent_check_args(args); + error = xfs_alloc_vextent_check_args(args, args->fsbno); if (error) { if (error == -ENOSPC) return 0; @@ -3394,14 +3396,15 @@ xfs_alloc_vextent_start_ag( * filesystem attempting blocking allocation. This does not wrap or try a second * pass, so will not recurse into AGs lower than indicated by fsbno. */ -static int +int xfs_alloc_vextent_first_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; int error; - error = xfs_alloc_vextent_check_args(args); + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; @@ -3409,6 +3412,7 @@ xfs_alloc_vextent_first_ag( } args->type = XFS_ALLOCTYPE_THIS_AG; + args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, XFS_FSB_TO_AGNO(mp, args->fsbno), 0); if (error) @@ -3437,8 +3441,6 @@ xfs_alloc_vextent( return error; case XFS_ALLOCTYPE_START_BNO: return xfs_alloc_vextent_start_ag(args); - case XFS_ALLOCTYPE_FIRST_AG: - return xfs_alloc_vextent_first_ag(args); default: ASSERT(0); /* NOTREACHED */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 7baf65a23e6e..1b47c48c6060 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -19,7 +19,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); /* * Freespace allocation types. Argument to xfs_alloc_[v]extent. */ -#define XFS_ALLOCTYPE_FIRST_AG 0x02 /* ... start at ag 0 */ #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ #define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ @@ -29,7 +28,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_TYPES \ - { XFS_ALLOCTYPE_FIRST_AG, "FIRST_AG" }, \ { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ @@ -131,6 +129,14 @@ xfs_alloc_vextent( */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Iterate from the AG indicated from args->fsbno through to the end of the + * filesystem attempting blocking allocation. This is for use in last + * resort allocation attempts when everything else has failed. + */ +int xfs_alloc_vextent_first_ag(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Free an extent. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 5bf3f0856d2a..52e00ce478e1 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3478,9 +3478,7 @@ xfs_bmap_exact_minlen_extent_alloc( ap->blkno = ap->tp->t_firstblock; } - args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; - args.type = XFS_ALLOCTYPE_FIRST_AG; args.minlen = args.maxlen = ap->minlen; args.total = ap->total; @@ -3492,7 +3490,7 @@ xfs_bmap_exact_minlen_extent_alloc( args.resv = XFS_AG_RESV_NONE; args.datatype = ap->datatype; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_first_ag(&args, ap->blkno); if (error) return error; @@ -3717,10 +3715,8 @@ xfs_btalloc_nullfb( * so they don't waste time on allocation modes that are unlikely to * succeed. */ - args->fsbno = 0; - args->type = XFS_ALLOCTYPE_FIRST_AG; args->total = ap->minlen; - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_first_ag(args, 0); if (error) return error; ap->tp->t_flags |= XFS_TRANS_LOWMODE; @@ -3738,13 +3734,12 @@ xfs_btalloc_low_mode( { ap->blkno = ap->tp->t_firstblock; xfs_bmap_adjacent(ap); - args->fsbno = ap->blkno; args->total = args->minlen = ap->minlen; if (xfs_inode_is_filestream(ap->ip)) - args->type = XFS_ALLOCTYPE_FIRST_AG; - else - args->type = XFS_ALLOCTYPE_START_BNO; + return xfs_alloc_vextent_first_ag(args, ap->blkno); + args->fsbno = ap->blkno; + args->type = XFS_ALLOCTYPE_START_BNO; return xfs_alloc_vextent(args); } diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index d7b1016355de..16899345a535 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -240,9 +240,7 @@ xfs_bmbt_alloc_block( * satisfy a full btree split. Try again and if * successful activate the lowspace algorithm. */ - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_first_ag(&args, 0); if (error) goto error0; cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; From patchwork Fri Dec 3 00:01:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653883 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 BA7DDC43217 for ; Fri, 3 Dec 2021 00:01:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349796AbhLCAEp (ORCPT ); Thu, 2 Dec 2021 19:04:45 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:36135 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377728AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 36E50869CC2 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LI-9p for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00BkiX-8h for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 29/36] xfs: use xfs_alloc_vextent_start_bno() where appropriate Date: Fri, 3 Dec 2021 11:01:04 +1100 Message-Id: <20211203000111.2800982-30-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=2bNGl3VnspcAYmXYyhAA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_start_bno(). Callers no long need to specify XFS_ALLOCTYPE_START_BNO, and so the type can be driven inward and removed. While doing this, also pass the allocation target fsb as a parameter rather than encoding it in args->fsbno. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 34 ++++++++++----------- fs/xfs/libxfs/xfs_alloc.h | 13 ++++++-- fs/xfs/libxfs/xfs_bmap.c | 54 ++++++++++++++++++---------------- fs/xfs/libxfs/xfs_bmap_btree.c | 8 ++--- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 946899a5e3cb..9c22d101d3ca 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3174,7 +3174,6 @@ xfs_alloc_vextent_check_args( struct xfs_mount *mp = args->mp; xfs_agblock_t agsize; - args->otype = args->type; args->agbno = NULLAGBLOCK; /* @@ -3260,12 +3259,11 @@ xfs_alloc_vextent_this_ag( /* * Iterate all AGs trying to allocate an extent starting from @start_ag. * - * If the - * incoming allocation type is XFS_ALLOCTYPE_NEAR_BNO, it means the allocation - * attempts in @start_agno have locality information. If we fail to allocate in - * that AG, then we revert to anywhere-in-AG for all the other AGs we attempt to - * allocation in as there is no locality optimisation possible for those - * allocations. + * If the incoming allocation type is XFS_ALLOCTYPE_NEAR_BNO, it means the + * allocation attempts in @start_agno have locality information. If we fail to + * allocate in that AG, then we revert to anywhere-in-AG for all the other AGs + * we attempt to allocation in as there is no locality optimisation possible for + * those allocations. * * When we wrap the AG iteration at the end of the filesystem, we have to be * careful not to wrap into AGs below ones we already have locked in the @@ -3299,7 +3297,7 @@ xfs_alloc_vextent_iterate_ags( trace_xfs_alloc_vextent_loopfailed(args); if (args->agno == start_agno && - args->otype == XFS_ALLOCTYPE_START_BNO) + args->otype == XFS_ALLOCTYPE_NEAR_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; /* * For the first allocation, we can try any AG to get @@ -3326,7 +3324,7 @@ xfs_alloc_vextent_iterate_ags( } flags = 0; - if (args->otype == XFS_ALLOCTYPE_START_BNO) { + if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) { args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_NEAR_BNO; } @@ -3345,9 +3343,10 @@ xfs_alloc_vextent_iterate_ags( * otherwise will wrap back to the start AG and run a second blocking pass to * the end of the filesystem. */ -static int +int xfs_alloc_vextent_start_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; xfs_agnumber_t start_agno; @@ -3355,7 +3354,7 @@ xfs_alloc_vextent_start_ag( bool bump_rotor = false; int error; - error = xfs_alloc_vextent_check_args(args, args->fsbno); + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; @@ -3364,14 +3363,17 @@ xfs_alloc_vextent_start_ag( if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && xfs_is_inode32(mp)) { - args->fsbno = XFS_AGB_TO_FSB(mp, + target = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount), 0); bump_rotor = 1; } - start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + + start_agno = XFS_FSB_TO_AGNO(mp, target); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->otype = XFS_ALLOCTYPE_NEAR_BNO; args->type = XFS_ALLOCTYPE_NEAR_BNO; + args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, start_agno, XFS_ALLOC_FLAG_TRYLOCK); @@ -3439,8 +3441,6 @@ xfs_alloc_vextent( error = xfs_alloc_vextent_this_ag(args); xfs_perag_put(args->pag); return error; - case XFS_ALLOCTYPE_START_BNO: - return xfs_alloc_vextent_start_ag(args); default: ASSERT(0); /* NOTREACHED */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 1b47c48c6060..a02ea72aa0c4 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -20,7 +20,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); * Freespace allocation types. Argument to xfs_alloc_[v]extent. */ #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ -#define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ #define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ @@ -29,7 +28,6 @@ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_TYPES \ { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ - { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } @@ -129,6 +127,17 @@ xfs_alloc_vextent( */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Best effort full filesystem allocation scan. + * + * Locality aware allocation will be attempted in the initial AG, but on failure + * non-localised attempts will be made. The AGs are constrained by previous + * allocations in the current transaction. Two passes will be made - the first + * non-blocking, the second blocking. + */ +int xfs_alloc_vextent_start_ag(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Iterate from the AG indicated from args->fsbno through to the end of the * filesystem attempting blocking allocation. This is for use in last diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 52e00ce478e1..23a29b33e77c 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -651,13 +651,10 @@ xfs_bmap_extents_to_btree( *logflagsp = 0; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); if (tp->t_firstblock == NULLFSBLOCK) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, + XFS_INO_TO_FSB(mp, ip->i_ino)); } else if (tp->t_flags & XFS_TRANS_LOWMODE) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = tp->t_firstblock; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, tp->t_firstblock); } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = tp->t_firstblock; @@ -813,9 +810,8 @@ xfs_bmap_local_to_extents( * file currently fits in an inode. */ if (tp->t_firstblock == NULLFSBLOCK) { - args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); - args.type = XFS_ALLOCTYPE_START_BNO; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, + XFS_INO_TO_FSB(args.mp, ip->i_ino)); } else { args.fsbno = tp->t_firstblock; args.type = XFS_ALLOCTYPE_NEAR_BNO; @@ -3522,7 +3518,8 @@ xfs_btalloc_at_eof( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t blen, - int stripe_align) + int stripe_align, + bool ag_only) { struct xfs_mount *mp = args->mp; xfs_alloctype_t atype; @@ -3587,7 +3584,10 @@ xfs_btalloc_at_eof( args->minalignslop = 0; } - error = xfs_alloc_vextent(args); + if (ag_only) + error = xfs_alloc_vextent(args); + else + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; @@ -3617,7 +3617,6 @@ xfs_btalloc_nullfb_bestlen( int notinit = 0; int error = 0; - args->type = XFS_ALLOCTYPE_START_BNO; args->total = ap->total; startag = XFS_FSB_TO_AGNO(mp, args->fsbno); @@ -3648,13 +3647,17 @@ xfs_btalloc_nullfb( { struct xfs_mount *mp = args->mp; xfs_extlen_t blen = 0; + bool is_filestream = false; int error; + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) + is_filestream = true; + /* * Determine the initial block number we will target for allocation. */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) { + if (is_filestream) { xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); if (agno == NULLAGNUMBER) agno = 0; @@ -3670,8 +3673,7 @@ xfs_btalloc_nullfb( * the request. If one isn't found, then adjust the minimum allocation * size to the largest space found. */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) + if (is_filestream) error = xfs_bmap_btalloc_filestreams(ap, args, &blen); else error = xfs_btalloc_nullfb_bestlen(ap, args, &blen); @@ -3679,14 +3681,18 @@ xfs_btalloc_nullfb( return error; if (ap->aeof) { - error = xfs_btalloc_at_eof(ap, args, blen, stripe_align); + error = xfs_btalloc_at_eof(ap, args, blen, stripe_align, + is_filestream); if (error) return error; if (args->fsbno != NULLFSBLOCK) return 0; } - error = xfs_alloc_vextent(args); + if (is_filestream) + error = xfs_alloc_vextent(args); + else + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; if (args->fsbno != NULLFSBLOCK) @@ -3698,9 +3704,7 @@ xfs_btalloc_nullfb( */ if (args->minlen > ap->minlen) { args->minlen = ap->minlen; - args->type = XFS_ALLOCTYPE_START_BNO; - args->fsbno = ap->blkno; - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; } @@ -3737,10 +3741,7 @@ xfs_btalloc_low_mode( args->total = args->minlen = ap->minlen; if (xfs_inode_is_filestream(ap->ip)) return xfs_alloc_vextent_first_ag(args, ap->blkno); - - args->fsbno = ap->blkno; - args->type = XFS_ALLOCTYPE_START_BNO; - return xfs_alloc_vextent(args); + return xfs_alloc_vextent_start_ag(args, ap->blkno); } /* @@ -3765,7 +3766,8 @@ xfs_btalloc_near( args->minlen = ap->minlen; if (ap->aeof) { - error = xfs_btalloc_at_eof(ap, args, blen, stripe_align); + error = xfs_btalloc_at_eof(ap, args, blen, stripe_align, + true); if (error) return error; if (args->fsbno != NULLFSBLOCK) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 16899345a535..b2166dc16459 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -216,8 +216,6 @@ xfs_bmbt_alloc_block( return -ENOSPC; if (args.fsbno == NULLFSBLOCK) { - args.fsbno = be64_to_cpu(start->l); - args.type = XFS_ALLOCTYPE_START_BNO; /* * Make sure there is sufficient room left in the AG to * complete a full tree split for an extent insert. If @@ -230,7 +228,7 @@ xfs_bmbt_alloc_block( * block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, be64_to_cpu(start->l)); if (error) goto error0; @@ -246,8 +244,8 @@ xfs_bmbt_alloc_block( cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; } } else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) { - args.type = XFS_ALLOCTYPE_START_BNO; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, + cur->bc_tp->t_firstblock); } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.pag = xfs_perag_get(args.mp, From patchwork Fri Dec 3 00:01:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653869 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 C17E5C433F5 for ; Fri, 3 Dec 2021 00:01:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377696AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35727 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349763AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 37BF4869CC3 for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LL-Av for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkic-9o for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 30/36] xfs: introduce xfs_alloc_vextent_near_bno() Date: Fri, 3 Dec 2021 11:01:05 +1100 Message-Id: <20211203000111.2800982-31-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=cxPQ6x55hLG55csZt-YA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The remaining callers of xfs_alloc_vextent() are all doing NEAR_BNO allocations. We can replace that function with a new xfs_alloc_vextent_near_bno() function that does this explicitly. We also multiplex NEAR_BNO allocations through xfs_alloc_vextent_this_ag via args->type. Replace all of these with direct calls to xfs_alloc_vextent_near_bno(), too. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 41 ++++++++++++++++++------------ fs/xfs/libxfs/xfs_alloc.h | 14 +++++----- fs/xfs/libxfs/xfs_bmap.c | 23 ++++------------- fs/xfs/libxfs/xfs_bmap_btree.c | 7 ++--- fs/xfs/libxfs/xfs_ialloc.c | 27 ++++++++------------ fs/xfs/libxfs/xfs_ialloc_btree.c | 5 ++-- fs/xfs/libxfs/xfs_refcount_btree.c | 7 +++-- 7 files changed, 54 insertions(+), 70 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 9c22d101d3ca..266753fe7893 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3424,29 +3424,38 @@ xfs_alloc_vextent_first_ag( } /* - * Allocate an extent (variable-size). - * Depending on the allocation type, we either look in a single allocation - * group or loop over the allocation groups to find the result. + * Allocate an extent as close to the target as possible. If there are not + * viable candidates in the AG, then fail the allocation. */ int -xfs_alloc_vextent( - struct xfs_alloc_arg *args) +xfs_alloc_vextent_near_bno( + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { + struct xfs_mount *mp = args->mp; + bool need_pag = !args->pag; int error; - switch (args->type) { - case XFS_ALLOCTYPE_NEAR_BNO: - args->pag = xfs_perag_get(args->mp, - XFS_FSB_TO_AGNO(args->mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); - xfs_perag_put(args->pag); + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; return error; - default: - ASSERT(0); - /* NOTREACHED */ } - /* Should never get here */ - return -EFSCORRUPTED; + + args->agno = XFS_FSB_TO_AGNO(mp, target); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->type = XFS_ALLOCTYPE_NEAR_BNO; + if (need_pag) + args->pag = xfs_perag_get(args->mp, args->agno); + error = xfs_alloc_ag_vextent(args); + if (need_pag) + xfs_perag_put(args->pag); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args); + return 0; } /* Ensure that the freelist is at full capacity. */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index a02ea72aa0c4..4cd0e9abdc1c 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -114,19 +114,19 @@ xfs_alloc_log_agf( struct xfs_buf *bp, /* buffer for a.g. freelist header */ int fields);/* mask of fields to be logged (XFS_AGF_...) */ -/* - * Allocate an extent (variable-size). - */ -int /* error */ -xfs_alloc_vextent( - xfs_alloc_arg_t *args); /* allocation argument structure */ - /* * Allocate an extent in the specific AG defined by args->fsbno. If there is no * space in that AG, then the allocation will fail. */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Allocate an extent as close to the target as possible. If there are not + * viable candidates in the AG, then fail the allocation. + */ +int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 23a29b33e77c..47414bd9be80 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -656,11 +656,7 @@ xfs_bmap_extents_to_btree( } else if (tp->t_flags & XFS_TRANS_LOWMODE) { error = xfs_alloc_vextent_start_ag(&args, tp->t_firstblock); } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = tp->t_firstblock; - args.pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args.fsbno)); - error = xfs_alloc_vextent_this_ag(&args); - xfs_perag_put(args.pag); + error = xfs_alloc_vextent_near_bno(&args, tp->t_firstblock); } if (error) goto out_root_realloc; @@ -813,12 +809,7 @@ xfs_bmap_local_to_extents( error = xfs_alloc_vextent_start_ag(&args, XFS_INO_TO_FSB(args.mp, ip->i_ino)); } else { - args.fsbno = tp->t_firstblock; - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.pag = xfs_perag_get(args.mp, - XFS_FSB_TO_AGNO(args.mp, args.fsbno)); - error = xfs_alloc_vextent_this_ag(&args); - xfs_perag_put(args.pag); + error = xfs_alloc_vextent_near_bno(&args, tp->t_firstblock); } if (error) goto done; @@ -3249,7 +3240,6 @@ xfs_bmap_btalloc_filestreams( int notinit = 0; int error; - args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); @@ -3585,7 +3575,7 @@ xfs_btalloc_at_eof( } if (ag_only) - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_near_bno(args, ap->blkno); else error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) @@ -3666,7 +3656,6 @@ xfs_btalloc_nullfb( ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } xfs_bmap_adjacent(ap); - args->fsbno = ap->blkno; /* * Search for an allocation group with a single extent large enough for @@ -3690,7 +3679,7 @@ xfs_btalloc_nullfb( } if (is_filestream) - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_near_bno(args, ap->blkno); else error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) @@ -3760,8 +3749,6 @@ xfs_btalloc_near( ap->blkno = ap->tp->t_firstblock; xfs_bmap_adjacent(ap); - args->fsbno = ap->blkno; - args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; args->minlen = ap->minlen; @@ -3773,7 +3760,7 @@ xfs_btalloc_near( if (args->fsbno != NULLFSBLOCK) return 0; } - return xfs_alloc_vextent(args); + return xfs_alloc_vextent_near_bno(args, ap->blkno); } STATIC int diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index b2166dc16459..ea548cca085f 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -247,11 +247,8 @@ xfs_bmbt_alloc_block( error = xfs_alloc_vextent_start_ag(&args, cur->bc_tp->t_firstblock); } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.pag = xfs_perag_get(args.mp, - XFS_FSB_TO_AGNO(args.mp, args.fsbno)); - error = xfs_alloc_vextent_this_ag(&args); - xfs_perag_put(args.pag); + error = xfs_alloc_vextent_near_bno(&args, + cur->bc_tp->t_firstblock); } if (error) goto error0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 27f5951ae087..64577be85c8b 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -717,23 +717,17 @@ xfs_ialloc_ag_alloc( isaligned = 1; } else args.alignment = igeo->cluster_align; - /* - * Need to figure out where to allocate the inode blocks. - * Ideally they should be spaced out through the a.g. - * For now, just allocate blocks up front. - */ - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); /* * Allocate a fixed-size extent of inodes. */ - args.type = XFS_ALLOCTYPE_NEAR_BNO; args.prod = 1; /* * Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); if (error) return error; } @@ -743,11 +737,11 @@ xfs_ialloc_ag_alloc( * alignment. */ if (isaligned && args.fsbno == NULLFSBLOCK) { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); args.alignment = igeo->cluster_align; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); + if (error) return error; } @@ -759,9 +753,6 @@ xfs_ialloc_ag_alloc( igeo->ialloc_min_blks < igeo->ialloc_blks && args.fsbno == NULLFSBLOCK) { sparse_alloc: - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); args.alignment = args.mp->m_sb.sb_spino_align; args.prod = 1; @@ -783,7 +774,9 @@ xfs_ialloc_ag_alloc( args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index fa6cd2502970..9b28211d5a4c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -105,14 +105,13 @@ __xfs_inobt_alloc_block( args.mp = cur->bc_mp; args.pag = cur->bc_ag.pag; args.oinfo = XFS_RMAP_OINFO_INOBT; - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, sbno)); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index bf4049b42f7d..7da175ac5cf6 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -67,14 +67,13 @@ xfs_refcountbt_alloc_block( args.tp = cur->bc_tp; args.mp = cur->bc_mp; args.pag = cur->bc_ag.pag; - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, - xfs_refc_block(args.mp)); args.oinfo = XFS_RMAP_OINFO_REFC; args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, + xfs_refc_block(args.mp))); if (error) goto out_error; trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno, From patchwork Fri Dec 3 00:01:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653885 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 3E553C4321E for ; Fri, 3 Dec 2021 00:01:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377726AbhLCAEr (ORCPT ); Thu, 2 Dec 2021 19:04:47 -0500 Received: from mail108.syd.optusnet.com.au ([211.29.132.59]:55994 "EHLO mail108.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377732AbhLCAEq (ORCPT ); Thu, 2 Dec 2021 19:04:46 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id 10681606B28 for ; Fri, 3 Dec 2021 11:01:18 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LO-Bv for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkih-As for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 31/36] xfs: introduce xfs_alloc_vextent_exact_bno() Date: Fri, 3 Dec 2021 11:01:06 +1100 Message-Id: <20211203000111.2800982-32-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4e a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=oGMmTz3EdBZv14weP10A:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Two of the callers to xfs_alloc_vextent_this_ag() actually want exact block number allocation, not anywhere-in-ag allocation. Split this out from _this_ag() as a first class citizen so no external extent allocation code needs to care about args->type anymore. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 6 ++---- fs/xfs/libxfs/xfs_alloc.c | 41 +++++++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_alloc.h | 13 +++++++++--- fs/xfs/libxfs/xfs_bmap.c | 6 ++---- fs/xfs/libxfs/xfs_ialloc.c | 6 +++--- fs/xfs/scrub/repair.c | 4 +--- 6 files changed, 56 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index f210f438db84..757cc72c8553 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -897,7 +897,6 @@ xfs_ag_shrink_space( .tp = *tpp, .mp = mp, .pag = pag, - .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, @@ -929,8 +928,6 @@ xfs_ag_shrink_space( if (delta >= aglen) return -EINVAL; - args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); - /* * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. @@ -948,7 +945,8 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta)); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 266753fe7893..1fb72fff5d26 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3235,19 +3235,24 @@ xfs_alloc_vextent_set_fsbno( */ int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_agnumber_t agno) { struct xfs_mount *mp = args->mp; int error; + xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); - error = xfs_alloc_vextent_check_args(args, args->fsbno); + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + args->agno = agno; + args->agbno = 0; + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_ag_vextent(args); if (error) return error; @@ -3423,6 +3428,36 @@ xfs_alloc_vextent_first_ag( return 0; } +/* + * Allocate within a single AG only. + */ +int +xfs_alloc_vextent_exact_bno( + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, target); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_BNO; + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args); + return 0; +} + /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 4cd0e9abdc1c..d61c3803c5dc 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -115,10 +115,10 @@ xfs_alloc_log_agf( int fields);/* mask of fields to be logged (XFS_AGF_...) */ /* - * Allocate an extent in the specific AG defined by args->fsbno. If there is no - * space in that AG, then the allocation will fail. + * Allocate an extent anywhere in the specific AG given. If there is no + * space matching the requirements in that AG, then the allocation will fail. */ -int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); /* * Allocate an extent as close to the target as possible. If there are not @@ -127,6 +127,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, xfs_rfsblock_t target); +/* + * Allocate an extent exactly at the target given. If this is not possible + * then the allocation fails. + */ +int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 47414bd9be80..4227007a4f9d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3525,7 +3525,6 @@ xfs_btalloc_at_eof( xfs_extlen_t nextminlen = 0; atype = args->type; - args->type = XFS_ALLOCTYPE_THIS_BNO; args->alignment = 1; /* @@ -3543,8 +3542,8 @@ xfs_btalloc_at_eof( else args->minalignslop = 0; - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); xfs_perag_put(args->pag); if (error) return error; @@ -3557,7 +3556,6 @@ xfs_btalloc_at_eof( */ args->pag = NULL; args->type = atype; - args->fsbno = ap->blkno; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 64577be85c8b..a519c2d3696e 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc( goto sparse_alloc; if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); - args.type = XFS_ALLOCTYPE_THIS_BNO; args.prod = 1; /* @@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + args.agbno)); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 0fd7ec7461a5..08d856bf75f8 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -315,14 +315,12 @@ xrep_alloc_ag_block( args.mp = sc->mp; args.pag = sc->sa.pag; args.oinfo = *oinfo; - args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_this_ag(&args, sc->sa.pag->pag_agno); if (error) return error; if (args.fsbno == NULLFSBLOCK) From patchwork Fri Dec 3 00:01:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653873 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 8AFAEC4167B for ; Fri, 3 Dec 2021 00:01:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349676AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35759 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243809AbhLCAEn (ORCPT ); Thu, 2 Dec 2021 19:04:43 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 5F0C1869C1B for ; Fri, 3 Dec 2021 11:01:17 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LR-D4 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkim-Bs for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 32/36] xfs: introduce xfs_alloc_vextent_prepare() Date: Fri, 3 Dec 2021 11:01:07 +1100 Message-Id: <20211203000111.2800982-33-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4d a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=wHXgHO0elxk0tAdDANkA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that we have wrapper functions for each type of allocation we can ask for, we can start unravelling xfs_alloc_ag_vextent(). That is essentially just a prepare stage, the allocation multiplexer and a post-allocation accounting step is the allocation proceeded. The current xfs_alloc_vextent*() wrappers all have a prepare stage, the allocation operation and a post-allocation accounting step. We can consolidate this by moving the AG alloc prep code into the wrapper functions, the accounting code in the wrapper accounting functions, and cut out the multiplexer layer entirely. This patch consolidates the AG preparation stage. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 122 +++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 36 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 1fb72fff5d26..d2595dada0e2 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1130,31 +1130,8 @@ static int xfs_alloc_ag_vextent( struct xfs_alloc_arg *args) { - struct xfs_mount *mp = args->mp; int error = 0; - ASSERT(args->minlen > 0); - ASSERT(args->maxlen > 0); - ASSERT(args->minlen <= args->maxlen); - ASSERT(args->mod < args->prod); - ASSERT(args->alignment > 0); - ASSERT(args->resv != XFS_AG_RESV_AGFL); - - - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - return error; - } - if (!args->agbp) { - /* cannot allocate in this AG at all */ - trace_xfs_alloc_vextent_noagbp(args); - args->agbno = NULLAGBLOCK; - return 0; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - args->wasfromfl = 0; - /* * Branch to correct routine based on the type. */ @@ -3186,11 +3163,18 @@ xfs_alloc_vextent_check_args( args->maxlen = agsize; if (args->alignment == 0) args->alignment = 1; + + ASSERT(args->minlen > 0); + ASSERT(args->maxlen > 0); + ASSERT(args->alignment > 0); + ASSERT(args->resv != XFS_AG_RESV_AGFL); + ASSERT(XFS_FSB_TO_AGNO(mp, target) < mp->m_sb.sb_agcount); ASSERT(XFS_FSB_TO_AGBNO(mp, target) < agsize); ASSERT(args->minlen <= args->maxlen); ASSERT(args->minlen <= agsize); ASSERT(args->mod < args->prod); + if (XFS_FSB_TO_AGNO(mp, target) >= mp->m_sb.sb_agcount || XFS_FSB_TO_AGBNO(mp, target) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || @@ -3202,6 +3186,40 @@ xfs_alloc_vextent_check_args( return 0; } +/* + * Prepare an AG for allocation. If the AG is not prepared to accept the + * allocation, return failure. + * + * XXX(dgc): The complexity of "need_pag" will go away as all caller paths are + * modified to hold their own perag references. + */ +static int +xfs_alloc_vextent_prepare_ag( + struct xfs_alloc_arg *args) +{ + bool need_pag = !args->pag; + int error; + + if (need_pag) + args->pag = xfs_perag_get(args->mp, args->agno); + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + if (need_pag) + xfs_perag_put(args->pag); + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->wasfromfl = 0; + return 0; +} + /* * Post-process allocation results to set the allocated block number correctly * for the caller. @@ -3231,7 +3249,8 @@ xfs_alloc_vextent_set_fsbno( } /* - * Allocate within a single AG only. + * Allocate within a single AG only. Caller is expected to hold a + * perag reference in args->pag. */ int xfs_alloc_vextent_this_ag( @@ -3253,10 +3272,16 @@ xfs_alloc_vextent_this_ag( args->agbno = 0; args->fsbno = target; args->type = XFS_ALLOCTYPE_THIS_AG; - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_vextent_prepare_ag(args); if (error) return error; + if (args->agbp) { + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + } + xfs_alloc_vextent_set_fsbno(args); return 0; } @@ -3294,16 +3319,27 @@ xfs_alloc_vextent_iterate_ags( */ args->agno = start_agno; for (;;) { - args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_ag_vextent(args); - if (error || args->agbp) + args->pag = xfs_perag_get(args->mp, args->agno); + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + error = xfs_alloc_vextent_prepare_ag(args); + if (error) break; + if (args->agbp) { + /* + * Allocation is supposed to succeed now, so break out + * of the loop regardless of whether we succeed or not. + */ + error = xfs_alloc_ag_vextent(args); + break; + } + trace_xfs_alloc_vextent_loopfailed(args); if (args->agno == start_agno && args->otype == XFS_ALLOCTYPE_NEAR_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; + /* * For the first allocation, we can try any AG to get * space. However, if we already have allocated a @@ -3329,14 +3365,14 @@ xfs_alloc_vextent_iterate_ags( } flags = 0; - if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) { - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) args->type = XFS_ALLOCTYPE_NEAR_BNO; - } } xfs_perag_put(args->pag); + args->pag = NULL; } xfs_perag_put(args->pag); + args->pag = NULL; return error; } @@ -3429,7 +3465,8 @@ xfs_alloc_vextent_first_ag( } /* - * Allocate within a single AG only. + * Allocate at the exact block target or fail. Caller is expected to hold a + * perag reference in args->pag. */ int xfs_alloc_vextent_exact_bno( @@ -3450,10 +3487,17 @@ xfs_alloc_vextent_exact_bno( args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->fsbno = target; args->type = XFS_ALLOCTYPE_THIS_BNO; - error = xfs_alloc_ag_vextent(args); + + error = xfs_alloc_vextent_prepare_ag(args); if (error) return error; + if (args->agbp) { + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + } + xfs_alloc_vextent_set_fsbno(args); return 0; } @@ -3461,6 +3505,8 @@ xfs_alloc_vextent_exact_bno( /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. + * + * Caller may or may not have a per-ag reference in args->pag. */ int xfs_alloc_vextent_near_bno( @@ -3481,9 +3527,13 @@ xfs_alloc_vextent_near_bno( args->agno = XFS_FSB_TO_AGNO(mp, target); args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->type = XFS_ALLOCTYPE_NEAR_BNO; - if (need_pag) - args->pag = xfs_perag_get(args->mp, args->agno); - error = xfs_alloc_ag_vextent(args); + + error = xfs_alloc_vextent_prepare_ag(args); + if (error) + return error; + + if (args->agbp) + error = xfs_alloc_ag_vextent(args); if (need_pag) xfs_perag_put(args->pag); if (error) From patchwork Fri Dec 3 00:01:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653901 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 85DCBC4321E for ; Fri, 3 Dec 2021 00:01:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377737AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37649 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377744AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 58B88869E5E for ; Fri, 3 Dec 2021 11:01:24 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LU-EI for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkir-D2 for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 33/36] xfs: move allocation accounting to xfs_alloc_vextent_set_fsbno() Date: Fri, 3 Dec 2021 11:01:08 +1100 Message-Id: <20211203000111.2800982-34-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=wN4_hNFfbszvjEHaC1QA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Move it from xfs_alloc_ag_vextent() so we can get rid of that layer. Rename xfs_alloc_vextent_set_fsbno() to xfs_alloc_vextent_finish() to indicate that it's function is finishing off the allocation that we've run now that it contains much more functionality. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 127 +++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index d2595dada0e2..a1f391a44fe5 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1149,36 +1149,6 @@ xfs_alloc_ag_vextent( ASSERT(0); /* NOTREACHED */ } - - if (error || args->agbno == NULLAGBLOCK) - return error; - - ASSERT(args->len >= args->minlen); - ASSERT(args->len <= args->maxlen); - ASSERT(args->agbno % args->alignment == 0); - - /* if not file data, insert new block into the reverse map btree */ - if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { - error = xfs_rmap_alloc(args->tp, args->agbp, args->pag, - args->agbno, args->len, &args->oinfo); - if (error) - return error; - } - - if (!args->wasfromfl) { - error = xfs_alloc_update_counters(args->tp, args->agbp, - -((long)(args->len))); - if (error) - return error; - - ASSERT(!xfs_extent_busy_search(args->mp, args->pag, - args->agbno, args->len)); - } - - xfs_ag_resv_alloc_extent(args->pag, args->resv, args); - - XFS_STATS_INC(args->mp, xs_allocx); - XFS_STATS_ADD(args->mp, xs_allocb, args->len); return error; } @@ -3221,31 +3191,56 @@ xfs_alloc_vextent_prepare_ag( } /* - * Post-process allocation results to set the allocated block number correctly - * for the caller. + * Post-process allocation results to account for the allocation if it succeed + * and set the allocated block number correctly for the caller. * - * XXX: xfs_alloc_vextent() should really be returning ENOSPC for ENOSPC, not + * XXX: we should really be returning ENOSPC for ENOSPC, not * hiding it behind a "successful" NULLFSBLOCK allocation. */ -static void -xfs_alloc_vextent_set_fsbno( +static int +xfs_alloc_vextent_finish( struct xfs_alloc_arg *args) { - struct xfs_mount *mp = args->mp; + int error = 0; /* Allocation failed with ENOSPC if NULLAGBLOCK was returned. */ if (args->agbno == NULLAGBLOCK) { args->fsbno = NULLFSBLOCK; - return; + return 0; } - args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); -#ifdef DEBUG + args->fsbno = XFS_AGB_TO_FSB(args->mp, args->agno, args->agbno); + ASSERT(args->len >= args->minlen); ASSERT(args->len <= args->maxlen); ASSERT(args->agbno % args->alignment == 0); - XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); -#endif + XFS_AG_CHECK_DADDR(args->mp, XFS_FSB_TO_DADDR(args->mp, args->fsbno), + args->len); + + /* if not file data, insert new block into the reverse map btree */ + if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { + error = xfs_rmap_alloc(args->tp, args->agbp, args->pag, + args->agbno, args->len, &args->oinfo); + if (error) + return error; + } + + if (!args->wasfromfl) { + error = xfs_alloc_update_counters(args->tp, args->agbp, + -((long)(args->len))); + if (error) + return error; + + ASSERT(!xfs_extent_busy_search(args->mp, args->pag, + args->agbno, args->len)); + } + + xfs_ag_resv_alloc_extent(args->pag, args->resv, args); + + XFS_STATS_INC(args->mp, xs_allocx); + XFS_STATS_ADD(args->mp, xs_allocb, args->len); + + return 0; } /* @@ -3282,8 +3277,7 @@ xfs_alloc_vextent_this_ag( return error; } - xfs_alloc_vextent_set_fsbno(args); - return 0; + return xfs_alloc_vextent_finish(args); } /* @@ -3371,8 +3365,10 @@ xfs_alloc_vextent_iterate_ags( xfs_perag_put(args->pag); args->pag = NULL; } - xfs_perag_put(args->pag); - args->pag = NULL; + /* + * On success, perag is left referenced in args for the caller to clean + * up after they've finished the allocation. + */ return error; } @@ -3418,8 +3414,12 @@ xfs_alloc_vextent_start_ag( error = xfs_alloc_vextent_iterate_ags(args, start_agno, XFS_ALLOC_FLAG_TRYLOCK); - if (error) - return error; + if (!error) + error = xfs_alloc_vextent_finish(args); + if (args->pag) { + xfs_perag_put(args->pag); + args->pag = NULL; + } if (bump_rotor) { if (args->agno == start_agno) @@ -3430,8 +3430,7 @@ xfs_alloc_vextent_start_ag( (mp->m_sb.sb_agcount * rotorstep); } - xfs_alloc_vextent_set_fsbno(args); - return 0; + return error; } /* @@ -3458,10 +3457,13 @@ xfs_alloc_vextent_first_ag( args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, XFS_FSB_TO_AGNO(mp, args->fsbno), 0); - if (error) - return error; - xfs_alloc_vextent_set_fsbno(args); - return 0; + if (!error) + error = xfs_alloc_vextent_finish(args); + if (args->pag) { + xfs_perag_put(args->pag); + args->pag = NULL; + } + return error; } /* @@ -3492,14 +3494,11 @@ xfs_alloc_vextent_exact_bno( if (error) return error; - if (args->agbp) { + if (args->agbp) error = xfs_alloc_ag_vextent(args); - if (error) - return error; - } - - xfs_alloc_vextent_set_fsbno(args); - return 0; + if (!error) + error = xfs_alloc_vextent_finish(args); + return error; } /* @@ -3534,13 +3533,11 @@ xfs_alloc_vextent_near_bno( if (args->agbp) error = xfs_alloc_ag_vextent(args); + if (!error) + error = xfs_alloc_vextent_finish(args); if (need_pag) xfs_perag_put(args->pag); - if (error) - return error; - - xfs_alloc_vextent_set_fsbno(args); - return 0; + return error; } /* Ensure that the freelist is at full capacity. */ From patchwork Fri Dec 3 00:01:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653881 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 088F6C433FE for ; Fri, 3 Dec 2021 00:01:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349677AbhLCAEp (ORCPT ); Thu, 2 Dec 2021 19:04:45 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:35761 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377726AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id B47F0869DA3 for ; Fri, 3 Dec 2021 11:01:18 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1LX-Fb for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkiw-EI for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 34/36] xfs: fold xfs_alloc_ag_vextent() into callers Date: Fri, 3 Dec 2021 11:01:09 +1100 Message-Id: <20211203000111.2800982-35-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=epq8cqlX c=1 sm=1 tr=0 ts=61a95e4e a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=Hfmiz4SQFC9lsfJXRUIA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We don't need the multiplexing xfs_alloc_ag_vextent() provided anymore - we can just call the exact/near/size variants directly. This allows us to remove args->type completely and stop using args->fsbno as an input to the allocator algorithms. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 97 ++++++++------------------------------- fs/xfs/libxfs/xfs_alloc.h | 17 ------- fs/xfs/libxfs/xfs_bmap.c | 10 +--- fs/xfs/xfs_trace.h | 8 +--- 4 files changed, 23 insertions(+), 109 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index a1f391a44fe5..b15dee98090a 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -36,10 +36,6 @@ struct workqueue_struct *xfs_alloc_wq; #define XFSA_FIXUP_BNO_OK 1 #define XFSA_FIXUP_CNT_OK 2 -STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); -STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); -STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); - /* * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in * the beginning of the block for a proper header with the location information @@ -758,8 +754,6 @@ xfs_alloc_cur_setup( int error; int i; - ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO); - acur->cur_len = args->maxlen; acur->rec_bno = 0; acur->rec_len = 0; @@ -873,7 +867,6 @@ xfs_alloc_cur_check( * We have an aligned record that satisfies minlen and beats or matches * the candidate extent size. Compare locality for near allocation mode. */ - ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); diff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, args->datatype, bnoa, lena, &bnew); @@ -1118,40 +1111,6 @@ xfs_alloc_ag_vextent_small( return error; } -/* - * Allocate a variable extent in the allocation group agno. - * Type and bno are used to determine where in the allocation group the - * extent will start. - * Extent's length (returned in *len) will be between minlen and maxlen, - * and of the form k * prod + mod unless there's nothing that large. - * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. - */ -static int -xfs_alloc_ag_vextent( - struct xfs_alloc_arg *args) -{ - int error = 0; - - /* - * Branch to correct routine based on the type. - */ - switch (args->type) { - case XFS_ALLOCTYPE_THIS_AG: - error = xfs_alloc_ag_vextent_size(args); - break; - case XFS_ALLOCTYPE_NEAR_BNO: - error = xfs_alloc_ag_vextent_near(args); - break; - case XFS_ALLOCTYPE_THIS_BNO: - error = xfs_alloc_ag_vextent_exact(args); - break; - default: - ASSERT(0); - /* NOTREACHED */ - } - return error; -} - /* * Allocate a variable extent at exactly agno/bno. * Extent's length (returned in *len) will be between minlen and maxlen, @@ -1337,7 +1296,6 @@ xfs_alloc_ag_vextent_locality( bool fbinc; ASSERT(acur->len == 0); - ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); *stat = 0; @@ -3122,6 +3080,7 @@ xfs_alloc_vextent_check_args( xfs_agblock_t agsize; args->agbno = NULLAGBLOCK; + args->fsbno = NULLFSBLOCK; /* * Just fix this up, for the case where the last a.g. is shorter @@ -3244,8 +3203,11 @@ xfs_alloc_vextent_finish( } /* - * Allocate within a single AG only. Caller is expected to hold a - * perag reference in args->pag. + * Allocate within a single AG only. This uses a best-fit length algorithm so if + * you need an exact sized allocation without locality constraints, this is the + * fastest way to do it. + * + * Caller is expected to hold a perag reference in args->pag. */ int xfs_alloc_vextent_this_ag( @@ -3254,9 +3216,8 @@ xfs_alloc_vextent_this_ag( { struct xfs_mount *mp = args->mp; int error; - xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); - error = xfs_alloc_vextent_check_args(args, target); + error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0)); if (error) { if (error == -ENOSPC) return 0; @@ -3265,14 +3226,12 @@ xfs_alloc_vextent_this_ag( args->agno = agno; args->agbno = 0; - args->fsbno = target; - args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_vextent_prepare_ag(args); if (error) return error; if (args->agbp) { - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_size(args); if (error) return error; } @@ -3302,6 +3261,7 @@ static int xfs_alloc_vextent_iterate_ags( struct xfs_alloc_arg *args, xfs_agnumber_t start_agno, + xfs_agblock_t target_agbno, uint32_t flags) { struct xfs_mount *mp = args->mp; @@ -3313,8 +3273,8 @@ xfs_alloc_vextent_iterate_ags( */ args->agno = start_agno; for (;;) { + args->agbno = target_agbno; args->pag = xfs_perag_get(args->mp, args->agno); - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); error = xfs_alloc_vextent_prepare_ag(args); if (error) break; @@ -3324,16 +3284,15 @@ xfs_alloc_vextent_iterate_ags( * Allocation is supposed to succeed now, so break out * of the loop regardless of whether we succeed or not. */ - error = xfs_alloc_ag_vextent(args); + if (args->agno == start_agno && target_agbno) + error = xfs_alloc_ag_vextent_near(args); + else + error = xfs_alloc_ag_vextent_size(args); break; } trace_xfs_alloc_vextent_loopfailed(args); - if (args->agno == start_agno && - args->otype == XFS_ALLOCTYPE_NEAR_BNO) - args->type = XFS_ALLOCTYPE_THIS_AG; - /* * For the first allocation, we can try any AG to get * space. However, if we already have allocated a @@ -3357,10 +3316,7 @@ xfs_alloc_vextent_iterate_ags( trace_xfs_alloc_vextent_allfailed(args); break; } - flags = 0; - if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) - args->type = XFS_ALLOCTYPE_NEAR_BNO; } xfs_perag_put(args->pag); args->pag = NULL; @@ -3386,8 +3342,8 @@ xfs_alloc_vextent_start_ag( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t start_agno; xfs_agnumber_t rotorstep = xfs_rotorstep; + xfs_agnumber_t start_agno = XFS_FSB_TO_AGNO(mp, target); bool bump_rotor = false; int error; @@ -3406,14 +3362,8 @@ xfs_alloc_vextent_start_ag( bump_rotor = 1; } - start_agno = XFS_FSB_TO_AGNO(mp, target); - args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->otype = XFS_ALLOCTYPE_NEAR_BNO; - args->type = XFS_ALLOCTYPE_NEAR_BNO; - args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, start_agno, - XFS_ALLOC_FLAG_TRYLOCK); + XFS_FSB_TO_AGBNO(mp, target), XFS_ALLOC_FLAG_TRYLOCK); if (!error) error = xfs_alloc_vextent_finish(args); if (args->pag) { @@ -3453,10 +3403,8 @@ xfs_alloc_vextent_first_ag( return error; } - args->type = XFS_ALLOCTYPE_THIS_AG; - args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, - XFS_FSB_TO_AGNO(mp, args->fsbno), 0); + error = xfs_alloc_vextent_iterate_ags(args, + XFS_FSB_TO_AGNO(mp, target), 0, 0); if (!error) error = xfs_alloc_vextent_finish(args); if (args->pag) { @@ -3487,15 +3435,12 @@ xfs_alloc_vextent_exact_bno( args->agno = XFS_FSB_TO_AGNO(mp, target); args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->fsbno = target; - args->type = XFS_ALLOCTYPE_THIS_BNO; - error = xfs_alloc_vextent_prepare_ag(args); if (error) return error; if (args->agbp) - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_exact(args); if (!error) error = xfs_alloc_vextent_finish(args); return error; @@ -3525,14 +3470,12 @@ xfs_alloc_vextent_near_bno( args->agno = XFS_FSB_TO_AGNO(mp, target); args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - error = xfs_alloc_vextent_prepare_ag(args); if (error) return error; if (args->agbp) - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_near(args); if (!error) error = xfs_alloc_vextent_finish(args); if (need_pag) diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index d61c3803c5dc..2d7b2066e156 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -16,21 +16,6 @@ extern struct workqueue_struct *xfs_alloc_wq; unsigned int xfs_agfl_size(struct xfs_mount *mp); -/* - * Freespace allocation types. Argument to xfs_alloc_[v]extent. - */ -#define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ -#define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ -#define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ - -/* this should become an enum again when the tracing code is fixed */ -typedef unsigned int xfs_alloctype_t; - -#define XFS_ALLOC_TYPES \ - { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ - { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ - { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } - /* * Flags for xfs_alloc_fix_freelist. */ @@ -64,8 +49,6 @@ typedef struct xfs_alloc_arg { xfs_agblock_t min_agbno; /* set an agbno range for NEAR allocs */ xfs_agblock_t max_agbno; /* ... */ xfs_extlen_t len; /* output: actual size of extent */ - xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ - xfs_alloctype_t otype; /* original allocation type */ int datatype; /* mask defining data type treatment */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4227007a4f9d..ab8f2d633bd6 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3512,7 +3512,6 @@ xfs_btalloc_at_eof( bool ag_only) { struct xfs_mount *mp = args->mp; - xfs_alloctype_t atype; int error; /* @@ -3524,14 +3523,12 @@ xfs_btalloc_at_eof( if (ap->offset) { xfs_extlen_t nextminlen = 0; - atype = args->type; - args->alignment = 1; - /* * Compute the minlen+alignment for the next case. Set slop so * that the value of minlen+alignment+slop doesn't go up between * the calls. */ + args->alignment = 1; if (blen > stripe_align && blen <= args->maxlen) nextminlen = blen - stripe_align; else @@ -3555,17 +3552,15 @@ xfs_btalloc_at_eof( * according to the original allocation specification. */ args->pag = NULL; - args->type = atype; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; } else { - args->alignment = stripe_align; - atype = args->type; /* * Adjust minlen to try and preserve alignment if we * can't guarantee an aligned maxlen extent. */ + args->alignment = stripe_align; if (blen > args->alignment && blen <= args->maxlen + args->alignment) args->minlen = blen - args->alignment; @@ -3587,7 +3582,6 @@ xfs_btalloc_at_eof( * original non-aligned state so the caller can proceed on allocation * failure as if this function was never called. */ - args->type = atype; args->fsbno = ap->blkno; args->alignment = 1; return 0; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 40ee3bc33cd4..fdcc4d6e098b 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1805,8 +1805,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __field(xfs_extlen_t, alignment) __field(xfs_extlen_t, minalignslop) __field(xfs_extlen_t, len) - __field(short, type) - __field(short, otype) __field(char, wasdel) __field(char, wasfromfl) __field(int, resv) @@ -1826,8 +1824,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->alignment = args->alignment; __entry->minalignslop = args->minalignslop; __entry->len = args->len; - __entry->type = args->type; - __entry->otype = args->otype; __entry->wasdel = args->wasdel; __entry->wasfromfl = args->wasfromfl; __entry->resv = args->resv; @@ -1836,7 +1832,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, ), TP_printk("dev %d:%d agno 0x%x agbno 0x%x minlen %u maxlen %u mod %u " "prod %u minleft %u total %u alignment %u minalignslop %u " - "len %u type %s otype %s wasdel %d wasfromfl %d resv %d " + "len %u wasdel %d wasfromfl %d resv %d " "datatype 0x%x firstblock 0x%llx", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, @@ -1850,8 +1846,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->alignment, __entry->minalignslop, __entry->len, - __print_symbolic(__entry->type, XFS_ALLOC_TYPES), - __print_symbolic(__entry->otype, XFS_ALLOC_TYPES), __entry->wasdel, __entry->wasfromfl, __entry->resv, From patchwork Fri Dec 3 00:01:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653899 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 38640C43217 for ; Fri, 3 Dec 2021 00:01:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377739AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:37651 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377734AbhLCAEu (ORCPT ); Thu, 2 Dec 2021 19:04:50 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 9616B869E6D for ; Fri, 3 Dec 2021 11:01:24 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1La-Gu for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkj1-FY for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 35/36] xfs: convert xfs_alloc_vextent_iterate_ags() to use perag walker Date: Fri, 3 Dec 2021 11:01:10 +1100 Message-Id: <20211203000111.2800982-36-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=e9dl9Yl/ c=1 sm=1 tr=0 ts=61a95e54 a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=rPMLGPRgkIbOATDFbHwA:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that the AG iteration code in the core allocation code has been cleaned up, we can easily convert it to use a for_each_perag..() variant to use active references and skip AGs that it can't get active references on. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.h | 22 ++++++--- fs/xfs/libxfs/xfs_alloc.c | 97 ++++++++++++++++++++------------------- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 23040a1094b9..2198166efa2f 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -244,6 +244,7 @@ xfs_perag_next_wrap( struct xfs_perag *pag, xfs_agnumber_t *agno, xfs_agnumber_t stop_agno, + xfs_agnumber_t restart_agno, xfs_agnumber_t wrap_agno) { struct xfs_mount *mp = pag->pag_mount; @@ -251,10 +252,11 @@ xfs_perag_next_wrap( *agno = pag->pag_agno + 1; xfs_perag_rele(pag); while (*agno != stop_agno) { - if (*agno >= wrap_agno) - *agno = 0; - if (*agno == stop_agno) - break; + if (*agno >= wrap_agno) { + if (restart_agno >= stop_agno) + break; + *agno = restart_agno; + } pag = xfs_perag_grab(mp, *agno); if (pag) @@ -265,14 +267,20 @@ xfs_perag_next_wrap( } /* - * Iterate all AGs from start_agno through wrap_agno, then 0 through + * Iterate all AGs from start_agno through wrap_agno, then restart_agno through * (start_agno - 1). */ -#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ +#define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \ for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \ (pag) != NULL; \ (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \ - (wrap_agno))) + (restart_agno), (wrap_agno))) +/* + * Iterate all AGs from start_agno through wrap_agno, then 0 through + * (start_agno - 1). + */ +#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ + for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag)) /* * Iterate all AGs from start_agno through to the end of the filesystem, then 0 diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index b15dee98090a..71bfb0c6150c 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3132,6 +3132,7 @@ xfs_alloc_vextent_prepare_ag( if (need_pag) args->pag = xfs_perag_get(args->mp, args->agno); + args->agbp = NULL; error = xfs_alloc_fix_freelist(args, 0); if (error) { trace_xfs_alloc_vextent_nofix(args); @@ -3253,6 +3254,10 @@ xfs_alloc_vextent_this_ag( * transaction. This will result in an out-of-order locking of AGFs and hence * can cause deadlocks. * + * On return, args->pag may be left referenced if we finish before the "all + * failed" return point. The allocation finish still needs the perag, and + * so the caller will release it once they've finished the allocation. + * * XXX(dgc): when wrapping in potential deadlock scenarios, we could use * try-locks on the AGFs below the critical AG rather than skip them entirely. * We won't deadlock in that case, we'll just skip the AGFs we can't lock. @@ -3265,67 +3270,65 @@ xfs_alloc_vextent_iterate_ags( uint32_t flags) { struct xfs_mount *mp = args->mp; + xfs_agnumber_t restart_agno = 0; + xfs_agnumber_t agno; int error = 0; /* - * Loop over allocation groups twice; first time with - * trylock set, second time without. + * If we already have allocated a block in this transaction, we don't + * want to lock AGs whose number is below the start AG. This results in + * out-of-order locking of AGF and deadlocks will result. */ - args->agno = start_agno; - for (;;) { + if (args->tp->t_firstblock != NULLFSBLOCK) + restart_agno = start_agno; + +restart: + for_each_perag_wrap_range(mp, start_agno, restart_agno, + mp->m_sb.sb_agcount, agno, args->pag) { + args->agno = agno; args->agbno = target_agbno; - args->pag = xfs_perag_get(args->mp, args->agno); + trace_printk("sag %u rag %u agno %u pag %u, agbno %u, agcnt %u", + start_agno, restart_agno, agno, args->pag->pag_agno, + target_agbno, mp->m_sb.sb_agcount); + error = xfs_alloc_vextent_prepare_ag(args); if (error) break; - - if (args->agbp) { - /* - * Allocation is supposed to succeed now, so break out - * of the loop regardless of whether we succeed or not. - */ - if (args->agno == start_agno && target_agbno) - error = xfs_alloc_ag_vextent_near(args); - else - error = xfs_alloc_ag_vextent_size(args); - break; + if (!args->agbp) { + trace_xfs_alloc_vextent_loopfailed(args); + continue; } - trace_xfs_alloc_vextent_loopfailed(args); - /* - * For the first allocation, we can try any AG to get - * space. However, if we already have allocated a - * block, we don't want to try AGs whose number is below - * sagno. Otherwise, we may end up with out-of-order - * locking of AGF, which might cause deadlock. - */ - if (++(args->agno) == mp->m_sb.sb_agcount) { - if (args->tp->t_firstblock != NULLFSBLOCK) - args->agno = start_agno; - else - args->agno = 0; - } - /* - * Reached the starting a.g., must either be done - * or switch to non-trylock mode. + * Allocation is supposed to succeed now, so break out of the + * loop regardless of whether we succeed or not. */ - if (args->agno == start_agno) { - if (flags == 0) { - args->agbno = NULLAGBLOCK; - trace_xfs_alloc_vextent_allfailed(args); - break; - } - flags = 0; - } - xfs_perag_put(args->pag); + if (args->agno == start_agno && target_agbno) + error = xfs_alloc_ag_vextent_near(args); + else + error = xfs_alloc_ag_vextent_size(args); + break; + } + if (error) { + xfs_perag_rele(args->pag); args->pag = NULL; + return error; } + if (args->agbp) + return 0; + /* - * On success, perag is left referenced in args for the caller to clean - * up after they've finished the allocation. + * We didn't find an AG we can alloation from. If we were given + * constraining flags by the caller, drop them and retry the allocation + * without any constraints being set. */ - return error; + if (flags) { + flags = 0; + goto restart; + } + + trace_xfs_alloc_vextent_allfailed(args); + return 0; } /* @@ -3367,7 +3370,7 @@ xfs_alloc_vextent_start_ag( if (!error) error = xfs_alloc_vextent_finish(args); if (args->pag) { - xfs_perag_put(args->pag); + xfs_perag_rele(args->pag); args->pag = NULL; } @@ -3408,7 +3411,7 @@ xfs_alloc_vextent_first_ag( if (!error) error = xfs_alloc_vextent_finish(args); if (args->pag) { - xfs_perag_put(args->pag); + xfs_perag_rele(args->pag); args->pag = NULL; } return error; From patchwork Fri Dec 3 00:01:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 12653875 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 93714C4332F for ; Fri, 3 Dec 2021 00:01:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349743AbhLCAEp (ORCPT ); Thu, 2 Dec 2021 19:04:45 -0500 Received: from mail106.syd.optusnet.com.au ([211.29.132.42]:36185 "EHLO mail106.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377734AbhLCAEo (ORCPT ); Thu, 2 Dec 2021 19:04:44 -0500 Received: from dread.disaster.area (pa49-195-103-97.pa.nsw.optusnet.com.au [49.195.103.97]) by mail106.syd.optusnet.com.au (Postfix) with ESMTPS id 4AD7B869B73 for ; Fri, 3 Dec 2021 11:01:18 +1100 (AEDT) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1msw0p-00G1Ld-IG for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 Received: from dave by discord.disaster.area with local (Exim 4.95) (envelope-from ) id 1msw0p-00Bkj6-Gs for linux-xfs@vger.kernel.org; Fri, 03 Dec 2021 11:01:15 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 36/36] xfs: convert trim to use for_each_perag_range Date: Fri, 3 Dec 2021 11:01:11 +1100 Message-Id: <20211203000111.2800982-37-david@fromorbit.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203000111.2800982-1-david@fromorbit.com> References: <20211203000111.2800982-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.4 cv=VuxAv86n c=1 sm=1 tr=0 ts=61a95e4e a=fP9RlOTWD4uZJjPSFnn6Ew==:117 a=fP9RlOTWD4uZJjPSFnn6Ew==:17 a=IOMw9HtfNCkA:10 a=20KFwNOVAAAA:8 a=PynOkrAUnEEYtSWtPP4A:9 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner To convert it to using active perag references and hence make it shrink safe. Signed-off-by: Dave Chinner --- fs/xfs/xfs_discard.c | 50 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index ccec28c914cd..310d760376a5 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -21,23 +21,20 @@ STATIC int xfs_trim_extents( - struct xfs_mount *mp, - xfs_agnumber_t agno, + struct xfs_perag *pag, xfs_daddr_t start, xfs_daddr_t end, xfs_daddr_t minlen, uint64_t *blocks_trimmed) { + struct xfs_mount *mp = pag->pag_mount; struct block_device *bdev = mp->m_ddev_targp->bt_bdev; struct xfs_btree_cur *cur; struct xfs_buf *agbp; struct xfs_agf *agf; - struct xfs_perag *pag; int error; int i; - pag = xfs_perag_get(mp, agno); - /* * Force out the log. This means any transactions that might have freed * space before we take the AGF buffer lock are now on disk, and the @@ -47,7 +44,7 @@ xfs_trim_extents( error = xfs_alloc_read_agf(pag, NULL, 0, &agbp); if (error) - goto out_put_perag; + return error; agf = agbp->b_addr; cur = xfs_allocbt_init_cursor(mp, NULL, agbp, pag, XFS_BTNUM_CNT); @@ -71,10 +68,10 @@ xfs_trim_extents( error = xfs_alloc_get_rec(cur, &fbno, &flen, &i); if (error) - goto out_del_cursor; + break; if (XFS_IS_CORRUPT(mp, i != 1)) { error = -EFSCORRUPTED; - goto out_del_cursor; + break; } ASSERT(flen <= be32_to_cpu(agf->agf_longest)); @@ -83,15 +80,15 @@ xfs_trim_extents( * the format the range/len variables are supplied in by * userspace. */ - dbno = XFS_AGB_TO_DADDR(mp, agno, fbno); + dbno = XFS_AGB_TO_DADDR(mp, pag->pag_agno, fbno); dlen = XFS_FSB_TO_BB(mp, flen); /* * Too small? Give up. */ if (dlen < minlen) { - trace_xfs_discard_toosmall(mp, agno, fbno, flen); - goto out_del_cursor; + trace_xfs_discard_toosmall(mp, pag->pag_agno, fbno, flen); + break; } /* @@ -100,7 +97,7 @@ xfs_trim_extents( * down partially overlapping ranges for now. */ if (dbno + dlen < start || dbno > end) { - trace_xfs_discard_exclude(mp, agno, fbno, flen); + trace_xfs_discard_exclude(mp, pag->pag_agno, fbno, flen); goto next_extent; } @@ -109,32 +106,30 @@ xfs_trim_extents( * discard and try again the next time. */ if (xfs_extent_busy_search(mp, pag, fbno, flen)) { - trace_xfs_discard_busy(mp, agno, fbno, flen); + trace_xfs_discard_busy(mp, pag->pag_agno, fbno, flen); goto next_extent; } - trace_xfs_discard_extent(mp, agno, fbno, flen); + trace_xfs_discard_extent(mp, pag->pag_agno, fbno, flen); error = blkdev_issue_discard(bdev, dbno, dlen, GFP_NOFS, 0); if (error) - goto out_del_cursor; + break; *blocks_trimmed += flen; next_extent: error = xfs_btree_decrement(cur, 0, &i); if (error) - goto out_del_cursor; + break; if (fatal_signal_pending(current)) { error = -ERESTARTSYS; - goto out_del_cursor; + break; } } out_del_cursor: xfs_btree_del_cursor(cur, error); xfs_buf_relse(agbp); -out_put_perag: - xfs_perag_put(pag); return error; } @@ -152,11 +147,12 @@ xfs_ioc_trim( struct xfs_mount *mp, struct fstrim_range __user *urange) { + struct xfs_perag *pag; struct request_queue *q = bdev_get_queue(mp->m_ddev_targp->bt_bdev); unsigned int granularity = q->limits.discard_granularity; struct fstrim_range range; xfs_daddr_t start, end, minlen; - xfs_agnumber_t start_agno, end_agno, agno; + xfs_agnumber_t agno; uint64_t blocks_trimmed = 0; int error, last_error = 0; @@ -193,18 +189,18 @@ xfs_ioc_trim( end = start + BTOBBT(range.len) - 1; if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1) - end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1; - - start_agno = xfs_daddr_to_agno(mp, start); - end_agno = xfs_daddr_to_agno(mp, end); + end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1; - for (agno = start_agno; agno <= end_agno; agno++) { - error = xfs_trim_extents(mp, agno, start, end, minlen, + agno = xfs_daddr_to_agno(mp, start); + for_each_perag_range(mp, agno, xfs_daddr_to_agno(mp, end), pag) { + error = xfs_trim_extents(pag, start, end, minlen, &blocks_trimmed); if (error) { last_error = error; - if (error == -ERESTARTSYS) + if (error == -ERESTARTSYS) { + xfs_perag_rele(pag); break; + } } }