[PATCH 08/27] xfs_db: support the realtime rmapbt

Darrick J. Wong
2025-02-06T22:51:49Z

Wire up various parts of xfs_db for realtime rmap support so that we can
dump the btree contents.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
db/btblock.c | 3 ++
db/btdump.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
db/btheight.c | 5 ++++
libxfs/libxfs_api_defs.h | 1 +
man/man8/xfs_db.8 | 3 +-
5 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/db/btblock.c b/db/btblock.c
index 5cad166278d98b..70f6c3f6aedde5 100644
--- a/db/btblock.c
+++ b/db/btblock.c
@@ -147,6 +147,9 @@ block_to_bt(
case TYP_RMAPBT:
magic = crc ? XFS_RMAP_CRC_MAGIC : 0;
break;
+ case TYP_RTRMAPBT:
+ magic = crc ? XFS_RTRMAP_CRC_MAGIC : 0;
+ break;
case TYP_REFCBT:
magic = crc ? XFS_REFC_CRC_MAGIC : 0;
break;
diff --git a/db/btdump.c b/db/btdump.c
index 81642cde2b6d8f..55301d25de10cd 100644
--- a/db/btdump.c
+++ b/db/btdump.c
@@ -441,6 +441,66 @@ dump_dabtree(
return ret;
}

+static bool
+is_btree_inode(void)
+{
+ struct xfs_dinode *dip = iocur_top->data;
+
+ return dip->di_format == XFS_DINODE_FMT_META_BTREE;
+}
+
+static int
+dump_btree_inode(
+ bool dump_node_blocks)
+{
+ char *prefix;
+ struct xfs_dinode *dip = iocur_top->data;
+ struct xfs_rtrmap_root *rtrmap;
+ int level;
+ int numrecs;
+ int ret;
+
+ switch (be16_to_cpu(dip->di_metatype)) {
+ case XFS_METAFILE_RTRMAP:
+ prefix = "u3.rtrmapbt";
+ rtrmap = (struct xfs_rtrmap_root *)XFS_DFORK_DPTR(dip);
+ level = be16_to_cpu(rtrmap->bb_level);
+ numrecs = be16_to_cpu(rtrmap->bb_numrecs);
+ break;
+ default:
+ dbprintf("Unknown metadata inode btree type %u\n",
+ be16_to_cpu(dip->di_metatype));
+ return 0;
+ }
+
+ if (numrecs == 0)
+ return 0;
+ if (level > 0) {
+ if (dump_node_blocks) {
+ ret = eval("print %s.keys", prefix);
+ if (ret)
+ goto err;
+ ret = eval("print %s.ptrs", prefix);
+ if (ret)
+ goto err;
+ }
+ ret = eval("addr %s.ptrs[1]", prefix);
+ if (ret)
+ goto err;
+ ret = dump_btree_long(dump_node_blocks);
+ } else {
+ ret = eval("print %s.recs", prefix);
+ }
+ if (ret)
+ goto err;
+
+ ret = eval("pop");
+ return ret;
+err:
+ eval("pop");
+ return ret;
+}
+
static int
btdump_f(
int argc,
@@ -488,8 +548,11 @@ btdump_f(
return dump_btree_short(iflag);
case TYP_BMAPBTA:
case TYP_BMAPBTD:
+ case TYP_RTRMAPBT:
return dump_btree_long(iflag);
case TYP_INODE:
+ if (is_btree_inode())
+ return dump_btree_inode(iflag);
return dump_inode(iflag, aflag);
case TYP_ATTR:
return dump_dabtree(iflag, crc ? &attr3_print : &attr_print);
diff --git a/db/btheight.c b/db/btheight.c
index 0456af08b39edf..31dff1c924a2e0 100644
--- a/db/btheight.c
+++ b/db/btheight.c
@@ -53,6 +53,11 @@ struct btmap {
.maxlevels = libxfs_rmapbt_maxlevels_ondisk,
.maxrecs = libxfs_rmapbt_maxrecs,
},
+ {
+ .tag = "rtrmapbt",
+ .maxlevels = libxfs_rtrmapbt_maxlevels_ondisk,
+ .maxrecs = libxfs_rtrmapbt_maxrecs,
+ },
};

static void
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index fcbcaaa11f1025..cf88656946ab1b 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -311,6 +311,7 @@
#define xfs_rtfree_blocks libxfs_rtfree_blocks
#define xfs_update_rtsb libxfs_update_rtsb
#define xfs_rtrmapbt_droot_maxrecs libxfs_rtrmapbt_droot_maxrecs
+#define xfs_rtrmapbt_maxlevels_ondisk libxfs_rtrmapbt_maxlevels_ondisk
#define xfs_rtrmapbt_maxrecs libxfs_rtrmapbt_maxrecs

#define xfs_sb_from_disk libxfs_sb_from_disk
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index ddbabe36b5fc41..83a8734d3c0b47 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -535,8 +535,9 @@ .SH COMMANDS
.IR finobt ,
.IR bmapbt ,
.IR refcountbt ,
+.IR rmapbt ,
and
-.IR rmapbt .
+.IR rtrmapbt .
The magic value
.I all
can be used to walk through all btree types.