xfs: use active perag references for inode allocation
authorDave Chinner <dchinner@redhat.com>
Sun, 12 Feb 2023 22:14:52 +0000 (09:14 +1100)
committerDave Chinner <dchinner@redhat.com>
Sun, 12 Feb 2023 22:14:52 +0000 (09:14 +1100)
Convert the inode allocation routines to use active perag references
or references held by callers rather than grab their own. Also drive
the perag further inwards to replace xfs_mounts when doing
operations on a specific AG.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_ialloc.h

index 7cff618..a3bdcde 100644 (file)
@@ -925,8 +925,7 @@ xfs_ag_shrink_space(
         * Make sure that the last inode cluster cannot overlap with the new
         * end of the AG, even if it's sparse.
         */
-       error = xfs_ialloc_check_shrink(*tpp, pag->pag_agno, agibp,
-                       aglen - delta);
+       error = xfs_ialloc_check_shrink(pag, *tpp, agibp, aglen - delta);
        if (error)
                return error;
 
index f120a48..53d6b77 100644 (file)
@@ -169,14 +169,14 @@ xfs_inobt_insert_rec(
  */
 STATIC int
 xfs_inobt_insert(
-       struct xfs_mount        *mp,
+       struct xfs_perag        *pag,
        struct xfs_trans        *tp,
        struct xfs_buf          *agbp,
-       struct xfs_perag        *pag,
        xfs_agino_t             newino,
        xfs_agino_t             newlen,
        xfs_btnum_t             btnum)
 {
+       struct xfs_mount        *mp = pag->pag_mount;
        struct xfs_btree_cur    *cur;
        xfs_agino_t             thisino;
        int                     i;
@@ -514,14 +514,14 @@ __xfs_inobt_rec_merge(
  */
 STATIC int
 xfs_inobt_insert_sprec(
-       struct xfs_mount                *mp,
+       struct xfs_perag                *pag,
        struct xfs_trans                *tp,
        struct xfs_buf                  *agbp,
-       struct xfs_perag                *pag,
        int                             btnum,
        struct xfs_inobt_rec_incore     *nrec,  /* in/out: new/merged rec. */
        bool                            merge)  /* merge or replace */
 {
+       struct xfs_mount                *mp = pag->pag_mount;
        struct xfs_btree_cur            *cur;
        int                             error;
        int                             i;
@@ -609,9 +609,9 @@ error:
  */
 STATIC int
 xfs_ialloc_ag_alloc(
+       struct xfs_perag        *pag,
        struct xfs_trans        *tp,
-       struct xfs_buf          *agbp,
-       struct xfs_perag        *pag)
+       struct xfs_buf          *agbp)
 {
        struct xfs_agi          *agi;
        struct xfs_alloc_arg    args;
@@ -831,7 +831,7 @@ sparse_alloc:
                 * if necessary. If a merge does occur, rec is updated to the
                 * merged record.
                 */
-               error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag,
+               error = xfs_inobt_insert_sprec(pag, tp, agbp,
                                XFS_BTNUM_INO, &rec, true);
                if (error == -EFSCORRUPTED) {
                        xfs_alert(args.mp,
@@ -856,20 +856,20 @@ sparse_alloc:
                 * existing record with this one.
                 */
                if (xfs_has_finobt(args.mp)) {
-                       error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag,
+                       error = xfs_inobt_insert_sprec(pag, tp, agbp,
                                       XFS_BTNUM_FINO, &rec, false);
                        if (error)
                                return error;
                }
        } else {
                /* full chunk - insert new records to both btrees */
-               error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, newlen,
+               error = xfs_inobt_insert(pag, tp, agbp, newino, newlen,
                                         XFS_BTNUM_INO);
                if (error)
                        return error;
 
                if (xfs_has_finobt(args.mp)) {
-                       error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino,
+                       error = xfs_inobt_insert(pag, tp, agbp, newino,
                                                 newlen, XFS_BTNUM_FINO);
                        if (error)
                                return error;
@@ -981,9 +981,9 @@ xfs_inobt_first_free_inode(
  */
 STATIC int
 xfs_dialloc_ag_inobt(
+       struct xfs_perag        *pag,
        struct xfs_trans        *tp,
        struct xfs_buf          *agbp,
-       struct xfs_perag        *pag,
        xfs_ino_t               parent,
        xfs_ino_t               *inop)
 {
@@ -1429,9 +1429,9 @@ xfs_dialloc_ag_update_inobt(
  */
 static int
 xfs_dialloc_ag(
+       struct xfs_perag        *pag,
        struct xfs_trans        *tp,
        struct xfs_buf          *agbp,
-       struct xfs_perag        *pag,
        xfs_ino_t               parent,
        xfs_ino_t               *inop)
 {
@@ -1448,7 +1448,7 @@ xfs_dialloc_ag(
        int                             i;
 
        if (!xfs_has_finobt(mp))
-               return xfs_dialloc_ag_inobt(tp, agbp, pag, parent, inop);
+               return xfs_dialloc_ag_inobt(pag, tp, agbp, parent, inop);
 
        /*
         * If pagino is 0 (this is the root inode allocation) use newino.
@@ -1594,8 +1594,8 @@ xfs_ialloc_next_ag(
 
 static bool
 xfs_dialloc_good_ag(
-       struct xfs_trans        *tp,
        struct xfs_perag        *pag,
+       struct xfs_trans        *tp,
        umode_t                 mode,
        int                     flags,
        bool                    ok_alloc)
@@ -1606,6 +1606,8 @@ xfs_dialloc_good_ag(
        int                     needspace;
        int                     error;
 
+       if (!pag)
+               return false;
        if (!pag->pagi_inodeok)
                return false;
 
@@ -1665,8 +1667,8 @@ xfs_dialloc_good_ag(
 
 static int
 xfs_dialloc_try_ag(
-       struct xfs_trans        **tpp,
        struct xfs_perag        *pag,
+       struct xfs_trans        **tpp,
        xfs_ino_t               parent,
        xfs_ino_t               *new_ino,
        bool                    ok_alloc)
@@ -1689,7 +1691,7 @@ xfs_dialloc_try_ag(
                        goto out_release;
                }
 
-               error = xfs_ialloc_ag_alloc(*tpp, agbp, pag);
+               error = xfs_ialloc_ag_alloc(pag, *tpp, agbp);
                if (error < 0)
                        goto out_release;
 
@@ -1705,7 +1707,7 @@ xfs_dialloc_try_ag(
        }
 
        /* Allocate an inode in the found AG */
-       error = xfs_dialloc_ag(*tpp, agbp, pag, parent, &ino);
+       error = xfs_dialloc_ag(pag, *tpp, agbp, parent, &ino);
        if (!error)
                *new_ino = ino;
        return error;
@@ -1790,9 +1792,9 @@ xfs_dialloc(
        agno = start_agno;
        flags = XFS_ALLOC_FLAG_TRYLOCK;
        for (;;) {
-               pag = xfs_perag_get(mp, agno);
-               if (xfs_dialloc_good_ag(*tpp, pag, mode, flags, ok_alloc)) {
-                       error = xfs_dialloc_try_ag(tpp, pag, parent,
+               pag = xfs_perag_grab(mp, agno);
+               if (xfs_dialloc_good_ag(pag, *tpp, mode, flags, ok_alloc)) {
+                       error = xfs_dialloc_try_ag(pag, tpp, parent,
                                        &ino, ok_alloc);
                        if (error != -EAGAIN)
                                break;
@@ -1813,12 +1815,12 @@ xfs_dialloc(
                        if (low_space)
                                ok_alloc = true;
                }
-               xfs_perag_put(pag);
+               xfs_perag_rele(pag);
        }
 
        if (!error)
                *new_ino = ino;
-       xfs_perag_put(pag);
+       xfs_perag_rele(pag);
        return error;
 }
 
@@ -1902,14 +1904,14 @@ next:
 
 STATIC int
 xfs_difree_inobt(
-       struct xfs_mount                *mp,
+       struct xfs_perag                *pag,
        struct xfs_trans                *tp,
        struct xfs_buf                  *agbp,
-       struct xfs_perag                *pag,
        xfs_agino_t                     agino,
        struct xfs_icluster             *xic,
        struct xfs_inobt_rec_incore     *orec)
 {
+       struct xfs_mount                *mp = pag->pag_mount;
        struct xfs_agi                  *agi = agbp->b_addr;
        struct xfs_btree_cur            *cur;
        struct xfs_inobt_rec_incore     rec;
@@ -2036,13 +2038,13 @@ error0:
  */
 STATIC int
 xfs_difree_finobt(
-       struct xfs_mount                *mp,
+       struct xfs_perag                *pag,
        struct xfs_trans                *tp,
        struct xfs_buf                  *agbp,
-       struct xfs_perag                *pag,
        xfs_agino_t                     agino,
        struct xfs_inobt_rec_incore     *ibtrec) /* inobt record */
 {
+       struct xfs_mount                *mp = pag->pag_mount;
        struct xfs_btree_cur            *cur;
        struct xfs_inobt_rec_incore     rec;
        int                             offset = agino - ibtrec->ir_startino;
@@ -2196,7 +2198,7 @@ xfs_difree(
        /*
         * Fix up the inode allocation btree.
         */
-       error = xfs_difree_inobt(mp, tp, agbp, pag, agino, xic, &rec);
+       error = xfs_difree_inobt(pag, tp, agbp, agino, xic, &rec);
        if (error)
                goto error0;
 
@@ -2204,7 +2206,7 @@ xfs_difree(
         * Fix up the free inode btree.
         */
        if (xfs_has_finobt(mp)) {
-               error = xfs_difree_finobt(mp, tp, agbp, pag, agino, &rec);
+               error = xfs_difree_finobt(pag, tp, agbp, agino, &rec);
                if (error)
                        goto error0;
        }
@@ -2928,15 +2930,14 @@ xfs_ialloc_calc_rootino(
  */
 int
 xfs_ialloc_check_shrink(
+       struct xfs_perag        *pag,
        struct xfs_trans        *tp,
-       xfs_agnumber_t          agno,
        struct xfs_buf          *agibp,
        xfs_agblock_t           new_length)
 {
        struct xfs_inobt_rec_incore rec;
        struct xfs_btree_cur    *cur;
        struct xfs_mount        *mp = tp->t_mountp;
-       struct xfs_perag        *pag;
        xfs_agino_t             agino = XFS_AGB_TO_AGINO(mp, new_length);
        int                     has;
        int                     error;
@@ -2944,7 +2945,6 @@ xfs_ialloc_check_shrink(
        if (!xfs_has_sparseinodes(mp))
                return 0;
 
-       pag = xfs_perag_get(mp, agno);
        cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO);
 
        /* Look up the inobt record that would correspond to the new EOFS. */
@@ -2968,6 +2968,5 @@ xfs_ialloc_check_shrink(
        }
 out:
        xfs_btree_del_cursor(cur, error);
-       xfs_perag_put(pag);
        return error;
 }
index 4cfce2e..ab8c30b 100644 (file)
@@ -107,7 +107,7 @@ int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
 void xfs_ialloc_setup_geometry(struct xfs_mount *mp);
 xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit);
 
-int xfs_ialloc_check_shrink(struct xfs_trans *tp, xfs_agnumber_t agno,
+int xfs_ialloc_check_shrink(struct xfs_perag *pag, struct xfs_trans *tp,
                struct xfs_buf *agibp, xfs_agblock_t new_length);
 
 #endif /* __XFS_IALLOC_H__ */