Whamcloud - gitweb
journal.c (clear_v2_journal_fields, e2fsck_journal_load): If the
authorTheodore Ts'o <tytso@mit.edu>
Sun, 7 Oct 2001 06:13:30 +0000 (02:13 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 7 Oct 2001 06:13:30 +0000 (02:13 -0400)
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.

e2fsck/ChangeLog
e2fsck/journal.c
e2fsck/problem.c
e2fsck/problem.h
tests/ChangeLog
tests/f_bad_local_jnl/expect.1 [new file with mode: 0644]
tests/f_bad_local_jnl/expect.2 [new file with mode: 0644]
tests/f_bad_local_jnl/image.gz [new file with mode: 0644]
tests/f_bad_local_jnl/name [new file with mode: 0644]

index ad944da..629b012 100644 (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
index 0bff025..62d4812 100644 (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;
index 34f4f30..58b8724 100644 (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 */
index e7ddf76..6a234b7 100644 (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
  */
index 9b0e810..2fd5c6c 100644 (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
diff --git a/tests/f_bad_local_jnl/expect.1 b/tests/f_bad_local_jnl/expect.1
new file mode 100644 (file)
index 0000000..d8f6551
--- /dev/null
@@ -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
diff --git a/tests/f_bad_local_jnl/expect.2 b/tests/f_bad_local_jnl/expect.2
new file mode 100644 (file)
index 0000000..632dc71
--- /dev/null
@@ -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
diff --git a/tests/f_bad_local_jnl/image.gz b/tests/f_bad_local_jnl/image.gz
new file mode 100644 (file)
index 0000000..addd58a
Binary files /dev/null and b/tests/f_bad_local_jnl/image.gz differ
diff --git a/tests/f_bad_local_jnl/name b/tests/f_bad_local_jnl/name
new file mode 100644 (file)
index 0000000..8b77264
--- /dev/null
@@ -0,0 +1 @@
+test for corrupt local journal (bad V1->V2 journal upgrade)