journal.c (clear_v2_journal_fields, e2fsck_journal_load): If the

V2 fields are set on a V1 journal superblock, or an
	internal V2 journal has s_nr_users is non-zero, clear the
	entire journal superblock beyond the V1 superblock.  This
	fixes botched V1->V2 updates.

problem.c, problem.h (PR_0_CLEAR_V2_JOURNAL): Add new problem code.

f_bad_local_jnl: New test which tests for a V2 journal with bad 
	fields caused by a botched V1->V2 upgrade.
Theodore Ts'o 2001-10-07 02:13:30 -04:00
parent 773fd8a1d4
commit 62e3e7fe4f
9 changed files with 68 additions and 0 deletions

View File

@ -1,3 +1,13 @@
2001-10-07 Theodore Tso <tytso@valinux.com>
* journal.c (clear_v2_journal_fields, e2fsck_journal_load): If the
V2 fields are set on a V1 journal superblock, or an
internal V2 journal has s_nr_users is non-zero, clear the
entire journal superblock beyond the V1 superblock. This
fixes botched V1->V2 updates.
* problem.c, problem.h (PR_0_CLEAR_V2_JOURNAL): Add new problem code.
2001-09-20 Theodore Tso <tytso@valinux.com>
* e2fsck.h, journal.c (e2fsck_move_ext3_journal): Add new function

View File

@ -351,6 +351,24 @@ static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
return 0;
}
#define V1_SB_SIZE 0x0024
static void clear_v2_journal_fields(journal_t *journal)
{
e2fsck_t ctx = journal->j_dev;
struct buffer_head *jbh = journal->j_sb_buffer;
struct problem_context pctx;
clear_problem_context(&pctx);
if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
return;
memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
ctx->fs->blocksize-V1_SB_SIZE);
mark_buffer_dirty(journal->j_sb_buffer, 1);
}
static errcode_t e2fsck_journal_load(journal_t *journal)
{
e2fsck_t ctx = journal->j_dev;
@ -375,10 +393,18 @@ static errcode_t e2fsck_journal_load(journal_t *journal)
switch (ntohl(jsb->s_header.h_blocktype)) {
case JFS_SUPERBLOCK_V1:
journal->j_format_version = 1;
if (jsb->s_feature_compat ||
jsb->s_feature_incompat ||
jsb->s_feature_ro_compat ||
jsb->s_nr_users)
clear_v2_journal_fields(journal);
break;
case JFS_SUPERBLOCK_V2:
journal->j_format_version = 2;
if (jsb->s_nr_users &&
(ctx->fs->io == ctx->journal_io))
clear_v2_journal_fields(journal);
if (ntohl(jsb->s_nr_users) > 1) {
fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
return EXT2_ET_JOURNAL_UNSUPP_VERSION;

View File

@ -287,6 +287,12 @@ static const struct e2fsck_problem problem_table[] = {
N_("Error moving @j: %m\n\n"),
PROMPT_NONE, 0 },
/* Clearing V2 journal superblock */
{ PR_0_CLEAR_V2_JOURNAL,
N_("Found invalid V2 @j @S fields (from V1 journal).\n"
"Clearing fields beyond the V1 @j @S...\n\n"),
PROMPT_NONE, 0 },
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */

View File

@ -161,6 +161,9 @@ struct problem_context {
/* Error moving journal */
#define PR_0_ERR_MOVE_JOURNAL 0x000029
/* Clearing V2 journal superblock */
#define PR_0_CLEAR_V2_JOURNAL 0x00002A
/*
* Pass 1 errors
*/

View File

@ -1,3 +1,8 @@
2001-10-07 Theodore Tso <tytso@valinux.com>
* f_bad_local_jnl: New test which tests for a V2 journal with bad
fields caused by a botched V1->V2 upgrade.
2001-09-20 Theodore Tso <tytso@thunk.org>
* Release of E2fsprogs 1.25

View File

@ -0,0 +1,10 @@
Found invalid V2 journal superblock fields (from V1 journal).
Clearing fields beyond the V1 journal superblock...
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/256 files (0.0% non-contiguous), 1080/8192 blocks
Exit status is 0

View File

@ -0,0 +1,7 @@
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/256 files (0.0% non-contiguous), 1080/8192 blocks
Exit status is 0

Binary file not shown.

View File

@ -0,0 +1 @@
test for corrupt local journal (bad V1->V2 journal upgrade)