__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);
+ size_t offset;
__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)) {
- /* This should never happen, but cap it for safety's sake */
- size = sizeof(struct ext4_group_desc);
- }
-
- desc = ext2fs_group_desc(fs, fs->group_desc, 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);
+ ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc);
desc = (struct ext2_group_desc *) &swabdesc;
-
group = ext2fs_swab32(group);
#endif
crc32 = ext2fs_crc32c_le(crc32, (unsigned char *)desc,
size);
desc->bg_checksum = old_crc;
-
+#ifdef WORDS_BIGENDIAN
+ if (save_size > ext4_bg_size)
+ crc32 = ext2fs_crc32c_le(crc32,
+ (char *)save_desc + ext4_bg_size,
+ save_size - ext4_bg_size);
+#endif
crc = crc32 & 0xFFFF;
goto out;
}
/* old crc16 code */
- size_t offset = offsetof(struct ext2_group_desc, bg_checksum);
+ offset = offsetof(struct ext2_group_desc, bg_checksum);
crc = ext2fs_crc16(~0, fs->super->s_uuid,
sizeof(fs->super->s_uuid));
crc = ext2fs_crc16(crc, &group, sizeof(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
out:
return crc;
{
__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 = 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;
/* 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,
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);