[PATCH 15/36] xfs: store rtgroup information with a bmap intent

Darrick J. Wong
2024-10-11T01:05:36Z

Make the bmap intent items take an active reference to the rtgroup
containing the space that is being mapped or unmapped. We will need
this functionality once we start enabling rmap and reflink on the rt
volume. Technically speaking we need it even for !rtgroups filesystems
to prevent the (dummy) rtgroup 0 from going away, even though this will
never happen.

As a bonus, we can rework the xfs_bmap_deferred_class tracepoint to use
the xfs_group object to figure out the type and group number, widen the
group block number field to fit 64-bit quantities, and get rid of the
now redundant opdev and rtblock fields.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/xfs_bmap_item.c | 25 ++++++++-----------------
fs/xfs/xfs_trace.h | 43 +++++++++++++++++++++++++------------------
2 files changed, 33 insertions(+), 35 deletions(-)

diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 37dab184c2dfc2..3d52e9d7ad571a 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -318,14 +318,16 @@ xfs_bmap_update_create_done(
return &budp->bud_item;
}

-/* Take a passive 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
@@ -335,7 +337,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. */
@@ -344,8 +346,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);

/*
@@ -358,20 +358,11 @@ xfs_bmap_defer_add(
*/
if (bi->bi_type == XFS_BMAP_MAP)
bi->bi_owner->i_delayed_blks += bi->bi_bmap.br_blockcount;
+
+ trace_xfs_bmap_defer(bi);
xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
}

-/* Release a passive 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);
-}
-
/* Cancel a deferred bmap update. */
STATIC void
xfs_bmap_update_cancel_item(
@@ -382,7 +373,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);
}

diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index deb23a91883ad7..5256b9cccf2e9b 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -3086,11 +3086,10 @@ DECLARE_EVENT_CLASS(xfs_bmap_deferred_class,
TP_ARGS(bi),
TP_STRUCT__entry(
__field(dev_t, dev)
- __field(dev_t, opdev)
+ __field(enum xfs_group_type, type)
__field(xfs_agnumber_t, agno)
__field(xfs_ino_t, ino)
- __field(xfs_agblock_t, agbno)
- __field(xfs_fsblock_t, rtbno)
+ __field(unsigned long long, gbno)
__field(int, whichfork)
__field(xfs_fileoff_t, l_loff)
__field(xfs_filblks_t, l_len)
@@ -3099,20 +3098,29 @@ DECLARE_EVENT_CLASS(xfs_bmap_deferred_class,
),
TP_fast_assign(
struct xfs_inode *ip = bi->bi_owner;
+ struct xfs_mount *mp = ip->i_mount;

- __entry->dev = ip->i_mount->m_super->s_dev;
- if (xfs_ifork_is_realtime(ip, bi->bi_whichfork)) {
- __entry->agno = 0;
- __entry->agbno = 0;
- __entry->rtbno = bi->bi_bmap.br_startblock;
- __entry->opdev = ip->i_mount->m_rtdev_targp->bt_dev;
- } else {
- __entry->agno = XFS_FSB_TO_AGNO(ip->i_mount,
+ __entry->dev = mp->m_super->s_dev;
+ __entry->type = bi->bi_group->xg_type;
+ __entry->agno = bi->bi_group->xg_index;
+ switch (__entry->type) {
+ case XG_TYPE_RTG:
+ /*
+ * Use the 64-bit version of xfs_rtb_to_rgbno because
+ * legacy rt filesystems can have group block numbers
+ * that exceed the size of an xfs_rgblock_t.
+ */
+ __entry->gbno = __xfs_rtb_to_rgbno(mp,
bi->bi_bmap.br_startblock);
- __entry->agbno = XFS_FSB_TO_AGBNO(ip->i_mount,
+ break;
+ case XG_TYPE_AG:
+ __entry->gbno = XFS_FSB_TO_AGBNO(mp,
bi->bi_bmap.br_startblock);
- __entry->rtbno = 0;
- __entry->opdev = __entry->dev;
+ break;
+ default:
+ /* should never happen */
+ __entry->gbno = -1ULL;
+ break;
}
__entry->ino = ip->i_ino;
__entry->whichfork = bi->bi_whichfork;
@@ -3121,14 +3129,13 @@ DECLARE_EVENT_CLASS(xfs_bmap_deferred_class,
__entry->l_state = bi->bi_bmap.br_state;
__entry->op = bi->bi_type;
),
- TP_printk("dev %d:%d op %s opdev %d:%d ino 0x%llx agno 0x%x agbno 0x%x rtbno 0x%llx %s fileoff 0x%llx fsbcount 0x%llx state %d",
+ TP_printk("dev %d:%d op %s ino 0x%llx %sno 0x%x gbno 0x%llx %s fileoff 0x%llx fsbcount 0x%llx state %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
__print_symbolic(__entry->op, XFS_BMAP_INTENT_STRINGS),
- MAJOR(__entry->opdev), MINOR(__entry->opdev),
__entry->ino,
+ __print_symbolic(__entry->type, XG_TYPE_STRINGS),
__entry->agno,
- __entry->agbno,
- __entry->rtbno,
+ __entry->gbno,
__print_symbolic(__entry->whichfork, XFS_WHICHFORK_STRINGS),
__entry->l_loff,
__entry->l_len,