xfs: pass perag to xfs_alloc_read_agf()
authorDave Chinner <dchinner@redhat.com>
Thu, 7 Jul 2022 09:07:40 +0000 (19:07 +1000)
committerDave Chinner <david@fromorbit.com>
Thu, 7 Jul 2022 09:07:40 +0000 (19:07 +1000)
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.

Whilst modifying the xfs_reflink_find_shared() function definition,
declare it static and remove the extern declaration as it is an
internal function only these days.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
20 files changed:
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag_resv.c
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.h
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/libxfs/xfs_refcount_btree.c
fs/xfs/libxfs/xfs_rmap_btree.c
fs/xfs/scrub/agheader_repair.c
fs/xfs/scrub/bmap.c
fs/xfs/scrub/common.c
fs/xfs/scrub/fscounters.c
fs/xfs/scrub/repair.c
fs/xfs/xfs_discard.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_filestream.c
fs/xfs/xfs_fsmap.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_reflink.h

index 2ed1583..1fa1725 100644 (file)
@@ -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;
@@ -792,7 +789,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,8 +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;
 
index ce28bf8..5af123d 100644 (file)
@@ -322,7 +322,7 @@ out:
         * 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;
 
index f7853ab..6912c4e 100644 (file)
@@ -2609,7 +2609,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)
@@ -2639,7 +2639,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)
@@ -3080,34 +3080,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);
@@ -3121,7 +3117,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
@@ -3131,13 +3127,14 @@ 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));
index 96d5301..b8cf5be 100644 (file)
@@ -135,17 +135,6 @@ xfs_alloc_put_freelist(
        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).
  */
 int                            /* error */
@@ -198,6 +187,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,
index a76d589..88828fc 100644 (file)
@@ -3185,7 +3185,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. */
index 8e25220..dfa8061 100644 (file)
@@ -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;
        }
index 97e9e60..098dac8 100644 (file)
@@ -1177,8 +1177,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;
 
@@ -1710,7 +1710,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);
index d14c172..1063234 100644 (file)
@@ -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;
 
index 69e104d..d6d4599 100644 (file)
@@ -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;
 
index 6da7f2c..230bdfe 100644 (file)
@@ -666,8 +666,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;
 
@@ -742,8 +741,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;
 
index 285995b..9353fd0 100644 (file)
@@ -540,7 +540,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;
 
index 6299779..cd7d4eb 100644 (file)
@@ -420,7 +420,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;
 
index bd06a18..6a6f8fe 100644 (file)
@@ -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;
 
index 14acf1d..1c66f7e 100644 (file)
@@ -207,7 +207,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;
@@ -543,6 +543,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
@@ -550,7 +551,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 {
index c6fe3f6..bfc829c 100644 (file)
@@ -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;
index 765be05..0d0a0b3 100644 (file)
@@ -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"
@@ -551,6 +552,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);
@@ -560,9 +562,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
index 6b09a30..34b21a2 100644 (file)
@@ -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) {
                                if (err != -EAGAIN) {
                                        xfs_perag_put(pag);
index bb23199..d833727 100644 (file)
@@ -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;
 
index e7a7c00..81994f4 100644 (file)
  * shared blocks.  If there are no shared extents, fbno and flen will
  * be set to NULLAGBLOCK and 0, respectively.
  */
-int
+static 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;
 
@@ -1420,11 +1421,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;
@@ -1437,17 +1433,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;
index bea65f2..65c5dfe 100644 (file)
@@ -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,