From: Dave Chinner Date: Mon, 22 Aug 2022 14:02:59 +0000 (+0200) Subject: xfs: Pre-calculate per-AG agbno geometry X-Git-Tag: v6.0.0-rc0~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83af0d13a62df25a1c994ad7c507cc0196903b5e;p=thirdparty%2Fxfsprogs-dev.git xfs: Pre-calculate per-AG agbno geometry Source kernel commit: 0800169e3e2c97a033e8b7f3d1e6c689e0d71a19 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 Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- diff --git a/libxfs/init.c b/libxfs/init.c index 15052696c..93dc1f1c5 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -892,7 +892,8 @@ libxfs_mount( libxfs_buf_relse(bp); } - error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); + error = libxfs_initialize_perag(mp, sbp->sb_agcount, sbp->sb_dblocks, + &mp->m_maxagi); if (error) { fprintf(stderr, _("%s: perag init failed\n"), progname); diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c index 9e43820df..4762d7138 100644 --- a/libxfs/xfs_ag.c +++ b/libxfs/xfs_ag.c @@ -199,10 +199,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; @@ -268,6 +293,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); @@ -925,10 +957,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/libxfs/xfs_ag.h b/libxfs/xfs_ag.h index 1132cda9a..77640f140 100644 --- a/libxfs/xfs_ag.h +++ b/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/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 5cb0b331d..91f5761a9 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -244,7 +244,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; @@ -259,11 +259,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; @@ -271,7 +271,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/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 77a639208..4048cd9ff 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -88,10 +88,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) { @@ -107,7 +106,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; @@ -192,11 +191,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)) @@ -214,16 +213,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; } @@ -285,7 +282,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); } /* @@ -4592,7 +4589,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; @@ -4601,12 +4597,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; } diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c index f287cdea5..bcd760fe1 100644 --- a/libxfs/xfs_refcount.c +++ b/libxfs/xfs_refcount.c @@ -110,7 +110,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; @@ -120,8 +120,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; @@ -136,22 +134,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/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c index 9ea2227db..fa4ae8fca 100644 --- a/libxfs/xfs_rmap.c +++ b/libxfs/xfs_rmap.c @@ -214,7 +214,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; @@ -234,12 +234,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; } @@ -253,7 +253,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/libxfs/xfs_types.c b/libxfs/xfs_types.c index c4cc5ce5a..bbc86aeb4 100644 --- a/libxfs/xfs_types.c +++ b/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/libxfs/xfs_types.h b/libxfs/xfs_types.h index 373f64a49..ccf61afb9 100644 --- a/libxfs/xfs_types.h +++ b/libxfs/xfs_types.h @@ -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); diff --git a/repair/scan.c b/repair/scan.c index 020fb02f3..a8c5cc5dd 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -584,6 +584,7 @@ scan_allocbt( const struct xfs_buf_ops *ops) { struct aghdr_cnts *agcnts = priv; + struct xfs_perag *pag; const char *name; int i; xfs_alloc_ptr_t *pp; @@ -670,6 +671,8 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), } rp = XFS_ALLOC_REC_ADDR(mp, block, 1); + pag = libxfs_perag_get(mp, agno); + for (i = 0; i < numrecs; i++) { xfs_agblock_t b, end; xfs_extlen_t len, blen; @@ -678,14 +681,14 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), len = be32_to_cpu(rp[i].ar_blockcount); end = b + len; - if (!libxfs_verify_agbno(mp, agno, b)) { + if (!libxfs_verify_agbno(pag, b)) { do_warn( _("invalid start block %u in record %u of %s btree block %u/%u\n"), b, i, name, agno, bno); continue; } if (len == 0 || end <= b || - !libxfs_verify_agbno(mp, agno, end - 1)) { + !libxfs_verify_agbno(pag, end - 1)) { do_warn( _("invalid length %u in record %u of %s btree block %u/%u\n"), len, i, name, agno, bno); @@ -742,6 +745,7 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), } } } + libxfs_perag_put(pag); return; } @@ -776,14 +780,16 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), suspect = 0; } + pag = libxfs_perag_get(mp, agno); for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); - if (!libxfs_verify_agbno(mp, agno, agbno)) { + if (!libxfs_verify_agbno(pag, agbno)) { do_warn( _("bad btree pointer (%u) in %sbt block %u/%u\n"), agbno, name, agno, bno); suspect++; + libxfs_perag_put(pag); return; } @@ -799,6 +805,7 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), scan_sbtree(agbno, level, agno, suspect, scan_allocbt, 0, magic, priv, ops); } + libxfs_perag_put(pag); } static bool @@ -986,6 +993,7 @@ scan_rmapbt( uint64_t lastoffset = 0; struct xfs_rmap_key *kp; struct xfs_rmap_irec key = {0}; + struct xfs_perag *pag; if (magic != XFS_RMAP_CRC_MAGIC) { name = "(unknown)"; @@ -1223,6 +1231,7 @@ advance: i, agno, bno, name); } + pag = libxfs_perag_get(mp, agno); for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); @@ -1250,17 +1259,19 @@ advance: continue; } - if (!libxfs_verify_agbno(mp, agno, agbno)) { + if (!libxfs_verify_agbno(pag, agbno)) { do_warn( _("bad btree pointer (%u) in %sbt block %u/%u\n"), agbno, name, agno, bno); suspect++; + libxfs_perag_put(pag); return; } scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, magic, priv, ops); } + libxfs_perag_put(pag); out: if (suspect) @@ -1294,6 +1305,7 @@ scan_refcbt( int state; xfs_agblock_t lastblock = 0; struct refc_priv *refc_priv = priv; + struct xfs_perag *pag; if (magic != XFS_REFC_CRC_MAGIC) { name = "(unknown)"; @@ -1352,6 +1364,8 @@ _("%s btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), } rp = XFS_REFCOUNT_REC_ADDR(block, 1); + pag = libxfs_perag_get(mp, agno); + for (i = 0; i < numrecs; i++) { xfs_agblock_t b, agb, end; xfs_extlen_t len; @@ -1373,14 +1387,14 @@ _("leftover CoW extent has invalid startblock in record %u of %s btree block %u/ } end = agb + len; - if (!libxfs_verify_agbno(mp, agno, agb)) { + if (!libxfs_verify_agbno(pag, agb)) { do_warn( _("invalid start block %u in record %u of %s btree block %u/%u\n"), b, i, name, agno, bno); continue; } if (len == 0 || end <= agb || - !libxfs_verify_agbno(mp, agno, end - 1)) { + !libxfs_verify_agbno(pag, end - 1)) { do_warn( _("invalid length %u in record %u of %s btree block %u/%u\n"), len, i, name, agno, bno); @@ -1439,6 +1453,7 @@ _("extent (%u/%u) len %u claimed, state is %d\n"), /* XXX: probably want to mark the reflinked areas? */ } + libxfs_perag_put(pag); goto out; } @@ -1473,20 +1488,23 @@ _("extent (%u/%u) len %u claimed, state is %d\n"), suspect = 0; } + pag = libxfs_perag_get(mp, agno); for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); - if (!libxfs_verify_agbno(mp, agno, agbno)) { + if (!libxfs_verify_agbno(pag, agbno)) { do_warn( _("bad btree pointer (%u) in %sbt block %u/%u\n"), agbno, name, agno, bno); suspect++; + libxfs_perag_put(pag); return; } scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, magic, priv, ops); } + libxfs_perag_put(pag); out: if (suspect) refcount_avoid_check(); @@ -1994,6 +2012,7 @@ scan_inobt( int hdr_errors; int freecount; struct xfs_ino_geometry *igeo = M_IGEO(mp); + struct xfs_perag *pag; hdr_errors = 0; @@ -2161,20 +2180,23 @@ _("%sbt btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), else suspect++; } + pag = libxfs_perag_get(mp, agno); for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); - if (!libxfs_verify_agbno(mp, agno, agbno)) { + if (!libxfs_verify_agbno(pag, agbno)) { do_warn( _("bad btree pointer (%u) in %sbt block %u/%u\n"), agbno, name, agno, bno); suspect++; + libxfs_perag_put(pag); return; } scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect, scan_inobt, 0, magic, priv, ops); } + libxfs_perag_put(pag); } struct agfl_state { @@ -2189,12 +2211,16 @@ scan_agfl( void *priv) { struct agfl_state *as = priv; + struct xfs_perag *pag; - if (libxfs_verify_agbno(mp, as->agno, bno)) + pag = libxfs_perag_get(mp, as->agno); + if (libxfs_verify_agbno(pag, bno)) set_bmap(as->agno, bno, XR_E_FREE); else do_warn(_("bad agbno %u in agfl, agno %d\n"), bno, as->agno); + + libxfs_perag_put(pag); as->count++; return 0; } @@ -2262,6 +2288,7 @@ validate_agf( xfs_agblock_t bno; uint32_t magic; unsigned int levels; + struct xfs_perag *pag = libxfs_perag_get(mp, agno); levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); if (levels == 0 || levels > mp->m_alloc_maxlevels) { @@ -2270,7 +2297,7 @@ validate_agf( } bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { magic = xfs_has_crc(mp) ? XFS_ABTB_CRC_MAGIC : XFS_ABTB_MAGIC; scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), @@ -2288,7 +2315,7 @@ validate_agf( } bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { magic = xfs_has_crc(mp) ? XFS_ABTC_CRC_MAGIC : XFS_ABTC_MAGIC; scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), @@ -2316,7 +2343,7 @@ validate_agf( } bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { scan_sbtree(bno, levels, agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC, &priv, &xfs_rmapbt_buf_ops); @@ -2340,7 +2367,7 @@ validate_agf( } bno = be32_to_cpu(agf->agf_refcount_root); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { struct refc_priv priv; memset(&priv, 0, sizeof(priv)); @@ -2373,6 +2400,7 @@ validate_agf( do_warn(_("agf_btreeblks %u, counted %" PRIu64 " in ag %u\n"), be32_to_cpu(agf->agf_btreeblks), agcnts->agfbtreeblks, agno); } + libxfs_perag_put(pag); } @@ -2389,6 +2417,7 @@ validate_agi( int i; uint32_t magic; unsigned int levels; + struct xfs_perag *pag = libxfs_perag_get(mp, agno); levels = be32_to_cpu(agi->agi_level); if (levels == 0 || levels > M_IGEO(mp)->inobt_maxlevels) { @@ -2397,7 +2426,7 @@ validate_agi( } bno = be32_to_cpu(agi->agi_root); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { magic = xfs_has_crc(mp) ? XFS_IBT_CRC_MAGIC : XFS_IBT_MAGIC; scan_sbtree(bno, be32_to_cpu(agi->agi_level), @@ -2416,7 +2445,7 @@ validate_agi( } bno = be32_to_cpu(agi->agi_free_root); - if (libxfs_verify_agbno(mp, agno, bno)) { + if (libxfs_verify_agbno(pag, bno)) { magic = xfs_has_crc(mp) ? XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC; scan_sbtree(bno, be32_to_cpu(agi->agi_free_level), @@ -2466,6 +2495,7 @@ validate_agi( XFS_AGINO_TO_INO(mp, agno, agino)); } } + libxfs_perag_put(pag); } /*