]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: add a realtime flag to the rmap update log redo items
authorDarrick J. Wong <djwong@kernel.org>
Mon, 23 Sep 2024 20:41:57 +0000 (13:41 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 9 Oct 2024 23:29:17 +0000 (16:29 -0700)
Extend the rmap update (RUI) log items with a new realtime flag that
indicates that the updates apply against the realtime rmapbt.  We'll
wire up the actual rmap code later.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
libxfs/defer_item.c
libxfs/xfs_defer.h
libxfs/xfs_log_format.h
libxfs/xfs_refcount.c
libxfs/xfs_rmap.c
libxfs/xfs_rmap.h

index d2622f4bb7415727367cc91093d272276ebaf12a..e4559edb35381ecb3b3242091f87a09ae722f2d0 100644 (file)
@@ -29,6 +29,7 @@
 #include "xfs_exchmaps.h"
 #include "defer_item.h"
 #include "xfs_group.h"
+#include "xfs_rtgroup.h"
 
 /* Dummy defer item ops, since we don't do logging. */
 
@@ -289,9 +290,18 @@ xfs_rmap_defer_add(
 
        trace_xfs_rmap_defer(mp, ri);
 
+       /*
+        * Deferred rmap updates for the realtime and data sections must use
+        * separate transactions to finish deferred work because updates to
+        * realtime metadata files can lock AGFs to allocate btree blocks and
+        * we don't want that mixing with the AGF locks taken to finish data
+        * section updates.
+        */
        ri->ri_group = xfs_group_intent_get(mp, ri->ri_bmap.br_startblock,
-                       XG_TYPE_AG);
-       xfs_defer_add(tp, &ri->ri_list, &xfs_rmap_update_defer_type);
+                       ri->ri_realtime ? XG_TYPE_RTG : XG_TYPE_AG);
+       xfs_defer_add(tp, &ri->ri_list, ri->ri_realtime ?
+                       &xfs_rtrmap_update_defer_type :
+                       &xfs_rmap_update_defer_type);
 }
 
 /* Cancel a deferred rmap update. */
@@ -356,6 +366,27 @@ const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
        .cancel_item    = xfs_rmap_update_cancel_item,
 };
 
+/* Clean up after calling xfs_rtrmap_finish_one. */
+STATIC void
+xfs_rtrmap_finish_one_cleanup(
+       struct xfs_trans        *tp,
+       struct xfs_btree_cur    *rcur,
+       int                     error)
+{
+       if (rcur)
+               xfs_btree_del_cursor(rcur, error);
+}
+
+const struct xfs_defer_op_type xfs_rtrmap_update_defer_type = {
+       .name           = "rtrmap",
+       .create_intent  = xfs_rmap_update_create_intent,
+       .abort_intent   = xfs_rmap_update_abort_intent,
+       .create_done    = xfs_rmap_update_create_done,
+       .finish_item    = xfs_rmap_update_finish_item,
+       .finish_cleanup = xfs_rtrmap_finish_one_cleanup,
+       .cancel_item    = xfs_rmap_update_cancel_item,
+};
+
 /* Reference Counting */
 
 static inline struct xfs_refcount_intent *ci_entry(const struct list_head *e)
