error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp);
        if (error)
                goto out_agi;
-       pag = xfs_perag_get(mp, agno);
+
+       pag = agi_bp->b_pag;
 
        /* Fill out form. */
        memset(ageo, 0, sizeof(*ageo));
        xfs_ag_geom_health(pag, ageo);
 
        /* Release resources. */
-       xfs_perag_put(pag);
        xfs_buf_relse(agf_bp);
 out_agi:
        xfs_buf_relse(agi_bp);
 
        xfs_perag_put(pag);
 }
 
-static inline void
-xfs_ag_resv_rmapbt_free(
-       struct xfs_mount        *mp,
-       xfs_agnumber_t          agno)
-{
-       struct xfs_perag        *pag;
-
-       pag = xfs_perag_get(mp, agno);
-       xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
-       xfs_perag_put(pag);
-}
-
 #endif /* __XFS_AG_RESV_H__ */
 
 STATIC int
 xfs_alloc_update_counters(
        struct xfs_trans        *tp,
-       struct xfs_perag        *pag,
        struct xfs_buf          *agbp,
        long                    len)
 {
        struct xfs_agf          *agf = agbp->b_addr;
 
-       pag->pagf_freeblks += len;
+       agbp->b_pag->pagf_freeblks += len;
        be32_add_cpu(&agf->agf_freeblks, len);
 
        xfs_trans_agblocks_delta(tp, len);
        }
 
        if (!args->wasfromfl) {
-               error = xfs_alloc_update_counters(args->tp, args->pag,
-                                                 args->agbp,
+               error = xfs_alloc_update_counters(args->tp, args->agbp,
                                                  -((long)(args->len)));
                if (error)
                        return error;
        enum xfs_ag_resv_type           type)
 {
        struct xfs_mount                *mp;
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *bno_cur;
        struct xfs_btree_cur            *cnt_cur;
        xfs_agblock_t                   gtbno; /* start of right neighbor */
        /*
         * Update the freespace totals in the ag and superblock.
         */
-       pag = xfs_perag_get(mp, agno);
-       error = xfs_alloc_update_counters(tp, pag, agbp, len);
-       xfs_ag_resv_free_extent(pag, type, tp, len);
-       xfs_perag_put(pag);
+       error = xfs_alloc_update_counters(tp, agbp, len);
+       xfs_ag_resv_free_extent(agbp->b_pag, type, tp, len);
        if (error)
                goto error0;
 
        if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp))
                agf->agf_flfirst = 0;
 
-       pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+       pag = agbp->b_pag;
        ASSERT(!pag->pagf_agflreset);
        be32_add_cpu(&agf->agf_flcount, -1);
        xfs_trans_agflist_delta(tp, -1);
                pag->pagf_btreeblks++;
                logflags |= XFS_AGF_BTREEBLKS;
        }
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(tp, agbp, logflags);
        *bnop = bno;
        if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp))
                agf->agf_fllast = 0;
 
-       pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+       pag = agbp->b_pag;
        ASSERT(!pag->pagf_agflreset);
        be32_add_cpu(&agf->agf_flcount, 1);
        xfs_trans_agflist_delta(tp, 1);
                pag->pagf_btreeblks--;
                logflags |= XFS_AGF_BTREEBLKS;
        }
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(tp, agbp, logflags);
 
        ASSERT(!(*bpp)->b_error);
 
        agf = (*bpp)->b_addr;
-       pag = xfs_perag_get(mp, agno);
+       pag = (*bpp)->b_pag;
        if (!pag->pagf_init) {
                pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
                pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
                       be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
        }
 #endif
-       xfs_perag_put(pag);
        return 0;
 }
 
 
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        int                     btnum = cur->bc_btnum;
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_roots[btnum] = ptr->s;
        be32_add_cpu(&agf->agf_levels[btnum], inc);
        pag->pagf_levels[btnum] += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
 }
        int                     reason)
 {
        struct xfs_agf          *agf = cur->bc_ag.agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        struct xfs_perag        *pag;
        __be32                  len;
        int                     numrecs;
        }
 
        agf->agf_longest = len;
