]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libxfs: port userspace deferred log item to handle rtgroups
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:24:32 +0000 (16:24 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:32 +0000 (18:01 -0800)
Make the userspace log items to handle rt groups correctly.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/defer_item.c

index eee84ffbe625d5d4ca96f4ded57a574bfd6cf3fc..9db0e471cba69c46bd1854955605bb4cefcd94f0 100644 (file)
@@ -77,6 +77,17 @@ xfs_extent_free_create_done(
        return NULL;
 }
 
+static inline const struct xfs_defer_op_type *
+xefi_ops(
+       struct xfs_extent_free_item     *xefi)
+{
+       if (xfs_efi_is_realtime(xefi))
+               return &xfs_rtextent_free_defer_type;
+       if (xefi->xefi_agresv == XFS_AG_RESV_AGFL)
+               return &xfs_agfl_free_defer_type;
+       return &xfs_extent_free_defer_type;
+}
+
 /* Add this deferred EFI to the transaction. */
 void
 xfs_extent_free_defer_add(
@@ -86,14 +97,11 @@ xfs_extent_free_defer_add(
 {
        struct xfs_mount                *mp = tp->t_mountp;
 
+       trace_xfs_extent_free_defer(mp, xefi);
+
        xefi->xefi_group = xfs_group_intent_get(mp, xefi->xefi_startblock,
-                       XG_TYPE_AG);
-       if (xefi->xefi_agresv == XFS_AG_RESV_AGFL)
-               *dfpp = xfs_defer_add(tp, &xefi->xefi_list,
-                               &xfs_agfl_free_defer_type);
-       else
-               *dfpp = xfs_defer_add(tp, &xefi->xefi_list,
-                               &xfs_extent_free_defer_type);
+                       xfs_efi_is_realtime(xefi) ? XG_TYPE_RTG : XG_TYPE_AG);
+       *dfpp = xfs_defer_add(tp, &xefi->xefi_list, xefi_ops(xefi));
 }
 
 /* Cancel a free extent. */
@@ -159,6 +167,32 @@ const struct xfs_defer_op_type xfs_extent_free_defer_type = {
        .cancel_item    = xfs_extent_free_cancel_item,
 };
 
+STATIC int
+xfs_rtextent_free_finish_item(
+       struct xfs_trans                *tp,
+       struct xfs_log_item             *done,
+       struct list_head                *item,
+       struct xfs_btree_cur            **state)
+{
+       struct xfs_extent_free_item     *xefi = xefi_entry(item);
+       int                             error;
+
+       error = xfs_rtfree_blocks(tp, to_rtg(xefi->xefi_group),
+                       xefi->xefi_startblock, xefi->xefi_blockcount);
+       if (error != -EAGAIN)
+               xfs_extent_free_cancel_item(item);
+       return error;
+}
+
+const struct xfs_defer_op_type xfs_rtextent_free_defer_type = {
+       .name           = "rtextent_free",
+       .create_intent  = xfs_extent_free_create_intent,
+       .abort_intent   = xfs_extent_free_abort_intent,
+       .create_done    = xfs_extent_free_create_done,
+       .finish_item    = xfs_rtextent_free_finish_item,
+       .cancel_item    = xfs_extent_free_cancel_item,
+};
+
 /*
  * AGFL blocks are accounted differently in the reserve pools and are not
  * inserted into the busy extent list.
@@ -496,14 +530,16 @@ xfs_bmap_update_create_done(
        return NULL;
 }
 
-/* Take an active ref to the AG containing the space we're mapping. */
+/* Take a passive ref to the group containing the space we're mapping. */
 static inline void
 xfs_bmap_update_get_group(
        struct xfs_mount        *mp,
        struct xfs_bmap_intent  *bi)
 {
+       enum xfs_group_type     type = XG_TYPE_AG;
+
        if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork))
-               return;
+               type = XG_TYPE_RTG;
 
        /*
         * Bump the intent count on behalf of the deferred rmap and refcount
@@ -513,7 +549,7 @@ xfs_bmap_update_get_group(
         * remains nonzero across the transaction roll.
         */
        bi->bi_group = xfs_group_intent_get(mp, bi->bi_bmap.br_startblock,
-                       XG_TYPE_AG);
+                               type);
 }
 
 /* Add this deferred BUI to the transaction. */
@@ -522,8 +558,6 @@ xfs_bmap_defer_add(
        struct xfs_trans        *tp,
        struct xfs_bmap_intent  *bi)
 {
-       trace_xfs_bmap_defer(bi);
-
        xfs_bmap_update_get_group(tp->t_mountp, bi);
 
        /*
@@ -536,18 +570,9 @@ xfs_bmap_defer_add(
         */
        if (bi->bi_type == XFS_BMAP_MAP)
                bi->bi_owner->i_delayed_blks += bi->bi_bmap.br_blockcount;
-       xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
-}
 
-/* Release an active AG ref after finishing mapping work. */
-static inline void
-xfs_bmap_update_put_group(
-       struct xfs_bmap_intent  *bi)
-{
-       if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork))
-               return;
-
-       xfs_group_intent_put(bi->bi_group);
+       trace_xfs_bmap_defer(bi);
+       xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
 }
 
 /* Cancel a deferred bmap update. */
@@ -560,7 +585,7 @@ xfs_bmap_update_cancel_item(
        if (bi->bi_type == XFS_BMAP_MAP)
                bi->bi_owner->i_delayed_blks -= bi->bi_bmap.br_blockcount;
 
-       xfs_bmap_update_put_group(bi);
+       xfs_group_intent_put(bi->bi_group);
        kmem_cache_free(xfs_bmap_intent_cache, bi);
 }