[PATCH 26/50] xfs_db: fix rtconvert to handle segmented rtblocks

Darrick J. Wong
2024-12-07T00:11:42Z

From: Darrick J. Wong <djwong@kernel.org>

Now that we've turned xfs_rtblock_t into a segmented address and
xfs_rtxnum_t into a per-rtgroup address, port the rtconvert debugger
command to handle the unit conversions correctly. Also add an example
of the bitmap/summary-related conversion commands to the manpage.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
db/convert.c | 52 ++++++++++++++++++++++++++++++++++++++--------------
man/man8/xfs_db.8 | 17 +++++++++++++++--
2 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/db/convert.c b/db/convert.c
index 0c5c942150fe6f..2cdde7d05ac397 100644
--- a/db/convert.c
+++ b/db/convert.c
@@ -26,14 +26,14 @@
agino_to_bytes(XFS_INO_TO_AGINO(mp, (x))))
#define inoidx_to_bytes(x) \
((uint64_t)(x) << mp->m_sb.sb_inodelog)
-#define rtblock_to_bytes(x) \
- ((uint64_t)(x) << mp->m_sb.sb_blocklog)
-#define rtx_to_rtblock(x) \
- ((uint64_t)(x) * mp->m_sb.sb_rextsize)
-#define rbmblock_to_bytes(x) \
- rtblock_to_bytes(rtx_to_rtblock(xfs_rbmblock_to_rtx(mp, (uint64_t)x)))
-#define rbmword_to_bytes(x) \
- rtblock_to_bytes(rtx_to_rtblock((uint64_t)(x) << XFS_NBWORDLOG))
+#define rtblock_to_bytes(x) \
+ (xfs_rtb_to_daddr(mp, (x)) << BBSHIFT)
+#define rtx_to_bytes(x) \
+ (((uint64_t)(x) * mp->m_sb.sb_rextsize) << mp->m_sb.sb_blocklog)
+#define rbmblock_to_bytes(x) \
+ rtx_to_bytes(xfs_rbmblock_to_rtx(mp, (x)))
+#define rbmword_to_bytes(x) \
+ rtx_to_bytes((uint64_t)(x) << XFS_NBWORDLOG)

typedef enum {
CT_NONE = -1,
@@ -316,7 +316,7 @@ bytevalue(ctype_t ctype, cval_t *val)
case CT_RTBLOCK:
return rtblock_to_bytes(val->rtblock);
case CT_RTX:
- return rtblock_to_bytes(rtx_to_rtblock(val->rtx));
+ return rtx_to_bytes(val->rtx);
case CT_RBMBLOCK:
return rbmblock_to_bytes(val->rbmblock);
case CT_RBMWORD:
@@ -495,6 +495,32 @@ rt_daddr_to_rsuminfo(
return xfs_rtsumoffs_to_infoword(mp, rsumoff);
}

+/* Translate an rt device disk address to be in units of realtime extents. */
+static inline uint64_t
+rt_daddr_to_rtx(
+ struct xfs_mount *mp,
+ xfs_daddr_t daddr)
+{
+ return XFS_BB_TO_FSBT(mp, daddr) / mp->m_sb.sb_rextsize;
+}
+
+/*
+ * Compute the offset of an rt device disk address from the start of an
+ * rtgroup and return the result in units of realtime extents.
+ */
+static inline uint64_t
+rt_daddr_to_rtgrtx(
+ struct xfs_mount *mp,
+ xfs_daddr_t daddr)
+{
+ uint64_t rtx = rt_daddr_to_rtx(mp, daddr);
+
+ if (xfs_has_rtgroups(mp))
+ return rtx % mp->m_sb.sb_rgextents;
+
+ return rtx;
+}
+
static int
rtconvert_f(int argc, char **argv)
{
@@ -565,17 +591,15 @@ rtconvert_f(int argc, char **argv)
v = xfs_daddr_to_rtb(mp, v >> BBSHIFT);
break;
case CT_RTX:
- v = xfs_daddr_to_rtb(mp, v >> BBSHIFT) / mp->m_sb.sb_rextsize;
+ v = rt_daddr_to_rtx(mp, v >> BBSHIFT);
break;
case CT_RBMBLOCK:
v = xfs_rtx_to_rbmblock(mp,
- xfs_rtb_to_rtx(mp,
- xfs_daddr_to_rtb(mp, v >> BBSHIFT)));
+ rt_daddr_to_rtgrtx(mp, v >> BBSHIFT));
break;
case CT_RBMWORD:
v = xfs_rtx_to_rbmword(mp,
- xfs_rtb_to_rtx(mp,
- xfs_daddr_to_rtb(mp, v >> BBSHIFT)));
+ rt_daddr_to_rtgrtx(mp, v >> BBSHIFT));
break;
case CT_RSUMBLOCK:
v = rt_daddr_to_rsumblock(mp, v);
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index 066f124458b286..3cc7314cac0e66 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -1244,10 +1244,23 @@ .SH COMMANDS
conversion type, and the type must be
.BR rsumlog .

-To compute the rt bitmap block from summary file location, the type/number pairs
-must be specified exactly in the order
+For example, these commands tell us where to look in the rt summary file for
+the number of free rtextents of length 2^21 starting in rt bitmap block 30:
+
+.B rtconvert rbmblock 30 rsumlog 21 rsumblock
+
+.B rtconvert rbmblock 30 rsumlog 21 rsuminfo
+
+To compute the rt bitmap block from summary file location, the type/number
+pairs must be specified exactly in the order
.BR rsumlog ", " rsuminfo ", " rsumblock .

+For example, this command tells us which block in the rt bitmap file is
+summarized by info word 809 in rt summary block 10 assuming that the
+maximum free extent length is 2^21 rtextents:
+
+.B rtconvert rsumlog 21 rsuminfo 809 rsumblock 10 rbmblock
+
.TP
.BI "sb [" agno ]
Set current address to SB header in allocation group