]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: store checksum seed in superblock
authorDarrick J. Wong <darrick.wong@oracle.com>
Sat, 13 Feb 2016 22:37:32 +0000 (14:37 -0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 7 Mar 2016 01:08:52 +0000 (20:08 -0500)
Allow the filesystem to store the metadata checksum seed in the
superblock and add an incompat feature to say that we're using it.
This enables tune2fs to change the UUID on a mounted metadata_csum
FS without having to (racy!) rewrite all disk metadata.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debugfs/set_fields.c
lib/e2p/feature.c
lib/e2p/ls.c
lib/ext2fs/csum.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h
lib/ext2fs/swapfs.c
lib/ext2fs/tst_super_size.c
tests/f_create_symlinks/script

index 973afa788a9888ad7141b22224601a0726c4bf15..458bc472814d61e6aa41fc717906ae9d331932e5 100644 (file)
@@ -175,6 +175,7 @@ static struct field_set_info super_fields[] = {
          FLAG_ARRAY, 4 },
        { "encrypt_pw_salt", &set_sb.s_encrypt_pw_salt, NULL, 16, parse_uuid },
        { "lpf_ino", &set_sb.s_lpf_ino, NULL, 4, parse_uint },
+       { "checksum_seed", &set_sb.s_checksum_seed, NULL, 4, parse_uint },
        { 0, 0, 0, 0 }
 };
 
index 17d2ad07d89b0ca16c96bf0bbb3e7e9484bb919a..b7f6c1d26fe699ac149d0d2c4b95d60ddbbe12df 100644 (file)
@@ -97,6 +97,8 @@ static struct feature feature_list[] = {
                        "ea_inode"},
        {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_DIRDATA,
                        "dirdata"},
+       {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+                       "metadata_csum_seed"},
        {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_LARGEDIR,
                        "large_dir"},
        {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INLINE_DATA,
index 6f5eff64c26277a8c966211bb4805c00ac0da9d6..a7586e094da1a0438515560b6d2b308f371324eb 100644 (file)
@@ -466,6 +466,10 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
        if (!e2p_is_null_uuid(sb->s_encrypt_pw_salt))
                fprintf(f, "Encryption PW Salt:       %s\n",
                        e2p_uuid2str(sb->s_encrypt_pw_salt));
+
+       if (ext2fs_has_feature_csum_seed(sb))
+               fprintf(f, "Checksum seed:            0x%08x\n",
+                       sb->s_checksum_seed);
 }
 
 void list_super (struct ext2_super_block * s)
index ab8b83fb5e30b711e71a77161075bc8318e5e666..ccb30578e70a70f6c2cbe4f979dd39c987eaecba 100644 (file)
 #define STATIC static
 #endif
 
+void ext2fs_init_csum_seed(ext2_filsys fs)
+{
+       if (ext2fs_has_feature_csum_seed(fs->super))
+               fs->csum_seed = fs->super->s_checksum_seed;
+       else if (ext2fs_has_feature_metadata_csum(fs->super))
+               fs->csum_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid,
+                                                sizeof(fs->super->s_uuid));
+}
+
 static __u32 ext2fs_mmp_csum(ext2_filsys fs, struct mmp_struct *mmp)
 {
        int offset = offsetof(struct mmp_struct, mmp_checksum);
index d16dd80228afe9ad0d6f084e9856cc98d636ef93..cdb68e8a75bda624a28eccdb79f7eedaff644b05 100644 (file)
@@ -727,7 +727,8 @@ struct ext2_super_block {
        __u8    s_encrypt_pw_salt[16];  /* Salt used for string2key algorithm */
        __le32  s_lpf_ino;              /* Location of the lost+found inode */
        __le32  s_prj_quota_inum;       /* inode for tracking project quota */
-       __le32  s_reserved[99];         /* Padding to the end of the block */
+       __le32  s_checksum_seed;        /* crc32c(orig_uuid) if csum_seed set */
+       __le32  s_reserved[98];         /* Padding to the end of the block */
        __u32   s_checksum;             /* crc32c(superblock) */
 };
 
@@ -813,7 +814,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
-/* 0x2000 was EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM but this was never used */
+#define EXT4_FEATURE_INCOMPAT_CSUM_SEED                0x2000
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR         0x4000 /* >2GB or 3-lvl htree */
 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA      0x8000 /* data in inode */
 #define EXT4_FEATURE_INCOMPAT_ENCRYPT          0x10000
@@ -904,6 +905,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(mmp,            4, MMP)
 EXT4_FEATURE_INCOMPAT_FUNCS(flex_bg,           4, FLEX_BG)
 EXT4_FEATURE_INCOMPAT_FUNCS(ea_inode,          4, EA_INODE)
 EXT4_FEATURE_INCOMPAT_FUNCS(dirdata,           4, DIRDATA)
+EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed,         4, CSUM_SEED)
 EXT4_FEATURE_INCOMPAT_FUNCS(largedir,          4, LARGEDIR)
 EXT4_FEATURE_INCOMPAT_FUNCS(inline_data,       4, INLINE_DATA)
 EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,           4, ENCRYPT)
