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

Give the xfs_extfree_intent an passive reference to the perag structure
data.  This reference will be used to enable scrub intent draining
functionality in subsequent patches.  The space being freed must already
be allocated, so we need to able to run even if the AG is being offlined
or shrunk.

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_alloc.c
libxfs/xfs_alloc.h

index 2ce3b1cc8af7d0de32c766399405c678606634e7..ed6edd982f076911bbfb5d2713a8dec7cab7854b 100644 (file)
@@ -36,14 +36,13 @@ xfs_extent_free_diff_items(
        struct list_head                *a,
        struct list_head                *b)
 {
-       struct xfs_mount                *mp = priv;
        struct xfs_extent_free_item     *ra;
        struct xfs_extent_free_item     *rb;
 
        ra = container_of(a, struct xfs_extent_free_item, xefi_list);
        rb = container_of(b, struct xfs_extent_free_item, xefi_list);
-       return  XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
-               XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
+
+       return ra->xefi_pag->pag_agno - rb->xefi_pag->pag_agno;
 }
 
 /* Get an EFI. */
@@ -71,6 +70,26 @@ xfs_extent_free_create_done(
        return NULL;
 }
 
+/* Take a passive ref to the AG containing the space we're freeing. */
+void
+xfs_extent_free_get_group(
+       struct xfs_mount                *mp,
+       struct xfs_extent_free_item     *xefi)
+{
+       xfs_agnumber_t                  agno;
+
+       agno = XFS_FSB_TO_AGNO(mp, xefi->xefi_startblock);
+       xefi->xefi_pag = xfs_perag_get(mp, agno);
+}
+
+/* Release a passive AG ref after some freeing work. */
+static inline void
+xfs_extent_free_put_group(
+       struct xfs_extent_free_item     *xefi)
+{
+       xfs_perag_put(xefi->xefi_pag);
+}
+
 /* Process a free extent. */
 STATIC int
 xfs_extent_free_finish_item(
@@ -81,8 +100,6 @@ xfs_extent_free_finish_item(
 {
        struct xfs_owner_info           oinfo = { };
        struct xfs_extent_free_item     *xefi;
-       struct xfs_perag                *pag;
-       xfs_agnumber_t                  agno;
        xfs_agblock_t                   agbno;
        int                             error;
 
@@ -93,13 +110,11 @@ xfs_extent_free_finish_item(
        if (xefi->xefi_flags & XFS_EFI_BMBT_BLOCK)
                oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
 
-       agno = XFS_FSB_TO_AGNO(tp->t_mountp, xefi->xefi_startblock);
        agbno = XFS_FSB_TO_AGBNO(tp->t_mountp, xefi->xefi_startblock);
-       pag = xfs_perag_get(tp->t_mountp, agno);
-       error = xfs_free_extent(tp, pag, agbno, xefi->xefi_blockcount, &oinfo,
-                       XFS_AG_RESV_NONE);
-       xfs_perag_put(pag);
+       error = xfs_free_extent(tp, xefi->xefi_pag, agbno,
+                       xefi->xefi_blockcount, &oinfo, XFS_AG_RESV_NONE);
 
+       xfs_extent_free_put_group(xefi);
        kmem_cache_free(xfs_extfree_item_cache, xefi);
        return error;
 }
@@ -119,6 +134,8 @@ xfs_extent_free_cancel_item(
        struct xfs_extent_free_item     *xefi;
 
        xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
+
+       xfs_extent_free_put_group(xefi);
        kmem_cache_free(xfs_extfree_item_cache, xefi);
 }
 
@@ -145,22 +162,20 @@ xfs_agfl_free_finish_item(
        struct xfs_mount                *mp = tp->t_mountp;
        struct xfs_extent_free_item     *xefi;
        struct xfs_buf                  *agbp;
-       struct xfs_perag                *pag;
        int                             error;
-       xfs_agnumber_t                  agno;
        xfs_agblock_t                   agbno;
 
        xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
        ASSERT(xefi->xefi_blockcount == 1);
-       agno = XFS_FSB_TO_AGNO(mp, xefi->xefi_startblock);
        agbno = XFS_FSB_TO_AGBNO(mp, xefi->xefi_startblock);
        oinfo.oi_owner = xefi->xefi_owner;
 
-       pag = libxfs_perag_get(mp, agno);
-       error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
+       error = xfs_alloc_read_agf(xefi->xefi_pag, tp, 0, &agbp);
        if (!error)
-               error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
-       libxfs_perag_put(pag);
+               error = xfs_free_agfl_block(tp, xefi->xefi_pag->pag_agno,
+                               agbno, agbp, &oinfo);
+
+       xfs_extent_free_put_group(xefi);
        kmem_cache_free(xfs_extfree_item_cache, xefi);
        return error;
 }
index e8eaa92ae9a36ba3add7ced4d1360d2aacf32040..8d5d5366e754840c8d1941706b09990b4cc7b82b 100644 (file)
@@ -2401,6 +2401,7 @@ xfs_defer_agfl_block(
 
        trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
 
+       xfs_extent_free_get_group(mp, xefi);
        xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &xefi->xefi_list);
 }
 
@@ -2417,8 +2418,8 @@ __xfs_free_extent_later(
        bool                            skip_discard)
 {
        struct xfs_extent_free_item     *xefi;
-#ifdef DEBUG
        struct xfs_mount                *mp = tp->t_mountp;
+#ifdef DEBUG
        xfs_agnumber_t                  agno;
        xfs_agblock_t                   agbno;
 
@@ -2452,9 +2453,11 @@ __xfs_free_extent_later(
        } else {
                xefi->xefi_owner = XFS_RMAP_OWN_NULL;
        }
-       trace_xfs_bmap_free_defer(tp->t_mountp,
+       trace_xfs_bmap_free_defer(mp,
                        XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
                        XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
+
+       xfs_extent_free_get_group(mp, xefi);
        xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &xefi->xefi_list);
 }
 
index e12d86e3aeeca1f8f87534061e860ed276b9e531..5569cb2ede0d3a08fba06e3b7f30ac6783563416 100644 (file)
@@ -237,9 +237,13 @@ struct xfs_extent_free_item {
        uint64_t                xefi_owner;
        xfs_fsblock_t           xefi_startblock;/* starting fs block number */
        xfs_extlen_t            xefi_blockcount;/* number of blocks in extent */
+       struct xfs_perag        *xefi_pag;
        unsigned int            xefi_flags;
 };
 
+void xfs_extent_free_get_group(struct xfs_mount *mp,
+               struct xfs_extent_free_item *xefi);
+
 #define XFS_EFI_SKIP_DISCARD   (1U << 0) /* don't issue discard */
 #define XFS_EFI_ATTR_FORK      (1U << 1) /* freeing attr fork block */
 #define XFS_EFI_BMBT_BLOCK     (1U << 2) /* freeing bmap btree block */