From c73eb7062ef0ddb553b2ab01b9369e431b7a99c9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 7 Nov 2019 09:01:23 -0500 Subject: [PATCH] debugfs: teach the htree command to check and display the dx block checksum To do this we need to export the ext2fs_dx_csum() function from libext2fs. Signed-off-by: Theodore Ts'o --- debian/libext2fs2.symbols | 1 + debugfs/htree.c | 30 +++++++++++++++++++++++++----- lib/ext2fs/csum.c | 6 +++--- lib/ext2fs/ext2fs.h | 3 +++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/debian/libext2fs2.symbols b/debian/libext2fs2.symbols index 78c20b2..53cb035 100644 --- a/debian/libext2fs2.symbols +++ b/debian/libext2fs2.symbols @@ -181,6 +181,7 @@ libext2fs.so.2 libext2fs2 #MINVER# ext2fs_div_ceil@Base 1.40 ext2fs_djb2_hash@Base 1.44.3~rc1 ext2fs_dup_handle@Base 1.37 + ext2fs_dx_csum@Base 1.46~WIP.2019.10.09 ext2fs_expand_dir@Base 1.37 ext2fs_ext_attr_block_csum_set@Base 1.43 ext2fs_ext_attr_block_csum_verify@Base 1.43 diff --git a/debugfs/htree.c b/debugfs/htree.c index 3aae3c2..b567a76 100644 --- a/debugfs/htree.c +++ b/debugfs/htree.c @@ -136,7 +136,7 @@ static void htree_dump_int_block(ext2_filsys fs, ext2_ino_t ino, static void htree_dump_int_node(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, struct ext2_dx_root_info * rootnode, - struct ext2_dx_entry *ent, + struct ext2_dx_entry *ent, __u32 crc, char *buf, int level) { struct ext2_dx_countlimit dx_countlimit; @@ -160,8 +160,11 @@ static void htree_dump_int_node(ext2_filsys fs, ext2_ino_t ino, if (ext2fs_has_feature_metadata_csum(fs->super) && remainder == sizeof(struct ext2_dx_tail)) { tail = (struct ext2_dx_tail *)(ent + limit); - fprintf(pager, "Checksum: 0x%08x\n", + fprintf(pager, "Checksum: 0x%08x", ext2fs_le32_to_cpu(tail->dt_checksum)); + if (tail->dt_checksum != crc) + fprintf(pager, " --- EXPECTED: 0x%08x", crc); + fputc('\n', pager); } for (i=0; i < count; i++) { @@ -199,6 +202,7 @@ static void htree_dump_int_block(ext2_filsys fs, ext2_ino_t ino, char *cbuf; errcode_t errcode; blk64_t pblk; + __u32 crc; cbuf = malloc(fs->blocksize); if (!cbuf) { @@ -216,13 +220,21 @@ static void htree_dump_int_block(ext2_filsys fs, ext2_ino_t ino, errcode = io_channel_read_blk64(current_fs->io, pblk, 1, buf); if (errcode) { com_err("htree_dump_int_block", errcode, - "while reading block %llu\n", blk); + "while reading block %llu\n", blk); goto errout; } + errcode = ext2fs_dx_csum(current_fs, ino, + (struct ext2_dir_entry *) buf, &crc, NULL); + if (errcode) { + com_err("htree_dump_int_block", errcode, + "while calculating checksum for logical block %llu\n", + (unsigned long long) blk); + crc = (unsigned int) -1; + } htree_dump_int_node(fs, ino, inode, rootnode, (struct ext2_dx_entry *) (buf+8), - cbuf, level); + crc, cbuf, level); errout: free(cbuf); } @@ -239,6 +251,7 @@ void do_htree_dump(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)), struct ext2_dx_root_info *rootnode; struct ext2_dx_entry *ent; errcode_t errcode; + __u32 crc; if (check_fs_open(argv[0])) return; @@ -293,7 +306,14 @@ void do_htree_dump(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)), ent = (struct ext2_dx_entry *) ((char *)rootnode + rootnode->info_length); - htree_dump_int_node(current_fs, ino, &inode, rootnode, ent, + errcode = ext2fs_dx_csum(current_fs, ino, + (struct ext2_dir_entry *) buf, &crc, NULL); + if (errcode) { + com_err("htree_dump_int_block", errcode, + "while calculating checksum for htree root\n"); + crc = (unsigned int) -1; + } + htree_dump_int_node(current_fs, ino, &inode, rootnode, ent, crc, buf + current_fs->blocksize, rootnode->indirect_levels); diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index bc80939..2c5b0f2 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -358,9 +358,9 @@ static errcode_t ext2fs_dirent_csum_set(ext2_filsys fs, ext2_ino_t inum, return 0; } -static errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum, - struct ext2_dir_entry *dirent, - __u32 *crc, struct ext2_dx_tail **ret_t) +errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum, + struct ext2_dir_entry *dirent, + __u32 *crc, struct ext2_dx_tail **ret_t) { errcode_t retval; char *buf = (char *)dirent; diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index a5ed10f..da30994 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -1082,6 +1082,9 @@ extern errcode_t ext2fs_get_dx_countlimit(ext2_filsys fs, struct ext2_dir_entry *dirent, struct ext2_dx_countlimit **cc, int *offset); +extern errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum, + struct ext2_dir_entry *dirent, + __u32 *crc, struct ext2_dx_tail **ret_t); extern errcode_t ext2fs_extent_block_csum_set(ext2_filsys fs, ext2_ino_t inum, struct ext3_extent_header *eh); -- 1.8.3.1