Change the block group algorithm to use the same algorithm as the rest of the metadata_csum, if a certain incompat feature flag is set. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- lib/e2p/feature.c | 2 ++ lib/ext2fs/csum.c | 62 ++++++++++++++++++++++++++++++++++---------------- lib/ext2fs/ext2_fs.h | 1 + lib/ext2fs/ext2fs.h | 6 +++-- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index 63486f3..dc52ba7 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -85,6 +85,8 @@ static struct feature feature_list[] = { "mmp" }, { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG, "flex_bg"}, + { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM, + "bg_use_meta_csum"}, { 0, 0, 0 }, }; diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index 9e4536e..9694185 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -711,32 +711,54 @@ STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) 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; + struct ext4_group_desc swabdesc; - /* Have to swab back to little-endian to do the checksum */ - memcpy(&swabdesc, desc, size); - ext2fs_swap_group_desc2(fs, - (struct ext2_group_desc *) &swabdesc); - desc = (struct ext2_group_desc *) &swabdesc; + /* Have to swab back to little-endian to do the checksum */ + memcpy(&swabdesc, desc, size); + ext2fs_swap_group_desc2(fs, + (struct ext2_group_desc *) &swabdesc); + desc = (struct ext2_group_desc *) &swabdesc; - group = ext2fs_swab32(group); + group = ext2fs_swab32(group); #endif - crc = ext2fs_crc16(~0, fs->super->s_uuid, - sizeof(fs->super->s_uuid)); - crc = ext2fs_crc16(crc, &group, sizeof(group)); - crc = ext2fs_crc16(crc, desc, offset); - offset += sizeof(desc->bg_checksum); /* skip checksum */ - /* for checksum of struct ext4_group_desc do the rest...*/ - if (offset < size) { - crc = ext2fs_crc16(crc, (char *)desc + offset, - size - offset); - } + + if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && + EXT2_HAS_INCOMPAT_FEATURE(fs->super, + EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM)) { + /* new metadata csum code */ + __u16 old_crc; + __u32 crc32; + + old_crc = desc->bg_checksum; + desc->bg_checksum = 0; + crc32 = ext2fs_crc32c_le(~0, fs->super->s_uuid, + sizeof(fs->super->s_uuid)); + crc32 = ext2fs_crc32c_le(crc32, (unsigned char *)&group, + sizeof(group)); + crc32 = ext2fs_crc32c_le(crc32, (unsigned char *)desc, + size); + desc->bg_checksum = old_crc; + + crc = crc32 & 0xFFFF; + goto out; } + /* old crc16 code */ + size_t 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, desc, offset); + offset += sizeof(desc->bg_checksum); /* skip checksum */ + /* for checksum of struct ext4_group_desc do the rest...*/ + if (offset < size) { + crc = ext2fs_crc16(crc, (char *)desc + offset, + size - offset); + } + +out: return crc; } diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index d6cd6e0..709fc2f 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -742,6 +742,7 @@ struct ext2_super_block { #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 #define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 +#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 #define EXT2_FEATURE_COMPAT_SUPP 0 #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 9311336..d4d4ecf 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -567,7 +567,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_MMP|\ - EXT4_FEATURE_INCOMPAT_64BIT) + EXT4_FEATURE_INCOMPAT_64BIT|\ + EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM) #else #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\ @@ -576,7 +577,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_MMP|\ - EXT4_FEATURE_INCOMPAT_64BIT) + EXT4_FEATURE_INCOMPAT_64BIT|\ + EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM) #endif #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\ -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html