[PATCH 14/41] xfs_db: display di_metatype

Darrick J. Wong
2024-12-06T23:43:18Z

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

Print the metadata file type if available.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
db/field.c | 2 +
db/field.h | 1 +
db/inode.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
db/inode.h | 2 +
4 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/db/field.c b/db/field.c
index a61ccc9ef6d072..946684415f65d3 100644
--- a/db/field.c
+++ b/db/field.c
@@ -212,6 +212,8 @@ const ftattr_t ftattrtab[] = {
SI(bitsz(struct xfs_dinode)), 0, NULL, inode_core_flds },
{ FLDT_DINODE_FMT, "dinode_fmt", fp_dinode_fmt, NULL,
SI(bitsz(int8_t)), 0, NULL, NULL },
+ { FLDT_DINODE_METATYPE, "metatype", fp_metatype, NULL,
+ SI(bitsz(uint16_t)), 0, NULL, NULL },
{ FLDT_DINODE_U, "dinode_u", NULL, (char *)inode_u_flds, inode_u_size,
FTARG_SIZE|FTARG_OKEMPTY, NULL, inode_u_flds },
{ FLDT_DINODE_V3, "dinode_v3", NULL, (char *)inode_v3_flds,
diff --git a/db/field.h b/db/field.h
index b1bfdbed19cea3..9746676a6c7ac9 100644
--- a/db/field.h
+++ b/db/field.h
@@ -95,6 +95,7 @@ typedef enum fldt {
FLDT_DINODE_A,
FLDT_DINODE_CORE,
FLDT_DINODE_FMT,
+ FLDT_DINODE_METATYPE,
FLDT_DINODE_U,
FLDT_DINODE_V3,

diff --git a/db/inode.c b/db/inode.c
index 0aff68083508cb..07efbb4902be08 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -25,6 +25,7 @@ static int inode_a_offset(void *obj, int startoff, int idx);
static int inode_a_sfattr_count(void *obj, int startoff);
static int inode_core_nlinkv2_count(void *obj, int startoff);
static int inode_core_onlink_count(void *obj, int startoff);
+static int inode_core_metatype_count(void *obj, int startoff);
static int inode_core_projid_count(void *obj, int startoff);
static int inode_core_nlinkv1_count(void *obj, int startoff);
static int inode_core_v3_pad_count(void *obj, int startoff);
@@ -94,6 +95,8 @@ const field_t inode_core_flds[] = {
FLD_COUNT, TYP_NONE },
{ "onlink", FLDT_UINT16D, OI(COFF(metatype)), inode_core_onlink_count,
FLD_COUNT, TYP_NONE },
+ { "metatype", FLDT_DINODE_METATYPE, OI(COFF(metatype)),
+ inode_core_metatype_count, FLD_COUNT, TYP_NONE },
{ "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
{ "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
{ "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count,
@@ -247,9 +250,8 @@ static const char *dinode_fmt_name[] =
static const int dinode_fmt_name_size =
sizeof(dinode_fmt_name) / sizeof(dinode_fmt_name[0]);

-/*ARGSUSED*/
-int
-fp_dinode_fmt(
+static int
+fp_enum_fmt(
void *obj,
int bit,
int count,
@@ -257,26 +259,65 @@ fp_dinode_fmt(
int size,
int arg,
int base,
- int array)
+ int array,
+ const char **names,
+ unsigned int nr_names)
{
int bitpos;
- enum xfs_dinode_fmt f;
+ int f;
int i;

for (i = 0, bitpos = bit; i < count; i++, bitpos += size) {
- f = (enum xfs_dinode_fmt)getbitval(obj, bitpos, size, BVUNSIGNED);
+ f = getbitval(obj, bitpos, size, BVUNSIGNED);
if (array)
dbprintf("%d:", i + base);
- if (f < 0 || f >= dinode_fmt_name_size)
- dbprintf("%d", (int)f);
+ if (f < 0 || f >= nr_names)
+ dbprintf("%d", f);
else
- dbprintf("%d (%s)", (int)f, dinode_fmt_name[(int)f]);
+ dbprintf("%d (%s)", f, names[f]);
if (i < count - 1)
dbprintf(" ");
}
return 1;
}

+/*ARGSUSED*/
+int
+fp_dinode_fmt(
+ void *obj,
+ int bit,
+ int count,
+ char *fmtstr,
+ int size,
+ int arg,
+ int base,
+ int array)
+{
+ return fp_enum_fmt(obj, bit, count, fmtstr, size, arg, base, array,
+ dinode_fmt_name, dinode_fmt_name_size);
+}
+
+static const char *metatype_name[] =
+ { "unknown", "dir", "usrquota", "grpquota", "prjquota", "rtbitmap",
+ "rtsummary"
+ };
+static const int metatype_name_size = ARRAY_SIZE(metatype_name);
+
+int
+fp_metatype(
+ void *obj,
+ int bit,
+ int count,
+ char *fmtstr,
+ int size,
+ int arg,
+ int base,
+ int array)
+{
+ return fp_enum_fmt(obj, bit, count, fmtstr, size, arg, base, array,
+ metatype_name, metatype_name_size);
+}
+
static int
inode_a_bmbt_count(
void *obj,
@@ -414,7 +455,29 @@ inode_core_onlink_count(
ASSERT(startoff == 0);
ASSERT(obj == iocur_top->data);
dic = obj;
- return dic->di_version >= 2;
+ if (dic->di_version < 2)
+ return 0;
+ if (dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA))
+ return 0;
+ return 1;
+}
+
+static int
+inode_core_metatype_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (dic->di_version < 3)
+ return 0;
+ if (dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA))
+ return 1;
+ return 0;
}

static int
diff --git a/db/inode.h b/db/inode.h
index 31a2ebbba6a175..e281cdff15c096 100644
--- a/db/inode.h
+++ b/db/inode.h
@@ -16,6 +16,8 @@ extern const struct field timestamp_flds[];

extern int fp_dinode_fmt(void *obj, int bit, int count, char *fmtstr,
int size, int arg, int base, int array);
+extern int fp_metatype(void *obj, int bit, int count, char *fmtstr,
+ int size, int arg, int base, int array);
extern int inode_a_size(void *obj, int startoff, int idx);
extern void inode_init(void);
extern typnm_t inode_next_type(void);