From: Darrick J. Wong Date: Tue, 13 Dec 2022 19:39:48 +0000 (-0800) Subject: xfs_db: create separate struct and field definitions for finobts X-Git-Tag: origin/for-next_2022-12-17~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e229a59f010b7f8544f9350987fff5e86d06dfcf;p=thirdparty%2Fxfsprogs-dev.git xfs_db: create separate struct and field definitions for finobts Create separate field_t definitions for the free inode btree because db needs to know that the interior block pointers point to finobt blocks, not inobt blocks. This is critical now because the buffer ops contain magic numbers, the ->verify_struct routines use the magics listed in the buffer ops, and the xfs_db iocursor calls the verifier functions. Without this patch, xfs_db emits bizarre output like this: # xfs_db -x /dev/sde -c 'agi 1' -c 'addr free_root' -c 'addr ptrs[1]' -c print 2>&1 | head Metadata corruption detected at 0x55dda21258b0, xfs_inobt block 0x275c20/0x1000 magic = 0x46494233 Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Signed-off-by: Carlos Maiolino --- diff --git a/db/btblock.c b/db/btblock.c index c563fb038..30f7b5ef9 100644 --- a/db/btblock.c +++ b/db/btblock.c @@ -491,6 +491,76 @@ const field_t inobt_spcrc_flds[] = { { NULL } }; +/* free inode btree */ + +const field_t finobt_hfld[] = { + { "", FLDT_FINOBT, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +const field_t finobt_crc_hfld[] = { + { "", FLDT_FINOBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +const field_t finobt_spcrc_hfld[] = { + { "", FLDT_FINOBT_SPCRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +const field_t finobt_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT }, + { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_FINOBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_FINOBT }, + { NULL } +}; +const field_t finobt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_INOBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_FINOBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_FINOBT }, + { NULL } +}; +const field_t finobt_spcrc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_INOBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_INOBTSPREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_FINOBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_FINOBT }, + { NULL } +}; + #undef OFF #define KOFF(f) bitize(offsetof(xfs_inobt_key_t, ir_ ## f)) diff --git a/db/btblock.h b/db/btblock.h index 465acde7b..4168c9e2e 100644 --- a/db/btblock.h +++ b/db/btblock.h @@ -24,6 +24,12 @@ extern const struct field inobt_crc_flds[]; extern const struct field inobt_spcrc_flds[]; extern const struct field inobt_crc_hfld[]; extern const struct field inobt_spcrc_hfld[]; +extern const struct field finobt_flds[]; +extern const struct field finobt_hfld[]; +extern const struct field finobt_crc_flds[]; +extern const struct field finobt_spcrc_flds[]; +extern const struct field finobt_crc_hfld[]; +extern const struct field finobt_spcrc_hfld[]; extern const struct field inobt_key_flds[]; extern const struct field inobt_rec_flds[]; extern const struct field inobt_sprec_flds[]; diff --git a/db/field.c b/db/field.c index 77cab9022..a3e47ee81 100644 --- a/db/field.c +++ b/db/field.c @@ -308,10 +308,18 @@ const ftattr_t ftattrtab[] = { FTARG_SIZE, NULL, inobt_crc_flds }, { FLDT_INOBT_SPCRC, "inobt", NULL, (char *)inobt_spcrc_flds, btblock_size, FTARG_SIZE, NULL, inobt_spcrc_flds }, + { FLDT_FINOBT, "finobt", NULL, (char *)finobt_flds, btblock_size, + FTARG_SIZE, NULL, finobt_flds }, + { FLDT_FINOBT_CRC, "finobt", NULL, (char *)finobt_crc_flds, btblock_size, + FTARG_SIZE, NULL, finobt_crc_flds }, + { FLDT_FINOBT_SPCRC, "finobt", NULL, (char *)finobt_spcrc_flds, + btblock_size, FTARG_SIZE, NULL, finobt_spcrc_flds }, { FLDT_INOBTKEY, "inobtkey", fp_sarray, (char *)inobt_key_flds, SI(bitsz(xfs_inobt_key_t)), 0, NULL, inobt_key_flds }, { FLDT_INOBTPTR, "inobtptr", fp_num, "%u", SI(bitsz(xfs_inobt_ptr_t)), 0, fa_agblock, NULL }, + { FLDT_FINOBTPTR, "finobtptr", fp_num, "%u", SI(bitsz(xfs_inobt_ptr_t)), + 0, fa_agblock, NULL }, { FLDT_INOBTREC, "inobtrec", fp_sarray, (char *)inobt_rec_flds, SI(bitsz(xfs_inobt_rec_t)), 0, NULL, inobt_rec_flds }, { FLDT_INOBTSPREC, "inobtsprec", fp_sarray, (char *) inobt_sprec_flds, diff --git a/db/field.h b/db/field.h index 614fd0ab4..634742a57 100644 --- a/db/field.h +++ b/db/field.h @@ -147,8 +147,12 @@ typedef enum fldt { FLDT_INOBT, FLDT_INOBT_CRC, FLDT_INOBT_SPCRC, + FLDT_FINOBT, + FLDT_FINOBT_CRC, + FLDT_FINOBT_SPCRC, FLDT_INOBTKEY, FLDT_INOBTPTR, + FLDT_FINOBTPTR, FLDT_INOBTREC, FLDT_INOBTSPREC, FLDT_INODE, diff --git a/db/type.c b/db/type.c index f8d8b5551..efe704456 100644 --- a/db/type.c +++ b/db/type.c @@ -63,7 +63,7 @@ static const typ_t __typtab[] = { { TYP_SB, "sb", handle_struct, sb_hfld, NULL, TYP_F_NO_CRC_OFF }, { TYP_SYMLINK, "symlink", handle_string, NULL, NULL, TYP_F_NO_CRC_OFF }, { TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF }, - { TYP_FINOBT, "finobt", handle_struct, inobt_hfld, NULL, + { TYP_FINOBT, "finobt", handle_struct, finobt_hfld, NULL, TYP_F_NO_CRC_OFF }, { TYP_NONE, NULL } }; @@ -107,7 +107,7 @@ static const typ_t __typtab_crc[] = { { TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld, &xfs_symlink_buf_ops, XFS_SYMLINK_CRC_OFF }, { TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF }, - { TYP_FINOBT, "finobt", handle_struct, inobt_crc_hfld, + { TYP_FINOBT, "finobt", handle_struct, finobt_crc_hfld, &xfs_finobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF }, { TYP_NONE, NULL } }; @@ -151,7 +151,7 @@ static const typ_t __typtab_spcrc[] = { { TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld, &xfs_symlink_buf_ops, XFS_SYMLINK_CRC_OFF }, { TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF }, - { TYP_FINOBT, "finobt", handle_struct, inobt_spcrc_hfld, + { TYP_FINOBT, "finobt", handle_struct, finobt_spcrc_hfld, &xfs_finobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF }, { TYP_NONE, NULL } };