index ec51b8465e61cba15bbd99791e2596bc119b65a7..1e2477eaa5a844e1cc0e7338bb2a7da28a41e6d8 100644 (file)
@@ -69,6 +69,7 @@ struct xfs_defer_op_type {
 extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
 extern const struct xfs_defer_op_type xfs_refcount_update_defer_type;
 extern const struct xfs_defer_op_type xfs_rmap_update_defer_type;
+extern const struct xfs_defer_op_type xfs_rtrmap_update_defer_type;
 extern const struct xfs_defer_op_type xfs_extent_free_defer_type;
 extern const struct xfs_defer_op_type xfs_agfl_free_defer_type;
 extern const struct xfs_defer_op_type xfs_rtextent_free_defer_type;
index 15dec19b6c32ad7aa182c378f3e0563075dfc6d7..a7e0e479454d3d5196abaea0094d0d8fc7b1492a 100644 (file)
@@ -250,6 +250,8 @@ typedef struct xfs_trans_header {
 #define        XFS_LI_XMD              0x1249  /* mapping exchange done */
 #define        XFS_LI_EFI_RT           0x124a  /* realtime extent free intent */
 #define        XFS_LI_EFD_RT           0x124b  /* realtime extent free done */
+#define        XFS_LI_RUI_RT           0x124c  /* realtime rmap update intent */
+#define        XFS_LI_RUD_RT           0x124d  /* realtime rmap update done */
 
 #define XFS_LI_TYPE_DESC \
        { XFS_LI_EFI,           "XFS_LI_EFI" }, \
@@ -271,7 +273,9 @@ typedef struct xfs_trans_header {
        { XFS_LI_XMI,           "XFS_LI_XMI" }, \
        { XFS_LI_XMD,           "XFS_LI_XMD" }, \
        { XFS_LI_EFI_RT,        "XFS_LI_EFI_RT" }, \
-       { XFS_LI_EFD_RT,        "XFS_LI_EFD_RT" }
+       { XFS_LI_EFD_RT,        "XFS_LI_EFD_RT" }, \
+       { XFS_LI_RUI_RT,        "XFS_LI_RUI_RT" }, \
+       { XFS_LI_RUD_RT,        "XFS_LI_RUD_RT" }
 
 /*
  * Inode Log Item Format definitions.
index 17cb2af457d89736d6f83b8fb0aacf85de833dc3..d173ac2757ea2d5ad4f6e79796d8ee10be3b9f24 100644 (file)
@@ -1830,7 +1830,7 @@ xfs_refcount_alloc_cow_extent(
        __xfs_refcount_add(tp, XFS_REFCOUNT_ALLOC_COW, fsb, len);
 
        /* Add rmap entry */
-       xfs_rmap_alloc_extent(tp, fsb, len, XFS_RMAP_OWN_COW);
+       xfs_rmap_alloc_extent(tp, false, fsb, len, XFS_RMAP_OWN_COW);
 }
 
 /* Forget a CoW staging event in the refcount btree. */
@@ -1846,7 +1846,7 @@ xfs_refcount_free_cow_extent(
                return;
 
        /* Remove rmap entry */
-       xfs_rmap_free_extent(tp, fsb, len, XFS_RMAP_OWN_COW);
+       xfs_rmap_free_extent(tp, false, fsb, len, XFS_RMAP_OWN_COW);
        __xfs_refcount_add(tp, XFS_REFCOUNT_FREE_COW, fsb, len);
 }
 
index 0dcaa8de784a05b3e0c3244e9d733062c12161ce..b75d10fce7c6c573338972004da10cf5e13c0e3b 100644 (file)
@@ -2711,6 +2711,7 @@ __xfs_rmap_add(
        struct xfs_trans                *tp,
        enum xfs_rmap_intent_type       type,
        uint64_t                        owner,
+       bool                            isrt,
        int                             whichfork,
        struct xfs_bmbt_irec            *bmap)
 {
@@ -2722,6 +2723,7 @@ __xfs_rmap_add(
        ri->ri_owner = owner;
        ri->ri_whichfork = whichfork;
        ri->ri_bmap = *bmap;
+       ri->ri_realtime = isrt;
 
        xfs_rmap_defer_add(tp, ri);
 }
@@ -2735,6 +2737,7 @@ xfs_rmap_map_extent(
        struct xfs_bmbt_irec    *PREV)
 {
        enum xfs_rmap_intent_type type = XFS_RMAP_MAP;
+       bool                    isrt = xfs_ifork_is_realtime(ip, whichfork);
 
        if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
                return;
@@ -2742,7 +2745,7 @@ xfs_rmap_map_extent(
        if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
                type = XFS_RMAP_MAP_SHARED;
 
-       __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
+       __xfs_rmap_add(tp, type, ip->i_ino, isrt, whichfork, PREV);
 }
 
 /* Unmap an extent out of a file. */
@@ -2754,6 +2757,7 @@ xfs_rmap_unmap_extent(
        struct xfs_bmbt_irec    *PREV)
 {
        enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP;
+       bool                    isrt = xfs_ifork_is_realtime(ip, whichfork);
 
        if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
                return;
@@ -2761,7 +2765,7 @@ xfs_rmap_unmap_extent(
        if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
                type = XFS_RMAP_UNMAP_SHARED;
 
-       __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
+       __xfs_rmap_add(tp, type, ip->i_ino, isrt, whichfork, PREV);
 }
 
 /*
@@ -2779,6 +2783,7 @@ xfs_rmap_convert_extent(
        struct xfs_bmbt_irec    *PREV)
 {
        enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT;
+       bool                    isrt = xfs_ifork_is_realtime(ip, whichfork);
 
        if (!xfs_rmap_update_is_needed(mp, whichfork))
                return;
@@ -2786,13 +2791,14 @@ xfs_rmap_convert_extent(
        if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
                type = XFS_RMAP_CONVERT_SHARED;
 
-       __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
+       __xfs_rmap_add(tp, type, ip->i_ino, isrt, whichfork, PREV);
 }
 
 /* Schedule the creation of an rmap for non-file data. */
 void
 xfs_rmap_alloc_extent(
        struct xfs_trans        *tp,
+       bool                    isrt,
        xfs_fsblock_t           fsbno,
        xfs_extlen_t            len,
        uint64_t                owner)
@@ -2807,13 +2813,14 @@ xfs_rmap_alloc_extent(
        bmap.br_startoff = 0;
        bmap.br_state = XFS_EXT_NORM;
 
-       __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap);
+       __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, isrt, XFS_DATA_FORK, &bmap);
 }
 
 /* Schedule the deletion of an rmap for non-file data. */
 void
 xfs_rmap_free_extent(
        struct xfs_trans        *tp,
+       bool                    isrt,
        xfs_fsblock_t           fsbno,
        xfs_extlen_t            len,
        uint64_t                owner)
@@ -2828,7 +2835,7 @@ xfs_rmap_free_extent(
        bmap.br_startoff = 0;
        bmap.br_state = XFS_EXT_NORM;
 
-       __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap);
+       __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, isrt, XFS_DATA_FORK, &bmap);
 }
 
 /* Compare rmap records.  Returns -1 if a < b, 1 if a > b, and 0 if equal. */
index 1b19f54b65047f3e38903b0a56aaf46b37f116f9..5f39f6e53cd19a7ebf090b993f37ad08ba16cbf9 100644 (file)
@@ -175,6 +175,7 @@ struct xfs_rmap_intent {
        uint64_t                                ri_owner;
        struct xfs_bmbt_irec                    ri_bmap;
        struct xfs_group                        *ri_group;
+       bool                                    ri_realtime;
 };
 
 /* functions for updating the rmapbt based on bmbt map/unmap operations */
@@ -185,9 +186,9 @@ void xfs_rmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
 void xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_trans *tp,
                struct xfs_inode *ip, int whichfork,
                struct xfs_bmbt_irec *imap);
-void xfs_rmap_alloc_extent(struct xfs_trans *tp, xfs_fsblock_t fsbno,
+void xfs_rmap_alloc_extent(struct xfs_trans *tp, bool isrt, xfs_fsblock_t fsbno,
                xfs_extlen_t len, uint64_t owner);
-void xfs_rmap_free_extent(struct xfs_trans *tp, xfs_fsblock_t fsbno,
+void xfs_rmap_free_extent(struct xfs_trans *tp, bool isrt, xfs_fsblock_t fsbno,
                xfs_extlen_t len, uint64_t owner);
 
 int xfs_rmap_finish_one(struct xfs_trans *tp, struct xfs_rmap_intent *ri,