]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: pass the exact range to initialize to xfs_initialize_perag
authorChristoph Hellwig <hch@lst.de>
Mon, 28 Oct 2024 05:11:47 +0000 (22:11 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 31 Oct 2024 22:45:04 +0000 (15:45 -0700)
Source kernel commit: 82742f8c3f1a93787a05a00aca50c2a565231f84

Currently only the new agcount is passed to xfs_initialize_perag, which
requires lookups of existing AGs to skip them and complicates error
handling.  Also pass the previous agcount so that the range that
xfs_initialize_perag operates on is exactly defined.  That way the
extra lookups can be avoided, and error handling can clean up the
exact range from the old count to the last added perag structure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
libxfs/xfs_ag.c
libxfs/xfs_ag.h

index 516c76790cc0d8e0daedc69a5e47dd6a96e9144d..3bbfefe5e469356be2e4fa14d2deccf46a9801cc 100644 (file)
@@ -294,27 +294,16 @@ xfs_free_unused_perag_range(
 int
 xfs_initialize_perag(
        struct xfs_mount        *mp,
-       xfs_agnumber_t          agcount,
+       xfs_agnumber_t          old_agcount,
+       xfs_agnumber_t          new_agcount,
        xfs_rfsblock_t          dblocks,
        xfs_agnumber_t          *maxagi)
 {
        struct xfs_perag        *pag;
        xfs_agnumber_t          index;
-       xfs_agnumber_t          first_initialised = NULLAGNUMBER;
        int                     error;
 
-       /*
-        * Walk the current per-ag tree so we don't try to initialise AGs
-        * that already exist (growfs case). Allocate and insert all the
-        * AGs we don't find ready for initialisation.
-        */
-       for (index = 0; index < agcount; index++) {
-               pag = xfs_perag_get(mp, index);
-               if (pag) {
-                       xfs_perag_put(pag);
-                       continue;
-               }
-
+       for (index = old_agcount; index < new_agcount; index++) {
                pag = kzalloc(sizeof(*pag), GFP_KERNEL | __GFP_RETRY_MAYFAIL);
                if (!pag) {
                        error = -ENOMEM;
@@ -351,21 +340,17 @@ xfs_initialize_perag(
                /* 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;
-
                /*
                 * Pre-calculated geometry
                 */
-               pag->block_count = __xfs_ag_block_count(mp, index, agcount,
+               pag->block_count = __xfs_ag_block_count(mp, index, new_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);
+       index = xfs_set_inode_alloc(mp, new_agcount);
 
        if (maxagi)
                *maxagi = index;
@@ -379,8 +364,7 @@ out_remove_pag:
 out_free_pag:
        kfree(pag);
 out_unwind_new_pags:
-       /* unwind any prior newly initialized pags */
-       xfs_free_unused_perag_range(mp, first_initialised, agcount);
+       xfs_free_unused_perag_range(mp, old_agcount, index);
        return error;
 }
 
index d9cccd093b60e06a5d16f79662471e67455329fc..69fc31e7b8472832c23d63091737399e46158983 100644 (file)
@@ -146,8 +146,9 @@ __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
 
 void xfs_free_unused_perag_range(struct xfs_mount *mp, xfs_agnumber_t agstart,
                        xfs_agnumber_t agend);
-int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
-                       xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
+int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
+               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);
 void xfs_free_perag(struct xfs_mount *mp);