-       pag = xfs_perag_get(cur->bc_mp, seqno);
+       pag = cur->bc_ag.agbp->b_pag;
        pag->pagf_longest = be32_to_cpu(len);
-       xfs_perag_put(pag);
        xfs_alloc_log_agf(cur->bc_tp, cur->bc_ag.agbp, XFS_AGF_LONGEST);
 }
 
 
         */
        be32_add_cpu(&agi->agi_count, newlen);
        be32_add_cpu(&agi->agi_freecount, newlen);
-       pag = xfs_perag_get(args.mp, agno);
+       pag = agbp->b_pag;
        pag->pagi_freecount += newlen;
        pag->pagi_count += newlen;
-       xfs_perag_put(pag);
        agi->agi_newino = cpu_to_be32(newino);
 
        /*
        xfs_agnumber_t          agno = be32_to_cpu(agi->agi_seqno);
        xfs_agnumber_t          pagno = XFS_INO_TO_AGNO(mp, parent);
        xfs_agino_t             pagino = XFS_INO_TO_AGINO(mp, parent);
-       struct xfs_perag        *pag;
+       struct xfs_perag        *pag = agbp->b_pag;
        struct xfs_btree_cur    *cur, *tcur;
        struct xfs_inobt_rec_incore rec, trec;
        xfs_ino_t               ino;
        int                     i, j;
        int                     searchdistance = 10;
 
-       pag = xfs_perag_get(mp, agno);
-
        ASSERT(pag->pagi_init);
        ASSERT(pag->pagi_inodeok);
        ASSERT(pag->pagi_freecount > 0);
 
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
        xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
-       xfs_perag_put(pag);
        *inop = ino;
        return 0;
 error1:
        xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
 error0:
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
-       xfs_perag_put(pag);
        return error;
 }
 
        xfs_agnumber_t                  agno = be32_to_cpu(agi->agi_seqno);
        xfs_agnumber_t                  pagno = XFS_INO_TO_AGNO(mp, parent);
        xfs_agino_t                     pagino = XFS_INO_TO_AGINO(mp, parent);
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *cur;   /* finobt cursor */
        struct xfs_btree_cur            *icur;  /* inobt cursor */
        struct xfs_inobt_rec_incore     rec;
        if (!xfs_sb_version_hasfinobt(&mp->m_sb))
                return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
 
-       pag = xfs_perag_get(mp, agno);
-
        /*
         * If pagino is 0 (this is the root inode allocation) use newino.
         * This must work because we've just allocated some.
         */
        be32_add_cpu(&agi->agi_freecount, -1);
        xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
-       pag->pagi_freecount--;
+       agbp->b_pag->pagi_freecount--;
 
        xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
 
 
        xfs_btree_del_cursor(icur, XFS_BTREE_NOERROR);
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
-       xfs_perag_put(pag);
        *inop = ino;
        return 0;
 
        xfs_btree_del_cursor(icur, XFS_BTREE_ERROR);
 error_cur:
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
-       xfs_perag_put(pag);
        return error;
 }
 
 {
        struct xfs_agi                  *agi = agbp->b_addr;
        xfs_agnumber_t                  agno = be32_to_cpu(agi->agi_seqno);
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *cur;
        struct xfs_inobt_rec_incore     rec;
        int                             ilen;
        if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
            rec.ir_free == XFS_INOBT_ALL_FREE &&
            mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
+               struct xfs_perag        *pag = agbp->b_pag;
+
                xic->deleted = true;
                xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
                xic->alloc = xfs_inobt_irec_to_allocmask(&rec);
                be32_add_cpu(&agi->agi_count, -ilen);
                be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
                xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
-               pag = xfs_perag_get(mp, agno);
                pag->pagi_freecount -= ilen - 1;
                pag->pagi_count -= ilen;
-               xfs_perag_put(pag);
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
 
                 */
                be32_add_cpu(&agi->agi_freecount, 1);
                xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
-               pag = xfs_perag_get(mp, agno);
-               pag->pagi_freecount++;
-               xfs_perag_put(pag);
+               agbp->b_pag->pagi_freecount++;
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
        }
 
                return error;
 
        agi = (*bpp)->b_addr;
