diff options
author | Theodore Ts'o <tytso@mit.edu> | 2001-10-07 02:13:30 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2001-10-07 02:13:30 -0400 |
commit | 62e3e7fe4f32c2186e848f37b7f977835975413e (patch) | |
tree | f8a89e8f421f08b0277cfb2286e1ed1bbd59c832 /e2fsck | |
parent | 773fd8a1d4202af708a37bdc7754134e6fdcfe22 (diff) | |
download | e2fsprogs-62e3e7fe4f32c2186e848f37b7f977835975413e.tar.gz |
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.
Diffstat (limited to 'e2fsck')
-rw-r--r-- | e2fsck/ChangeLog | 10 | ||||
-rw-r--r-- | e2fsck/journal.c | 26 | ||||
-rw-r--r-- | e2fsck/problem.c | 6 | ||||
-rw-r--r-- | e2fsck/problem.h | 3 |
4 files changed, 45 insertions, 0 deletions
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index ad944da0..629b0127 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -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 diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 0bff025a..62d4812f 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -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; diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 34f4f305..58b87244 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -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 */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index e7ddf768..6a234b7f 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -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 */ |