]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: give xfs_rmap_intent its own perag reference
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 May 2023 08:49:36 +0000 (10:49 +0200)
committerCarlos Maiolino <cem@kernel.org>
Fri, 9 Jun 2023 08:27:50 +0000 (10:27 +0200)
Source kernel commit: c13418e8eb375872ad297aeec5fa26277febc155

Give the xfs_rmap_intent a passive reference to the perag structure
data.  This reference will be used to enable scrub intent draining
functionality in subsequent patches.  The space we're (reverse) mapping
is already allocated, so we need to be able to operate even if the AG is
being shrunk or offlined.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
libxfs/defer_item.c
libxfs/xfs_rmap.c
libxfs/xfs_rmap.h

index ed6edd982f076911bbfb5d2713a8dec7cab7854b..8c511eb4eeccda0d1bc834457e7d74cab7de4ded 100644 (file)
@@ -198,14 +198,13 @@ xfs_rmap_update_diff_items(
        struct list_head                *a,
        struct list_head                *b)
 {
-       struct xfs_mount                *mp = priv;
        struct xfs_rmap_intent          *ra;
        struct xfs_rmap_intent          *rb;
 
        ra = container_of(a, struct xfs_rmap_intent, ri_list);
        rb = container_of(b, struct xfs_rmap_intent, ri_list);
-       return  XFS_FSB_TO_AGNO(mp, ra->ri_bmap.br_startblock) -
-               XFS_FSB_TO_AGNO(mp, rb->ri_bmap.br_startblock);
+
+       return ra->ri_pag->pag_agno - rb->ri_pag->pag_agno;
 }
 
 /* Get an RUI. */
@@ -233,6 +232,26 @@ xfs_rmap_update_create_done(
        return NULL;
 }
 
+/* Take a passive ref to the AG containing the space we're rmapping. */
+void
+xfs_rmap_update_get_group(
+       struct xfs_mount        *mp,
+       struct xfs_rmap_intent  *ri)
+{
+       xfs_agnumber_t  agno;
+
+       agno = XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock);
+       ri->ri_pag = xfs_perag_get(mp, agno);
+}
+
+/* Release a passive AG ref after finishing rmapping work. */
+static inline void
+xfs_rmap_update_put_group(
+       struct xfs_rmap_intent  *ri)
+{
+       xfs_perag_put(ri->ri_pag);
+}
+
 /* Process a deferred rmap update. */
 STATIC int
 xfs_rmap_update_finish_item(
@@ -245,7 +264,10 @@ xfs_rmap_update_finish_item(
        int                             error;
 
        ri = container_of(item, struct xfs_rmap_intent, ri_list);
+
        error = xfs_rmap_finish_one(tp, ri, state);
+
+       xfs_rmap_update_put_group(ri);
        kmem_cache_free(xfs_rmap_intent_cache, ri);
        return error;
 }
@@ -265,6 +287,8 @@ xfs_rmap_update_cancel_item(
        struct xfs_rmap_intent          *ri;
 
        ri = container_of(item, struct xfs_rmap_intent, ri_list);
+
+       xfs_rmap_update_put_group(ri);
        kmem_cache_free(xfs_rmap_intent_cache, ri);
 }
 
index 2f21b744dccc106a379f29d465283ec6d4e99c76..a235fc75394cc9f2538771144e22837229c859fb 100644 (file)
@@ -2393,7 +2393,6 @@ xfs_rmap_finish_one(
        struct xfs_btree_cur            **pcur)
 {
        struct xfs_mount                *mp = tp->t_mountp;
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *rcur;
        struct xfs_buf                  *agbp = NULL;
        int                             error = 0;
@@ -2401,26 +2400,22 @@ xfs_rmap_finish_one(
        xfs_agblock_t                   bno;
        bool                            unwritten;
 
-       pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock));
        bno = XFS_FSB_TO_AGBNO(mp, ri->ri_bmap.br_startblock);
 
-       trace_xfs_rmap_deferred(mp, pag->pag_agno, ri->ri_type, bno,
+       trace_xfs_rmap_deferred(mp, ri->ri_pag->pag_agno, ri->ri_type, bno,
                        ri->ri_owner, ri->ri_whichfork,
                        ri->ri_bmap.br_startoff, ri->ri_bmap.br_blockcount,
                        ri->ri_bmap.br_state);
 
-       if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE)) {
-               error = -EIO;
-               goto out_drop;
-       }
-
+       if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE))
+               return -EIO;
 
        /*
         * If we haven't gotten a cursor or the cursor AG doesn't match
         * the startblock, get one now.
         */
        rcur = *pcur;
-       if (rcur != NULL && rcur->bc_ag.pag != pag) {
+       if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
                xfs_rmap_finish_one_cleanup(tp, rcur, 0);
                rcur = NULL;
                *pcur = NULL;
@@ -2431,15 +2426,13 @@ xfs_rmap_finish_one(
                 * rmapbt, because a shape change could cause us to
                 * allocate blocks.
                 */
-               error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
+               error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
                if (error)
-                       goto out_drop;
-               if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
-                       error = -EFSCORRUPTED;
-                       goto out_drop;
-               }
+                       return error;
+               if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
+                       return -EFSCORRUPTED;
 
-               rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
+               rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
        }
        *pcur = rcur;
 
@@ -2479,8 +2472,7 @@ xfs_rmap_finish_one(
                ASSERT(0);
                error = -EFSCORRUPTED;
        }
-out_drop:
-       xfs_perag_put(pag);
+
        return error;
 }
 
@@ -2525,6 +2517,7 @@ __xfs_rmap_add(
        ri->ri_whichfork = whichfork;
        ri->ri_bmap = *bmap;
 
+       xfs_rmap_update_get_group(tp->t_mountp, ri);
        xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
 }
 
index 2dac88cea28dc4688ee76e1b47c8023db66be508..1472ae570a8a631def322303aab58b2fff973da7 100644 (file)
@@ -162,8 +162,12 @@ struct xfs_rmap_intent {
        int                                     ri_whichfork;
        uint64_t                                ri_owner;
        struct xfs_bmbt_irec                    ri_bmap;
+       struct xfs_perag                        *ri_pag;
 };
 
+void xfs_rmap_update_get_group(struct xfs_mount *mp,
+               struct xfs_rmap_intent *ri);
+
 /* functions for updating the rmapbt based on bmbt map/unmap operations */
 void xfs_rmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
                int whichfork, struct xfs_bmbt_irec *imap);