From 8dceb92407f751d1a8aecd4bfb36d1fe2dc3cf9a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 24 Sep 2005 21:59:45 -0400 Subject: [PATCH] E2fsck: fix future times in the superblock's last mount or last write fields Detect if the superblock's last mount field or last write field is in the future, and offer to fix if so. (Addresses Debian Bug #327580) Signed-off-by: "Theodore Ts'o" --- e2fsck/ChangeLog | 7 +++++++ e2fsck/journal.c | 1 + e2fsck/problem.c | 10 ++++++++++ e2fsck/problem.h | 6 ++++++ e2fsck/super.c | 19 +++++++++++++++++++ e2fsck/unix.c | 1 + tests/ChangeLog | 6 ++++++ tests/f_dup_resize/script | 1 + 8 files changed, 51 insertions(+) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index deec7eab..b7da9b6d 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,10 @@ +2005-09-24 Theodore Ts'o + + * super.c (check_super_block), problem.c, problem.h: Detect if the + superblock's last mount field or last write field is in + the future, and offer to fix if so. (Addresses Debian Bug + #327580) + 2005-07-25 Theodore Ts'o * unix.c (main): Fix a use-after-free bug of the e2fsck context diff --git a/e2fsck/journal.c b/e2fsck/journal.c index a5f156c5..0a53cc7a 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -827,6 +827,7 @@ int e2fsck_run_ext3_journal(e2fsck_t ctx) fatal_error(ctx, 0); } ctx->fs->priv_data = ctx; + ctx->fs->now = ctx->now; /* Set the superblock flags */ e2fsck_clear_recover(ctx, recover_retval); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index c2e50760..357bd8db 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -332,6 +332,16 @@ static const struct e2fsck_problem problem_table[] = { N_("Resize @i not valid. "), PROMPT_RECREATE, 0 }, + /* Last mount time is in the future */ + { PR_0_FUTURE_SB_LAST_MOUNT, + N_("@S last mount time is in the future. "), + PROMPT_FIX, 0 }, + + /* Last write time is in the future */ + { PR_0_FUTURE_SB_LAST_WRITE, + N_("@S last write time is in the future. "), + PROMPT_FIX, 0 }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 0e39a293..9614d1cc 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -184,6 +184,12 @@ struct problem_context { /* Resize inode invalid */ #define PR_0_RESIZE_INODE_INVALID 0x000030 +/* Last mount time is in the future */ +#define PR_0_FUTURE_SB_LAST_MOUNT 0x000031 + +/* Last write time is in the future */ +#define PR_0_FUTURE_SB_LAST_WRITE 0x000032 + /* * Pass 1 errors */ diff --git a/e2fsck/super.c b/e2fsck/super.c index 0855fb54..d886bbd1 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -705,6 +705,25 @@ void check_super_block(e2fsck_t ctx) ext2fs_mark_super_dirty(fs); } + /* + * Check to see if the superblock last mount time or last + * write time is in the future. + */ + if (fs->super->s_mtime > ctx->now) { + pctx.num = fs->super->s_mtime; + if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_MOUNT, &pctx)) { + fs->super->s_mtime = ctx->now; + ext2fs_mark_super_dirty(fs); + } + } + if (fs->super->s_wtime > ctx->now) { + pctx.num = fs->super->s_wtime; + if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_WRITE, &pctx)) { + fs->super->s_wtime = ctx->now; + ext2fs_mark_super_dirty(fs); + } + } + /* * Move the ext3 journal file, if necessary. */ diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 6cbcb10c..5f1aaa23 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -943,6 +943,7 @@ restart: } ctx->fs = fs; fs->priv_data = ctx; + fs->now = ctx->now; sb = fs->super; if (sb->s_rev_level > E2FSCK_CURRENT_REV) { com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH, diff --git a/tests/ChangeLog b/tests/ChangeLog index a3522c2b..2c2813bf 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2005-09-24 Theodore Ts'o + + * f_dup_resize: Set the current time to in debugfs to a value + which avoids triggering the "s_mtime in the future" + warning from e2fsck. + 2005-08-08 Theodore Ts'o * test_config, test_script.in, d_loaddump, f_dup_resize, diff --git a/tests/f_dup_resize/script b/tests/f_dup_resize/script index ed374feb..7a5214c0 100644 --- a/tests/f_dup_resize/script +++ b/tests/f_dup_resize/script @@ -9,6 +9,7 @@ $DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1 freeb 4 4 freeb 8195 4 write $TEST_DATA debugfs +set_current_time 200504110000 set_inode_field debugfs mtime 200504110000 q EOF