From b3c2a638139b5da7f63f7ebe450860918d297a39 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 24 Dec 2013 23:19:07 -0500 Subject: [PATCH] libext2fs: checksum bg descriptors larger than 64 bytes Currently the ext4 block group descriptor is 64 bytes. In case we need to support larger block group descriptors in the future, teach ext2fs_group_desc_csum() to checksum parts of the block group descriptors that libext2fs doesn't yet understand. Signed-off-by: "Theodore Ts'o" --- lib/ext2fs/csum.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index 77d3d17..b681d34 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -43,8 +43,13 @@ __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) #ifdef WORDS_BIGENDIAN struct ext4_group_desc swabdesc; + size_t save_size = size; + const size_t ext4_bg_size = sizeof(struct ext4_group_desc); + struct ext2_group_desc *save_desc = desc; /* Have to swab back to little-endian to do the checksum */ + if (size > ext4_bg_size) + size = ext4_bg_size; memcpy(&swabdesc, desc, size); ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc); @@ -62,6 +67,17 @@ __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) crc = ext2fs_crc16(crc, (char *)desc + offset, size - offset); } +#ifdef WORDS_BIGENDIAN + /* + * If the size of the bg descriptor is greater than 64 + * bytes, which is the size of the traditional ext4 bg + * descriptor, checksum the rest of the descriptor here + */ + if (save_size > ext4_bg_size) + crc = ext2fs_crc16(crc, + (char *)save_desc + ext4_bg_size, + save_size - ext4_bg_size); +#endif } return crc; @@ -158,18 +174,22 @@ void print_csum(const char *msg, ext2_filsys fs, dgrp_t group) { __u16 crc1, crc2, crc3; dgrp_t swabgroup; - struct ext2_group_desc *desc; - size_t size; + struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, + group); + size_t size = EXT2_DESC_SIZE(fs->super); struct ext2_super_block *sb = fs->super; int offset = offsetof(struct ext2_group_desc, bg_checksum); #ifdef WORDS_BIGENDIAN struct ext4_group_desc swabdesc; + struct ext2_group_desc *save_desc = desc; + const size_t ext4_bg_size = sizeof(struct ext4_group_desc); + size_t save_size = size; #endif - desc = ext2fs_group_desc(fs, fs->group_desc, group); - size = EXT2_DESC_SIZE(fs->super); #ifdef WORDS_BIGENDIAN /* Have to swab back to little-endian to do the checksum */ + if (size > ext4_bg_size) + size = ext4_bg_size; memcpy(&swabdesc, desc, size); ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc); desc = (struct ext2_group_desc *) &swabdesc; @@ -186,6 +206,11 @@ void print_csum(const char *msg, ext2_filsys fs, dgrp_t group) /* for checksum of struct ext4_group_desc do the rest...*/ if (offset < size) crc3 = ext2fs_crc16(crc3, (char *)desc + offset, size - offset); +#ifdef WORDS_BIGENDIAN + if (save_size > ext4_bg_size) + crc3 = ext2fs_crc16(crc3, (char *)save_desc + ext4_bg_size, + save_size - ext4_bg_size); +#endif printf("%s UUID %s=%04x, grp %u=%04x: %04x=%04x\n", msg, e2p_uuid2str(sb->s_uuid), crc1, group, crc2, crc3, @@ -205,6 +230,11 @@ int main(int argc, char **argv) memset(¶m, 0, sizeof(param)); ext2fs_blocks_count_set(¶m, 32768); +#if 0 + param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT; + param.s_desc_size = 128; + csum_known = 0x5b6e; +#endif retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, test_io_manager, &fs); -- 1.8.3.1