if (fs->orig_super)
memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);
+ if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)) {
+ retval = 0;
+ if (!ext2fs_verify_csum_type(fs, fs->super))
+ retval = EXT2_ET_UNKNOWN_CSUM;
+ if (!ext2fs_superblock_csum_verify(fs, fs->super))
+ retval = EXT2_ET_SB_CSUM_INVALID;
+ if (retval)
+ goto cleanup;
+ }
+
#ifdef WORDS_BIGENDIAN
fs->flags |= EXT2_FLAG_SWAP_BYTES;
ext2fs_swap_super(fs->super);
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
+
+ /* Enforce the block group descriptor size */
+ if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) {
+ if (fs->super->s_desc_size < EXT2_MIN_DESC_SIZE_64BIT) {
+ retval = EXT2_ET_BAD_DESC_SIZE;
+ goto cleanup;
+ }
+ } else {
+ if (fs->super->s_desc_size &&
+ fs->super->s_desc_size != EXT2_MIN_DESC_SIZE) {
+ retval = EXT2_ET_BAD_DESC_SIZE;
+ goto cleanup;
+ }
+ }
+
fs->cluster_ratio_bits = fs->super->s_log_cluster_size -
fs->super->s_log_block_size;
if (EXT2_BLOCKS_PER_GROUP(fs->super) !=
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
+ /* Precompute the FS UUID to seed other checksums */
+ ext2fs_init_csum_seed(fs);
/*
* Read group descriptors
* If recovery is from backup superblock, Clear _UNININT flags &
* reset bg_itable_unused to zero
*/
- if (superblock > 1 && EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ if (superblock > 1 && ext2fs_has_group_desc_csum(fs)) {
dgrp_t group;
for (group = 0; group < fs->group_desc_count; group++) {