summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-07-16 23:44:50 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-07-16 23:44:50 -0400
commit26ea4899d1fea0fbc5d28120944d2c2758ac1b11 (patch)
tree506bb855d7bd3bb7960d62ad2bde27380c4141d0
parent25c7e0c3042cb92a71d25cb3c2709a55b9f120a6 (diff)
downloade2fsprogs-26ea4899d1fea0fbc5d28120944d2c2758ac1b11.tar.gz
e2fsck: Fix superblock times in the future even if buggy_init_scripts=1
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>
-rw-r--r--e2fsck/problem.c16
-rw-r--r--e2fsck/problem.h7
-rw-r--r--e2fsck/super.c15
3 files changed, 32 insertions, 6 deletions
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 43a0aa64..d6b345cf 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -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 */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 1d2c2334..69dcfba7 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -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
*/
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 344777d4..ef29aa52 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -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);
}