-       pag = xfs_perag_get(mp, agno);
+       pag = (*bpp)->b_pag;
        if (!pag->pagi_init) {
                pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
                pag->pagi_count = be32_to_cpu(agi->agi_count);
         */
        ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
                XFS_FORCED_SHUTDOWN(mp));
-       xfs_perag_put(pag);
        return 0;
 }
 
 
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_refcount_root = ptr->s;
        be32_add_cpu(&agf->agf_refcount_level, inc);
        pag->pagf_refcount_level += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp,
                        XFS_AGF_REFCOUNT_ROOT | XFS_AGF_REFCOUNT_LEVEL);
 
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        int                     btnum = cur->bc_btnum;
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_roots[btnum] = ptr->s;
        be32_add_cpu(&agf->agf_levels[btnum], inc);
        pag->pagf_levels[btnum] += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
 }
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
+       struct xfs_perag        *pag;
        xfs_agblock_t           bno;
        int                     error;
 
                              XFS_EXTENT_BUSY_SKIP_DISCARD);
        xfs_trans_agbtree_delta(cur->bc_tp, -1);
 
-       xfs_ag_resv_rmapbt_free(cur->bc_mp, cur->bc_ag.agno);
-
+       pag = cur->bc_ag.agbp->b_pag;
+       xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
        return 0;
 }
 
 
        }
 
        if (next_agino != NULLAGINO) {
-               struct xfs_perag        *pag;
                xfs_agino_t             old_agino;
 
                /*
                 * agino has been unlinked, add a backref from the next inode
                 * back to agino.
                 */
-               pag = xfs_perag_get(mp, agno);
-               error = xfs_iunlink_add_backref(pag, agino, next_agino);
-               xfs_perag_put(pag);
+               error = xfs_iunlink_add_backref(agibp->b_pag, agino, next_agino);
                if (error)
                        return error;
        }
        struct xfs_buf          *agibp;
        struct xfs_buf          *last_ibp;
        struct xfs_dinode       *last_dip = NULL;
-       struct xfs_perag        *pag = NULL;
        xfs_agnumber_t          agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
        xfs_agino_t             agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
        xfs_agino_t             next_agino;
         * this inode's backref to point from the next inode.
         */
        if (next_agino != NULLAGINO) {
-               pag = xfs_perag_get(mp, agno);
-               error = xfs_iunlink_change_backref(pag, next_agino,
+               error = xfs_iunlink_change_backref(agibp->b_pag, next_agino,
                                NULLAGINO);
                if (error)
-                       goto out;
+                       return error;
        }
 
-       if (head_agino == agino) {
-               /* Point the head of the list to the next unlinked inode. */
-               error = xfs_iunlink_update_bucket(tp, agno, agibp, bucket_index,
-                               next_agino);
-               if (error)
-                       goto out;
-       } else {
+       if (head_agino != agino) {
                struct xfs_imap imap;
                xfs_agino_t     prev_agino;
 
-               if (!pag)
-                       pag = xfs_perag_get(mp, agno);
-
                /* We need to search the list for the inode being freed. */
                error = xfs_iunlink_map_prev(tp, agno, head_agino, agino,
                                &prev_agino, &imap, &last_dip, &last_ibp,
-                               pag);
+                               agibp->b_pag);
                if (error)
-                       goto out;
+                       return error;
 
                /* Point the previous inode on the list to the next inode. */
                xfs_iunlink_update_dinode(tp, agno, prev_agino, last_ibp,
                 * change_backref takes care of deleting the backref if
                 * next_agino is NULLAGINO.
                 */
-               error = xfs_iunlink_change_backref(pag, agino, next_agino);
-               if (error)
-                       goto out;
+               return xfs_iunlink_change_backref(agibp->b_pag, agino,
+                               next_agino);
        }
 
-out:
-       if (pag)
-               xfs_perag_put(pag);
-       return error;
+       /* Point the head of the list to the next unlinked inode. */
+       return xfs_iunlink_update_bucket(tp, agno, agibp, bucket_index,
+                       next_agino);
 }
 
 /*