diff options
Diffstat (limited to 'lib/ext2fs/csum.c')
-rw-r--r-- | lib/ext2fs/csum.c | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index 9fa3f24f..669f8068 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -32,27 +32,23 @@ __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) { + struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, + group); + size_t size = EXT2_DESC_SIZE(fs->super); __u16 crc = 0; - struct ext2_group_desc *desc; - size_t size; - - size = fs->super->s_desc_size; - if (size < EXT2_MIN_DESC_SIZE) - size = EXT2_MIN_DESC_SIZE; - if (size > sizeof(struct ext4_group_desc)) { - printf("%s: illegal s_desc_size(%zd)\n", __func__, size); - size = sizeof(struct ext4_group_desc); - } - - desc = ext2fs_group_desc(fs, fs->group_desc, group); if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { size_t offset = offsetof(struct ext2_group_desc, bg_checksum); #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); @@ -70,6 +66,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; @@ -166,21 +173,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 = ext2fs_group_desc(fs, fs->group_desc, group); - 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 - size = fs->super->s_desc_size; - if (size < EXT2_MIN_DESC_SIZE) - size = EXT2_MIN_DESC_SIZE; - if (size > sizeof(struct ext4_group_desc)) - size = sizeof(struct ext4_group_desc); #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; @@ -197,8 +205,13 @@ 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", + printf("%s UUID %s=%04x, grp %u=%04x: %04x=%04x\n", msg, e2p_uuid2str(sb->s_uuid), crc1, group, crc2, crc3, ext2fs_group_desc_csum(fs, group)); } @@ -216,6 +229,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); |