xfs: inode allocation can use a single perag instance
authorDave Chinner <dchinner@redhat.com>
Wed, 2 Jun 2021 00:48:24 +0000 (10:48 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 2 Jun 2021 00:48:24 +0000 (10:48 +1000)
Now that we've internalised the two-phase inode allocation, we can
now easily make the AG selection and allocation atomic from the
perspective of a single perag context. This will ensure AGs going
offline/away cannot occur between the selection and allocation
steps.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_ialloc.c

index 4a04ca79ba3321883ea28c2a6b26fdb054136a44..a5604df959cf9da5314f62095ad14984597b5eb5 100644 (file)
@@ -1432,6 +1432,7 @@ static int
 xfs_dialloc_ag(
        struct xfs_trans        *tp,
        struct xfs_buf          *agbp,
+       struct xfs_perag        *pag,
        xfs_ino_t               parent,
        xfs_ino_t               *inop)
 {
@@ -1446,7 +1447,6 @@ xfs_dialloc_ag(
        int                             error;
        int                             offset;
        int                             i;
-       struct xfs_perag                *pag = agbp->b_pag;
 
        if (!xfs_sb_version_hasfinobt(&mp->m_sb))
                return xfs_dialloc_ag_inobt(tp, agbp, pag, parent, inop);
@@ -1763,9 +1763,9 @@ nextag:
        xfs_perag_put(pag);
        return error ? error : -ENOSPC;
 found_ag:
-       xfs_perag_put(pag);
        /* Allocate an inode in the found AG */
-       error = xfs_dialloc_ag(*tpp, agbp, parent, &ino);
+       error = xfs_dialloc_ag(*tpp, agbp, pag, parent, &ino);
+       xfs_perag_put(pag);
        if (error)
                return error;
        *new_ino = ino;