Whamcloud - gitweb
e2fsck: Fix superblock times in the future even if buggy_init_scripts=1
authorTheodore Ts'o <tytso@mit.edu>
Fri, 17 Jul 2009 03:44:50 +0000 (23:44 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 17 Jul 2009 03:44:50 +0000 (23:44 -0400)
Unfortunately, distributions like Ubuntu seem to have buggy init
scripts that run e2fsck and mount the root filesystem before making
sure the system time and time zone is correctly set.  As a result, a
filesystem's last write and last mounted time can be set in future.
The buggy_init_scripts configuration option will stop e2fsck from
aborting the boot process, but it also inhibits the superblock times
from getting fixed.  This causes resize2fs to refuse to resize the
filesystem, even after running e2fsck on the file system.  To deal
with this, we need to fix the superblock write times unconditionally.

Addresses-Launchpad-bug: #373409

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/problem.c
e2fsck/problem.h
e2fsck/super.c

index 43a0aa6..d6b345c 100644 (file)
@@ -335,12 +335,12 @@ static struct e2fsck_problem problem_table[] = {
        /* Last mount time is in the future */
        { PR_0_FUTURE_SB_LAST_MOUNT,
          N_("@S last mount time is in the future.  "),
-         PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
+         PROMPT_FIX, PR_NO_OK },
 
        /* Last write time is in the future */
        { PR_0_FUTURE_SB_LAST_WRITE,
          N_("@S last write time is in the future.  "),
-         PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
+         PROMPT_FIX, PR_NO_OK },
 
        { PR_0_EXTERNAL_JOURNAL_HINT,
          N_("@S hint for external superblock @s %X.  "),
@@ -385,6 +385,18 @@ static struct e2fsck_problem problem_table[] = {
          N_("The test_fs flag is set (and ext4 is available).  "),
          PROMPT_CLEAR, PR_PREEN_OK },
 
+       /* Last mount time is in the future (fudged) */
+       { PR_0_FUTURE_SB_LAST_MOUNT_FUDGED,
+         N_("@S last mount time is in the future.\n\t(by less than a day, "
+            "probably due to buggy init scripts)  "),
+         PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
+
+       /* Last write time is in the future (fudged) */
+       { PR_0_FUTURE_SB_LAST_WRITE_FUDGED,
+         N_("@S last write time is in the future.\n\t(by less than a day, "
+            "probably due to buggy init scripts).  "),
+         PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
+
        /* Pass 1 errors */
 
        /* Pass 1: Checking inodes, blocks, and sizes */
index 1d2c233..69dcfba 100644 (file)
@@ -217,6 +217,13 @@ struct problem_context {
 /* The test_fs filesystem flag is set and ext4 is available */
 #define PR_0_CLEAR_TESTFS_FLAG                 0x00003B
 
+/* Last mount time is in the future (fudged) */
+#define PR_0_FUTURE_SB_LAST_MOUNT_FUDGED       0x00003C
+
+/* Last write time is in the future (fudged) */
+#define PR_0_FUTURE_SB_LAST_WRITE_FUDGED       0x00003D
+
+
 /*
  * Pass 1 errors
  */
index 344777d..ef29aa5 100644 (file)
@@ -457,6 +457,7 @@ void check_super_block(e2fsck_t ctx)
        blk_t   first_block, last_block;
        struct ext2_super_block *sb = fs->super;
        struct ext2_group_desc *gd;
+       problem_t       problem;
        blk_t   blocks_per_group = fs->super->s_blocks_per_group;
        blk_t   bpg_max;
        int     inodes_per_block;
@@ -818,16 +819,22 @@ void check_super_block(e2fsck_t ctx)
         * Check to see if the superblock last mount time or last
         * write time is in the future.
         */
-       if (fs->super->s_mtime > (__u32) ctx->now + ctx->time_fudge) {
+       if (fs->super->s_mtime > (__u32) ctx->now) {
                pctx.num = fs->super->s_mtime;
-               if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_MOUNT, &pctx)) {
+               problem = PR_0_FUTURE_SB_LAST_MOUNT;
+               if (fs->super->s_mtime <= (__u32) ctx->now + ctx->time_fudge)
+                       problem = PR_0_FUTURE_SB_LAST_MOUNT_FUDGED;
+               if (fix_problem(ctx, problem, &pctx)) {
                        fs->super->s_mtime = ctx->now;
                        ext2fs_mark_super_dirty(fs);
                }
        }
-       if (fs->super->s_wtime > (__u32) ctx->now + ctx->time_fudge) {
+       if (fs->super->s_wtime > (__u32) ctx->now) {
                pctx.num = fs->super->s_wtime;
-               if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_WRITE, &pctx)) {
+               problem = PR_0_FUTURE_SB_LAST_MOUNT;
+               if (fs->super->s_wtime <= (__u32) ctx->now + ctx->time_fudge)
+                       problem = PR_0_FUTURE_SB_LAST_MOUNT_FUDGED;
+               if (fix_problem(ctx, problem, &pctx)) {
                        fs->super->s_wtime = ctx->now;
                        ext2fs_mark_super_dirty(fs);
                }