index f6fed2c41f5ef4c524c97d4be2c7d519a07b1b4e..c98355db38e00980cc1f77eb137072b2a4043239 100644 (file)
@@ -580,7 +580,8 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT4_LIB_INCOMPAT_MMP|\
                                         EXT4_FEATURE_INCOMPAT_64BIT|\
                                         EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
-                                        EXT4_FEATURE_INCOMPAT_ENCRYPT)
+                                        EXT4_FEATURE_INCOMPAT_ENCRYPT|\
+                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED)
 
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
                                         EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
@@ -986,6 +987,7 @@ extern __u32 ext2fs_crc32_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 void ext2fs_init_csum_seed(ext2_filsys fs);
 extern errcode_t ext2fs_mmp_csum_set(ext2_filsys fs, struct mmp_struct *mmp);
 extern int ext2fs_mmp_csum_verify(ext2_filsys, struct mmp_struct *mmp);
 extern int ext2fs_verify_csum_type(ext2_filsys fs, struct ext2_super_block *sb);
@@ -1713,15 +1715,6 @@ extern void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type);
 #endif /* __STDC_VERSION__ >= 199901L */
 #endif
 
-static inline void ext2fs_init_csum_seed(ext2_filsys fs)
-{
-       if (!ext2fs_has_feature_metadata_csum(fs->super))
-               return;
-
-       fs->csum_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid,
-                                        sizeof(fs->super->s_uuid));
-}
-
 #ifndef EXT2_CUSTOM_MEMORY_ROUTINES
 #include <string.h>
 /*
index 18535e5b42f3b78d9f4f1eefd3ef36f8cb130477..5d23fb352dde18deac32b4ad60111344cf3d706f 100644 (file)
@@ -101,6 +101,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
                sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
        sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]);
        sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]);
+       sb->s_checksum_seed = ext2fs_swab32(sb->s_checksum_seed);
 }
 
 void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
index 9b25cce8af2a91d3c2d58cf8e01b162768b839bc..0adac41106156b31d57e9adbb9249ab080458516 100644 (file)
@@ -141,7 +141,8 @@ int main(int argc, char **argv)
        check_field(s_encrypt_pw_salt, 16);
        check_field(s_lpf_ino, 4);
        check_field(s_prj_quota_inum, 4);
-       check_field(s_reserved, 99 * 4);
+       check_field(s_checksum_seed, 4);
+       check_field(s_reserved, 98 * 4);
        check_field(s_checksum, 4);
        do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
index 529848f2604129010c626bca109271befaa8b891..779d92ede05f8e8c3a63946bfb3d3b135d072b9b 100644 (file)
@@ -35,8 +35,6 @@ for i in 30 70 500 1023 1024 1500; do
                 sed -f $cmd_dir/filter.sed | grep -v "time: " >> $OUT
 done
 
-/bin/cp $TMPFILE /tmp/foo.img
-
 $FSCK $FSCK_OPT  -N test_filesys $TMPFILE > $OUT.new 2>&1
 status=$?
 echo Exit status is $status >> $OUT.new