xfs: Pre-calculate per-AG agbno geometry
authorDave Chinner <dchinner@redhat.com>
Thu, 7 Jul 2022 09:13:02 +0000 (19:13 +1000)
committerDave Chinner <david@fromorbit.com>
Thu, 7 Jul 2022 09:13:02 +0000 (19:13 +1000)
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 1483006  329588     572 1813166  1baaae (TOTALS)
after 1482185  329588     572 1812345  1ba779 (TOTALS)

This rework reduces the binary size by ~820 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 <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
17 files changed:
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/libxfs/xfs_rmap.c
fs/xfs/libxfs/xfs_types.c
fs/xfs/libxfs/xfs_types.h
fs/xfs/scrub/agheader.c
fs/xfs/scrub/agheader_repair.c
fs/xfs/scrub/alloc.c
fs/xfs/scrub/ialloc.c
fs/xfs/scrub/refcount.c
fs/xfs/scrub/rmap.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c

index 1fa172501b3d9cf93548ef331c837ed720c9f2c4..8f3e6ee85c34bd0d19d3a757439c9d0cae5d9321 100644 (file)
@@ -201,10 +201,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;
@@ -270,6 +295,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. */
index 1132cda9a92fe5d44df6589b11a506ba12288643..77640f1409fd5ab04debd65268c1ab00d79f09fe 100644 (file)
@@ -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
  */
index ea9452950647b72804c0005b77311ffd890e92f0..41557c430cb6e979efa8ea71b710ceb16bcfed28 100644 (file)
@@ -248,7 +248,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;
 
@@ -263,11 +263,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;
@@ -275,7 +275,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;
index 2eecc49fc1b2d31d44652bc4f3c8228ef06b84c2..06ab364d2de31964fb7a98ba0eea00dda2e0747a 100644 (file)
@@ -91,10 +91,9 @@ xfs_btree_check_lblock_siblings(
 
 static inline xfs_failaddr_t
 xfs_btree_check_sblock_siblings(
-       struct xfs_mount        *mp,
+       struct xfs_perag        *pag,
        struct xfs_btree_cur    *cur,
        int                     level,
-       xfs_agnumber_t          agno,
        xfs_agblock_t           agbno,
        __be32                  dsibling)
 {
@@ -110,7 +109,7 @@ xfs_btree_check_sblock_siblings(
                if (!xfs_btree_check_sptr(cur, sibling, level + 1))
                        return __this_address;
        } else {
-               if (!xfs_verify_agbno(mp, agno, sibling))
+               if (!xfs_verify_agbno(pag, sibling))
                        return __this_address;
        }
        return NULL;
@@ -195,11 +194,11 @@ __xfs_btree_check_sblock(
        struct xfs_buf          *bp)
 {
        struct xfs_mount        *mp = cur->bc_mp;
+       struct xfs_perag        *pag = cur->bc_ag.pag;
        xfs_btnum_t             btnum = cur->bc_btnum;
        int                     crc = xfs_has_crc(mp);
        xfs_failaddr_t          fa;
        xfs_agblock_t           agbno = NULLAGBLOCK;
-       xfs_agnumber_t          agno = NULLAGNUMBER;
 
        if (crc) {
                if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -217,16 +216,14 @@ __xfs_btree_check_sblock(
            cur->bc_ops->get_maxrecs(cur, level))
                return __this_address;
 
-       if (bp) {
+       if (bp)
                agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
-               agno = xfs_daddr_to_agno(mp, xfs_buf_daddr(bp));
-       }
 
-       fa = xfs_btree_check_sblock_siblings(mp, cur, level, agno, agbno,
+       fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno,
                        block->bb_u.s.bb_leftsib);
        if (!fa)
-               fa = xfs_btree_check_sblock_siblings(mp, cur, level, agno,
-                                agbno, block->bb_u.s.bb_rightsib);
+               fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno,
+                               block->bb_u.s.bb_rightsib);
        return fa;
 }
 
@@ -288,7 +285,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);
 }
 
 /*
@@ -4595,7 +4592,6 @@ xfs_btree_sblock_verify(
 {
        struct xfs_mount        *mp = bp->b_mount;
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
-       xfs_agnumber_t          agno;
        xfs_agblock_t           agbno;
        xfs_failaddr_t          fa;
 
@@ -4604,12 +4600,11 @@ xfs_btree_sblock_verify(
                return __this_address;
 
        /* sibling pointer verification */
-       agno = xfs_daddr_to_agno(mp, xfs_buf_daddr(bp));
        agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
-       fa = xfs_btree_check_sblock_siblings(mp, NULL, -1, agno, agbno,
+       fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno,
                        block->bb_u.s.bb_leftsib);
        if (!fa)
-               fa = xfs_btree_check_sblock_siblings(mp, NULL, -1, agno, agbno,
+               fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno,
                                block->bb_u.s.bb_rightsib);
        return fa;
 }
index 098dac888c228053d1ebd7dd5244eea1099fb309..64b910caafaad42a2a6e92f682ca21165b06b3b0 100644 (file)
@@ -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);
index 2845019d31da1c9e1b9b28a7cbffbbacee51c46f..094dfc897ebcdf27ebd4ad7f30bfd8b551d849a4 100644 (file)
@@ -215,7 +215,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;
 
@@ -235,12 +235,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;
        }
@@ -254,7 +254,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,
index e810d23f2d97f170623075ef69c4408a47d667a0..b3c6b0274e956c13b6779c8f04b248ded47bfc2f 100644 (file)
 #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));
 }
 
 /*
index 373f64a492a4feb044a67880aefa26bfad271a27..ccf61afb959df74ba10b437dd12cea5898ffbdf5 100644 (file)
@@ -179,9 +179,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);
index 90aebfe9dc5fa456bf25617f5b698d299c65178f..181bba5f9b8f369c5d050a569043f5695607bcd1 100644 (file)
@@ -541,16 +541,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]);
@@ -563,7 +563,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]);
@@ -573,7 +573,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);
@@ -639,9 +639,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
@@ -871,12 +870,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);
@@ -885,7 +884,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);
index 10ac1118a5958ee4e82f971a32377a8c475bea2d..ba012a5da0bf912fbedae0bd9f42b118ce75d4a9 100644 (file)
@@ -106,7 +106,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;
 }
@@ -130,10 +130,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;
 }
 
index 87518e1292f84a16b5f26f10d8a92ef70175992e..ab427b4d7fe0b8be847f2574dfee962ec4209ee9 100644 (file)
@@ -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);
index 00848ee542fbaac7f6e1588ca50e45839cf84822..b80a54be8634518870548128db6a7e783e2ad403 100644 (file)
@@ -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);
index 2744eecdbaf018628e8069c6dcdd1b0fc7e3c069..3f82a1a1f3906fc3e90aa51468be0c80c7caf6be 100644 (file)
@@ -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)
index 8dae0345c7dfcf13f8a088d81989308573fda81d..229826b2e1c0723c849791204d1747c17a2699b2 100644 (file)
@@ -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);
        }
index 7be4d83d588470049221989ac6f276352e75be50..5fe9af24dfcd2afd2f60e5fca8693a2ea0f3f208 100644 (file)
@@ -132,7 +132,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) {
index 38aae3409c96b100986314dbead5917a213d1b35..3e8c62c6c2b1571c730be4f049eaac45b295816b 100644 (file)
@@ -3313,7 +3313,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;
index daa8d29c46b49da832f1232614c27d160a6251b4..f10c88cee116e17619a9ca03f08f87c998180ddd 100644 (file)
@@ -778,7 +778,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;