}
memcpy(&jsuper, start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET,
sizeof(jsuper));
- brelse(bh);
#ifdef WORDS_BIGENDIAN
if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
ext2fs_swap_super(&jsuper);
!(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
retval = EXT2_ET_LOAD_EXT_JOURNAL;
+ brelse(bh);
goto errout;
}
/* Make sure the journal UUID is correct */
sizeof(jsuper.s_uuid))) {
fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
retval = EXT2_ET_LOAD_EXT_JOURNAL;
+ brelse(bh);
goto errout;
}
+ /* Check the superblock checksum */
+ if (jsuper.s_feature_ro_compat &
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
+ struct struct_ext2_filsys fsx;
+ struct ext2_super_block superx;
+ void *p;
+
+ p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET;
+ memcpy(&fsx, ctx->fs, sizeof(fsx));
+ memcpy(&superx, ctx->fs->super, sizeof(superx));
+ fsx.super = &superx;
+ fsx.super->s_feature_ro_compat |=
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
+ if (!ext2fs_superblock_csum_verify(&fsx, p) &&
+ fix_problem(ctx, PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
+ &pctx)) {
+ ext2fs_superblock_csum_set(&fsx, p);
+ mark_buffer_dirty(bh);
+ }
+ }
+ brelse(bh);
+
maxlen = ext2fs_blocks_count(&jsuper);
journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1;
start++;
N_("First_meta_bg is too big. (%N, max value %g). "),
PROMPT_CLEAR, 0 },
+ /* External journal has corrupt superblock */
+ { PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
+ N_("External @j @S checksum does not match @S. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */
/* The first_meta_bg is too big */
#define PR_0_FIRST_META_BG_TOO_BIG 0x000049
+/* External journal has corrupt superblock */
+#define PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID 0x00004A
+
/*
* Pass 1 errors
*/
--- /dev/null
+External journal does not support this filesystem
+
+test_filesys: ********** WARNING: Filesystem still has errors **********
+
+Exit status is 12
--- /dev/null
+corrupt external journal fs superblock block (metadata_csum)
--- /dev/null
+FSCK_OPT=-fy
+OUT=$test_name.log
+if [ -f $test_dir/expect.gz ]; then
+ EXP=$test_name.tmp
+ gunzip < $test_dir/expect.gz > $EXP1
+else
+ EXP=$test_dir/expect
+fi
+
+cp /dev/null $OUT
+
+bzip2 -dc < $test_dir/image.tar.bz2 | tar x
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img "$JOURNAL_DUMP_DIR/$test_name.img"
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img.jnl "$JOURNAL_DUMP_DIR/$test_name.img.jnl"
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm -f $TMPFILE $test_name.img $test_name.img.jnl
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+ rm -f $test_name.tmp
+fi
+
+unset IMAGE FSCK_OPT OUT EXP
--- /dev/null
+External journal superblock checksum does not match superblock. Fix? yes
+
+test_filesys: recovering journal
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Block bitmap differences: +(1--31) +34 +(50--82)
+Fix? yes
+
+Inode bitmap differences: +(1--11)
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/128 files (0.0% non-contiguous), 66/2048 blocks
+Exit status is 1
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/128 files (0.0% non-contiguous), 66/2048 blocks
+Exit status is 0
--- /dev/null
+corrupt external journal fs superblock csum (metadata_csum)
--- /dev/null
+FSCK_OPT=-fy
+OUT=$test_name.log
+if [ -f $test_dir/expect.gz ]; then
+ EXP=$test_name.tmp
+ gunzip < $test_dir/expect.gz > $EXP1
+else
+ EXP=$test_dir/expect
+fi
+
+cp /dev/null $OUT
+
+bzip2 -dc < $test_dir/image.tar.bz2 | tar x
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img "$JOURNAL_DUMP_DIR/$test_name.img"
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img.jnl "$JOURNAL_DUMP_DIR/$test_name.img.jnl"
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm -f $TMPFILE $test_name.img $test_name.img.jnl
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+ rm -f $test_name.tmp
+fi
+
+unset IMAGE FSCK_OPT OUT EXP