Whamcloud - gitweb
libext2fs: record the checksum algorithm in use in the superblock
authorDarrick J. Wong <djwong@us.ibm.com>
Fri, 3 Aug 2012 00:47:44 +0000 (20:47 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 3 Aug 2012 00:47:44 +0000 (20:47 -0400)
Record the type of checksum algorithm we're using for metadata in the
superblock, in case we ever want/need to change the algorithm.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debugfs/set_fields.c
lib/e2p/ls.c
lib/ext2fs/csum.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h
lib/ext2fs/openfs.c

index a42faa2..4126e7b 100644 (file)
@@ -151,6 +151,7 @@ static struct field_set_info super_fields[] = {
        { "grp_quota_inum", &set_sb.s_grp_quota_inum, NULL, 4, parse_uint },
        { "overhead_blocks", &set_sb.s_overhead_blocks, NULL, 4, parse_uint },
        { "checksum", &set_sb.s_checksum, NULL, 4, parse_uint },
+       { "checksum_type", &set_sb.s_checksum_type, NULL, 1, parse_uint },
        { 0, 0, 0, 0 }
 };
 
index f05e16d..d2e84eb 100644 (file)
@@ -196,6 +196,16 @@ static __u64 e2p_free_blocks_count(struct ext2_super_block *super)
 #define EXT2_GOOD_OLD_REV 0
 #endif
 
+static const char *checksum_type(__u8 type)
+{
+       switch (type) {
+       case EXT2_CRC32C_CHKSUM:
+               return "crc32c";
+       default:
+               return "unknown";
+       }
+}
+
 void list_super2(struct ext2_super_block * sb, FILE *f)
 {
        int inode_blocks_per_group;
@@ -421,9 +431,12 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
                fprintf(f, "Group quota inode:        %u\n",
                        sb->s_grp_quota_inum);
 
-       if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
+       if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
+               fprintf(f, "Checksum type:            %s\n",
+                       checksum_type(sb->s_checksum_type));
                fprintf(f, "Checksum:                 0x%08x\n",
                        sb->s_checksum);
+       }
 }
 
 void list_super (struct ext2_super_block * s)
index 4cb242b..e276c5d 100644 (file)
 #define STATIC static
 #endif
 
+int ext2fs_verify_csum_type(ext2_filsys fs, struct ext2_super_block *sb)
+{
+       if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+               return 1;
+
+       return sb->s_checksum_type == EXT2_CRC32C_CHKSUM;
+}
+
 static __u32 ext2fs_superblock_csum(ext2_filsys fs, struct ext2_super_block *sb)
 {
        int offset = offsetof(struct ext2_super_block, s_checksum);
index 0580865..cb63689 100644 (file)
@@ -467,4 +467,7 @@ ec  EXT2_ET_EXT_ATTR_CSUM_INVALID,
 ec     EXT2_ET_SB_CSUM_INVALID,
        "Superblock checksum does not match superblock"
 
+ec     EXT2_ET_UNKNOWN_CSUM,
+       "Unknown checksum algorithm"
+
        end
index a6fc7f3..383e049 100644 (file)
@@ -943,6 +943,7 @@ extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
 extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
 
 /* csum.c */
+extern int ext2fs_verify_csum_type(ext2_filsys fs, struct ext2_super_block *sb);
 extern errcode_t ext2fs_superblock_csum_set(ext2_filsys fs,
                                            struct ext2_super_block *sb);
 extern int ext2fs_superblock_csum_verify(ext2_filsys fs,
index 2a5c235..48c951d 100644 (file)
@@ -195,10 +195,14 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
        if (fs->orig_super)
                memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);
 
-       if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&
-           !ext2fs_superblock_csum_verify(fs, fs->super)) {
-               retval = EXT2_ET_SB_CSUM_INVALID;
-               goto cleanup;
+       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