aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-02-13 14:37:32 -0800
committerTheodore Ts'o <tytso@mit.edu>2016-03-06 20:08:52 -0500
commit2ed0adbce68c0bbe7e1fc2cf23f009327f10441b (patch)
tree39ca23c76f942a0f395559c8f7a7107aa2a9382d
parentf3d9ac36a021aab3d84ef7759790839f9a65a1bf (diff)
downloade2fsprogs-2ed0adbce68c0bbe7e1fc2cf23f009327f10441b.tar.gz
libext2fs: store checksum seed in superblock
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>
-rw-r--r--debugfs/set_fields.c1
-rw-r--r--lib/e2p/feature.c2
-rw-r--r--lib/e2p/ls.c4
-rw-r--r--lib/ext2fs/csum.c9
-rw-r--r--lib/ext2fs/ext2_fs.h6
-rw-r--r--lib/ext2fs/ext2fs.h13
-rw-r--r--lib/ext2fs/swapfs.c1
-rw-r--r--lib/ext2fs/tst_super_size.c3
-rw-r--r--tests/f_create_symlinks/script2
9 files changed, 26 insertions, 15 deletions
diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index 973afa78..458bc472 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -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 }
};
diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index 17d2ad07..b7f6c1d2 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -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,
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 6f5eff64..a7586e09 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -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)
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index ab8b83fb..ccb30578 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -30,6 +30,15 @@
#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);
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index d16dd802..cdb68e8a 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -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)
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index f6fed2c4..c98355db 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -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>
/*
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 18535e5b..5d23fb35 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -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)
diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c
index 9b25cce8..0adac411 100644
--- a/lib/ext2fs/tst_super_size.c
+++ b/lib/ext2fs/tst_super_size.c
@@ -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
diff --git a/tests/f_create_symlinks/script b/tests/f_create_symlinks/script
index 529848f2..779d92ed 100644
--- a/tests/f_create_symlinks/script
+++ b/tests/f_create_symlinks/script
@@ -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