aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@dilger.ca>2023-09-26 23:40:16 -0600
committerTheodore Ts'o <tytso@mit.edu>2024-03-31 13:54:33 -0400
commitca8bc9240a00665dd4c96de350e610add8543a08 (patch)
treef4bcab265b4afc14deabf94ebcfc75af0db6e52d
parentf8728c88c089a75abcc8bbfd00e19a050b97eb08 (diff)
downloade2fsprogs-ca8bc9240a00665dd4c96de350e610add8543a08.tar.gz
Add post-2038 timestamp support to e2fsprogs
The ext4 kernel code implemented support for s_mtime_hi, s_wtime_hi, and related timestamp fields to avoid timestamp overflow in 2038, but similar handling is not in e2fsprogs. Add helper macros for the superblock _hi timestamp fields ext2fs_super_tstamp_get() and ext2fs_super_tstamp_set(). Add helper macro for inode _extra timestamp fields ext2fs_inode_xtime_get() and ext2fs_inode_xtime_set(). Add helper macro ext2fs_actual_inode_size() to avoid open coding the i_extra_isize check in multiple places. Remove inode_time_to_string() since this is unused once callers change to time_to_string(ext2fs_inode_xtime_get()) directly. Fix inode_includes() macro to properly wrap "inode" parameter, and rename to ext2fs_inode_includes() to avoid potential name clashes. Use this to check inode field inclusion in debugfs instead of bare constants for inode field offsets. Use these interfaces to access timestamps in debugfs, e2fsck, libext2fs, fuse2fs, tune2fs, and e2undo. Signed-off-by: Andreas Dilger <adilger@dilger.ca> Link: https://lore.kernel.org/r/20230927054016.16645-1-adilger@dilger.ca Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--debugfs/debugfs.c69
-rw-r--r--debugfs/debugfs.h1
-rw-r--r--debugfs/journal.c7
-rw-r--r--debugfs/set_fields.c32
-rw-r--r--debugfs/util.c8
-rw-r--r--e2fsck/message.c2
-rw-r--r--e2fsck/pass1.c16
-rw-r--r--e2fsck/pass3.c8
-rw-r--r--e2fsck/super.c16
-rw-r--r--e2fsck/unix.c2
-rw-r--r--lib/e2p/ls.c28
-rw-r--r--lib/ext2fs/bb_inode.c11
-rw-r--r--lib/ext2fs/closefs.c2
-rw-r--r--lib/ext2fs/ext2_fs.h6
-rw-r--r--lib/ext2fs/ext2fs.h52
-rw-r--r--lib/ext2fs/initialize.c3
-rw-r--r--lib/ext2fs/inode.c18
-rw-r--r--lib/ext2fs/mkjournal.c5
-rw-r--r--lib/ext2fs/orphan.c7
-rw-r--r--lib/ext2fs/res_gdt.c5
-rw-r--r--lib/ext2fs/swapfs.c16
-rw-r--r--lib/support/mkquota.c2
-rw-r--r--lib/support/plausible.c9
-rw-r--r--lib/support/quotaio.c7
-rw-r--r--misc/create_inode.c20
-rw-r--r--misc/e2undo.c6
-rw-r--r--misc/findsuper.c7
-rw-r--r--misc/fuse2fs.c8
-rw-r--r--misc/tune2fs.c6
29 files changed, 232 insertions, 147 deletions
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 9b6321dc4..965511739 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -831,11 +831,13 @@ void internal_dump_inode(FILE *out, const char *prefix,
char frag, fsize;
int os = current_fs->super->s_creator_os;
struct ext2_inode_large *large_inode;
- int is_large_inode = 0;
+ size_t inode_size;
- if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
- is_large_inode = 1;
large_inode = (struct ext2_inode_large *) inode;
+ if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
+ inode_size = ext2fs_inode_actual_size(large_inode);
+ else
+ inode_size = EXT2_GOOD_OLD_INODE_SIZE;
if (LINUX_S_ISDIR(inode->i_mode)) i_type = "directory";
else if (LINUX_S_ISREG(inode->i_mode)) i_type = "regular";
@@ -848,7 +850,7 @@ void internal_dump_inode(FILE *out, const char *prefix,
fprintf(out, "%sInode: %u Type: %s ", prefix, inode_num, i_type);
fprintf(out, "%sMode: 0%03o Flags: 0x%x\n",
prefix, inode->i_mode & 07777, inode->i_flags);
- if (is_large_inode && large_inode->i_extra_isize >= 24) {
+ if (ext2fs_inode_includes(inode_size, i_version_hi)) {
fprintf(out, "%sGeneration: %u Version: 0x%08x:%08x\n",
prefix, inode->i_generation, large_inode->i_version_hi,
inode->osd1.linux1.l_i_version);
@@ -858,7 +860,7 @@ void internal_dump_inode(FILE *out, const char *prefix,
}
fprintf(out, "%sUser: %5d Group: %5d",
prefix, inode_uid(*inode), inode_gid(*inode));
- if (is_large_inode && large_inode->i_extra_isize >= 32)
+ if (ext2fs_inode_includes(inode_size, i_projid))
fprintf(out, " Project: %5d", large_inode->i_projid);
fputs(" Size: ", out);
if (LINUX_S_ISREG(inode->i_mode) || LINUX_S_ISDIR(inode->i_mode))
@@ -895,39 +897,48 @@ void internal_dump_inode(FILE *out, const char *prefix,
}
fprintf(out, "%sFragment: Address: %u Number: %u Size: %u\n",
prefix, inode->i_faddr, frag, fsize);
- if (is_large_inode && large_inode->i_extra_isize >= 24) {
+ if (ext2fs_inode_includes(inode_size, i_ctime_extra))
fprintf(out, "%s ctime: 0x%08x:%08x -- %s", prefix,
inode->i_ctime, large_inode->i_ctime_extra,
- inode_time_to_string(inode->i_ctime,
- large_inode->i_ctime_extra));
+ time_to_string(ext2fs_inode_xtime_get(inode, i_ctime)));
+ else
+ fprintf(out, "%sctime: 0x%08x -- %s", prefix, inode->i_ctime,
+ time_to_string((__s32) inode->i_ctime));
+ if (ext2fs_inode_includes(inode_size, i_atime_extra))
fprintf(out, "%s atime: 0x%08x:%08x -- %s", prefix,
inode->i_atime, large_inode->i_atime_extra,
- inode_time_to_string(inode->i_atime,
- large_inode->i_atime_extra));
+ time_to_string(ext2fs_inode_xtime_get(inode, i_atime)));
+ else
+ fprintf(out, "%satime: 0x%08x -- %s", prefix, inode->i_atime,
+ time_to_string((__s32) inode->i_atime));
+ if (ext2fs_inode_includes(inode_size, i_mtime_extra))
fprintf(out, "%s mtime: 0x%08x:%08x -- %s", prefix,
inode->i_mtime, large_inode->i_mtime_extra,
- inode_time_to_string(inode->i_mtime,
- large_inode->i_mtime_extra));
+ time_to_string(ext2fs_inode_xtime_get(inode, i_mtime)));
+ else
+ fprintf(out, "%smtime: 0x%08x -- %s", prefix, inode->i_mtime,
+ time_to_string((__s32) inode->i_mtime));
+ if (ext2fs_inode_includes(inode_size, i_crtime_extra))
fprintf(out, "%scrtime: 0x%08x:%08x -- %s", prefix,
large_inode->i_crtime, large_inode->i_crtime_extra,
- inode_time_to_string(large_inode->i_crtime,
- large_inode->i_crtime_extra));
- if (inode->i_dtime)
+ time_to_string(ext2fs_inode_xtime_get(large_inode,
+ i_crtime)));
+ if (inode->i_dtime) {
+ if (ext2fs_inode_includes(inode_size, i_ctime_extra)) {
+ time_t tm;
+
+ /* dtime doesn't have its own i_dtime_extra field, so
+ * approximate this with i_ctime_extra instead. */
+ tm = __decode_extra_sec(inode->i_dtime,
+ large_inode->i_ctime_extra);
fprintf(out, "%s dtime: 0x%08x:(%08x) -- %s", prefix,
- large_inode->i_dtime, large_inode->i_ctime_extra,
- inode_time_to_string(inode->i_dtime,
- large_inode->i_ctime_extra));
- } else {
- fprintf(out, "%sctime: 0x%08x -- %s", prefix, inode->i_ctime,
- time_to_string((__s32) inode->i_ctime));
- fprintf(out, "%satime: 0x%08x -- %s", prefix, inode->i_atime,
- time_to_string((__s32) inode->i_atime));
- fprintf(out, "%smtime: 0x%08x -- %s", prefix, inode->i_mtime,
- time_to_string((__s32) inode->i_mtime));
- if (inode->i_dtime)
+ inode->i_dtime, large_inode->i_ctime_extra,
+ time_to_string(tm));
+ } else {
fprintf(out, "%sdtime: 0x%08x -- %s", prefix,
inode->i_dtime,
time_to_string((__s32) inode->i_dtime));
+ }
}
if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
internal_dump_inode_extra(out, prefix, inode_num,
@@ -935,11 +946,7 @@ void internal_dump_inode(FILE *out, const char *prefix,
dump_inode_attributes(out, inode_num);
if (ext2fs_has_feature_metadata_csum(current_fs->super)) {
__u32 crc = inode->i_checksum_lo;
- if (is_large_inode &&
- large_inode->i_extra_isize >=
- (offsetof(struct ext2_inode_large,
- i_checksum_hi) -
- EXT2_GOOD_OLD_INODE_SIZE))
+ if (ext2fs_inode_includes(inode_size, i_checksum_hi))
crc |= ((__u32)large_inode->i_checksum_hi) << 16;
fprintf(out, "Inode checksum: 0x%08x\n", crc);
}
diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h
index 39bc0247f..85c82b950 100644
--- a/debugfs/debugfs.h
+++ b/debugfs/debugfs.h
@@ -36,7 +36,6 @@ extern int check_fs_not_open(char *name);
extern int check_fs_read_write(char *name);
extern int check_fs_bitmaps(char *name);
extern ext2_ino_t string_to_inode(char *str);
-extern char *inode_time_to_string(__u32 xtime, __u32 xtime_extra);
extern char *time_to_string(__s64);
extern __s64 string_to_time(const char *);
extern unsigned long parse_ulong(const char *str, const char *cmd,
diff --git a/debugfs/journal.c b/debugfs/journal.c
index 79e3fff86..04611acf7 100644
--- a/debugfs/journal.c
+++ b/debugfs/journal.c
@@ -245,6 +245,8 @@ void wait_on_buffer(struct buffer_head *bh)
static void ext2fs_clear_recover(ext2_filsys fs, int error)
{
+ time_t s_mtime;
+
ext2fs_clear_feature_journal_needs_recovery(fs->super);
/* if we had an error doing journal recovery, we need a full fsck */
@@ -254,8 +256,9 @@ static void ext2fs_clear_recover(ext2_filsys fs, int error)
* If we replayed the journal by definition the file system
* was mounted since the last time it was checked
*/
- if (fs->super->s_lastcheck >= fs->super->s_mtime)
- fs->super->s_lastcheck = fs->super->s_mtime - 1;
+ s_mtime = ext2fs_get_tstamp(fs->super, s_mtime);
+ if (ext2fs_get_tstamp(fs->super, s_lastcheck) >= s_mtime)
+ ext2fs_set_tstamp(fs->super, s_lastcheck, s_mtime - 1);
ext2fs_mark_super_dirty(fs);
}
diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index f916deab8..ef137b0f2 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -99,15 +99,16 @@ static struct field_set_info super_fields[] = {
{ "blocks_per_group", &set_sb.s_blocks_per_group, NULL, 4, parse_uint },
{ "clusters_per_group", &set_sb.s_clusters_per_group, NULL, 4, parse_uint },
{ "inodes_per_group", &set_sb.s_inodes_per_group, NULL, 4, parse_uint },
- { "mtime", &set_sb.s_mtime, NULL, 4, parse_time },
- { "wtime", &set_sb.s_wtime, NULL, 4, parse_time },
+ { "mtime", &set_sb.s_mtime, &set_sb.s_mtime_hi, 5, parse_time },
+ { "wtime", &set_sb.s_wtime, &set_sb.s_wtime_hi, 5, parse_time },
{ "mnt_count", &set_sb.s_mnt_count, NULL, 2, parse_uint },
{ "max_mnt_count", &set_sb.s_max_mnt_count, NULL, 2, parse_int },
/* s_magic */
{ "state", &set_sb.s_state, NULL, 2, parse_uint },
{ "errors", &set_sb.s_errors, NULL, 2, parse_uint },
{ "minor_rev_level", &set_sb.s_minor_rev_level, NULL, 2, parse_uint },
- { "lastcheck", &set_sb.s_lastcheck, NULL, 4, parse_time },
+ { "lastcheck", &set_sb.s_lastcheck, &set_sb.s_lastcheck_hi, 5,
+ parse_time },
{ "checkinterval", &set_sb.s_checkinterval, NULL, 4, parse_uint },
{ "creator_os", &set_sb.s_creator_os, NULL, 4, parse_uint },
{ "rev_level", &set_sb.s_rev_level, NULL, 4, parse_uint },
@@ -139,7 +140,8 @@ static struct field_set_info super_fields[] = {
{ "desc_size", &set_sb.s_desc_size, NULL, 2, parse_uint },
{ "default_mount_opts", &set_sb.s_default_mount_opts, NULL, 4, parse_uint },
{ "first_meta_bg", &set_sb.s_first_meta_bg, NULL, 4, parse_uint },
- { "mkfs_time", &set_sb.s_mkfs_time, NULL, 4, parse_time },
+ { "mkfs_time", &set_sb.s_mkfs_time, &set_sb.s_mkfs_time_hi, 5,
+ parse_time },
{ "jnl_blocks", &set_sb.s_jnl_blocks[0], NULL, 4, parse_uint, FLAG_ARRAY,
17 },
{ "min_extra_isize", &set_sb.s_min_extra_isize, NULL, 2, parse_uint },
@@ -167,12 +169,14 @@ static struct field_set_info super_fields[] = {
{ "checksum_type", &set_sb.s_checksum_type, NULL, 1, parse_uint },
{ "encryption_level", &set_sb.s_encryption_level, NULL, 1, parse_uint },
{ "error_count", &set_sb.s_error_count, NULL, 4, parse_uint },
- { "first_error_time", &set_sb.s_first_error_time, NULL, 4, parse_time },
+ { "first_error_time", &set_sb.s_first_error_time,
+ &set_sb.s_first_error_time_hi, 5, parse_time },
{ "first_error_ino", &set_sb.s_first_error_ino, NULL, 4, parse_uint },
{ "first_error_block", &set_sb.s_first_error_block, NULL, 8, parse_uint },
{ "first_error_func", &set_sb.s_first_error_func, NULL, 32, parse_string },
{ "first_error_line", &set_sb.s_first_error_line, NULL, 4, parse_uint },
- { "last_error_time", &set_sb.s_last_error_time, NULL, 4, parse_time },
+ { "last_error_time", &set_sb.s_last_error_time,
+ &set_sb.s_last_error_time_hi, 5, parse_time },
{ "last_error_ino", &set_sb.s_last_error_ino, NULL, 4, parse_uint },
{ "last_error_block", &set_sb.s_last_error_block, NULL, 8, parse_uint },
{ "last_error_func", &set_sb.s_last_error_func, NULL, 32, parse_string },
@@ -441,6 +445,9 @@ static struct field_set_info *find_field(struct field_set_info *fields,
* Note: info->size == 6 is special; this means a base size 4 bytes,
* and secondary (high) size of 2 bytes. This is needed for the
* special case of i_blocks_high and i_file_acl_high.
+ *
+ * Similarly, info->size == 5 is for superblock timestamps, which have
+ * a 4-byte primary field and a 1-byte _hi field.
*/
static errcode_t parse_uint(struct field_set_info *info, char *field,
char *arg)
@@ -449,7 +456,7 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
int suffix = check_suffix(field);
char *tmp;
void *field1 = info->ptr, *field2 = info->ptr2;
- int size = (info->size == 6) ? 4 : info->size;
+ int size = (info->size == 6 || info->size == 5) ? 4 : info->size;
union {
__u64 *ptr64;
__u32 *ptr32;
@@ -477,7 +484,7 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
}
mask = ~0ULL >> ((8 - size) * 8);
limit = ~0ULL >> ((8 - info->size) * 8);
- if (field2 && info->size != 6)
+ if (field2 && (info->size != 6 || info->size != 5))
limit = ~0ULL >> ((8 - info->size*2) * 8);
if (num > limit) {
@@ -504,13 +511,14 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
return 0;
n = (size == 8) ? 0 : (num >> (size*8));
u.ptr8 = (__u8 *) field2;
- if (info->size == 6)
- size = 2;
+ if (info->size > size)
+ size = info->size - size;
switch (size) {
case 8:
/* Should never get here */
- fprintf(stderr, "64-bit field %s has a second 64-bit field\n"
- "defined; BUG?!?\n", info->name);
+ fprintf(stderr,
+ "64-bit field %s has a second 64-bit field defined; BUG?!?\n",
+ info->name);
*u.ptr64 = 0;
break;
case 4:
diff --git a/debugfs/util.c b/debugfs/util.c
index 9e8805481..d3ef63c68 100644
--- a/debugfs/util.c
+++ b/debugfs/util.c
@@ -191,14 +191,6 @@ int check_fs_bitmaps(char *name)
return 0;
}
-char *inode_time_to_string(__u32 xtime, __u32 xtime_extra)
-{
- __s64 t = (__s32) xtime;
-
- t += (__s64) (xtime_extra & EXT4_EPOCH_MASK) << 32;
- return time_to_string(t);
-}
-
/*
* This function takes a __s64 time value and converts it to a string,
* using ctime
diff --git a/e2fsck/message.c b/e2fsck/message.c
index ba38038cf..9c42b13fb 100644
--- a/e2fsck/message.c
+++ b/e2fsck/message.c
@@ -301,7 +301,7 @@ static _INLINE_ void expand_inode_expression(FILE *f, ext2_filsys fs, char ch,
fprintf(f, "0%o", inode->i_mode);
break;
case 'M':
- print_time(f, inode->i_mtime);
+ print_time(f, ext2fs_inode_xtime_get(inode, i_mtime));
break;
case 'F':
fprintf(f, "%u", inode->i_faddr);
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index a341c72ac..078bcb9bf 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1181,6 +1181,7 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2_ino_t ino_threshold = 0;
dgrp_t ra_group = 0;
struct ea_quota ea_ibody_quota;
+ time_t tm;
init_resource_track(&rtrack, ctx->fs->io);
clear_problem_context(&pctx);
@@ -1357,12 +1358,13 @@ void e2fsck_pass1(e2fsck_t ctx)
if (ctx->progress && ((ctx->progress)(ctx, 1, 0,
ctx->fs->group_desc_count)))
goto endit;
- if ((fs->super->s_wtime &&
- fs->super->s_wtime < fs->super->s_inodes_count) ||
- (fs->super->s_mtime &&
- fs->super->s_mtime < fs->super->s_inodes_count) ||
- (fs->super->s_mkfs_time &&
- fs->super->s_mkfs_time < fs->super->s_inodes_count))
+
+ if (((tm = ext2fs_get_tstamp(fs->super, s_wtime)) &&
+ tm < fs->super->s_inodes_count) ||
+ ((tm = ext2fs_get_tstamp(fs->super, s_mtime)) &&
+ tm < fs->super->s_inodes_count) ||
+ ((tm = ext2fs_get_tstamp(fs->super, s_mkfs_time)) &&
+ tm < fs->super->s_inodes_count))
low_dtime_check = 0;
if (ext2fs_has_feature_mmp(fs->super) &&
@@ -2076,7 +2078,7 @@ void e2fsck_pass1(e2fsck_t ctx)
if (!pctx.errcode) {
e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
"recreate inode");
- inode->i_mtime = ctx->now;
+ ext2fs_inode_xtime_set(inode, i_mtime, ctx->now);
e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
"recreate inode");
}
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 16d243f6c..ba794165b 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -212,7 +212,9 @@ skip_new_block:
memset(&inode, 0, sizeof(inode));
inode.i_mode = 040755;
inode.i_size = fs->blocksize;
- inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
+ ext2fs_inode_xtime_set(&inode, i_atime, ctx->now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, ctx->now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, ctx->now);
inode.i_links_count = 2;
ext2fs_iblk_set(fs, iptr, 1);
inode.i_block[0] = blk;
@@ -528,7 +530,9 @@ skip_new_block:
memset(&inode, 0, sizeof(inode));
inode.i_mode = 040700;
inode.i_size = fs->blocksize;
- inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
+ ext2fs_inode_xtime_set(&inode, i_atime, ctx->now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, ctx->now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, ctx->now);
inode.i_links_count = 2;
ext2fs_iblk_set(fs, EXT2_INODE(&inode), 1);
inode.i_block[0] = blk;
diff --git a/e2fsck/super.c b/e2fsck/super.c
index be40dd8fb..757a475de 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -1320,25 +1320,25 @@ void check_super_block(e2fsck_t ctx)
*/
if (((ctx->options & E2F_OPT_FORCE) || fs->super->s_checkinterval) &&
!broken_system_clock && !(ctx->flags & E2F_FLAG_TIME_INSANE) &&
- (fs->super->s_mtime > (__u32) ctx->now)) {
- pctx.num = fs->super->s_mtime;
+ (ext2fs_get_tstamp(fs->super, s_mtime) > ctx->now)) {
+ pctx.num = ext2fs_get_tstamp(fs->super, s_mtime);
problem = PR_0_FUTURE_SB_LAST_MOUNT;
- if (fs->super->s_mtime <= (__u32) ctx->now + ctx->time_fudge)
+ if (pctx.num <= 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_set_tstamp(fs->super, s_mtime, ctx->now);
fs->flags |= EXT2_FLAG_DIRTY;
}
}
if (((ctx->options & E2F_OPT_FORCE) || fs->super->s_checkinterval) &&
!broken_system_clock && !(ctx->flags & E2F_FLAG_TIME_INSANE) &&
- (fs->super->s_wtime > (__u32) ctx->now)) {
- pctx.num = fs->super->s_wtime;
+ (ext2fs_get_tstamp(fs->super, s_wtime) > ctx->now)) {
+ pctx.num = ext2fs_get_tstamp(fs->super, s_wtime);
problem = PR_0_FUTURE_SB_LAST_WRITE;
- if (fs->super->s_wtime <= (__u32) ctx->now + ctx->time_fudge)
+ if (pctx.num <= ctx->now + ctx->time_fudge)
problem = PR_0_FUTURE_SB_LAST_WRITE_FUDGED;
if (fix_problem(ctx, problem, &pctx)) {
- fs->super->s_wtime = ctx->now;
+ ext2fs_set_tstamp(fs->super, s_wtime, ctx->now);
fs->flags |= EXT2_FLAG_DIRTY;
}
}
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index e5b672a2e..bc6b518d5 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -2080,7 +2080,7 @@ cleanup:
} else
sb->s_state &= ~EXT2_VALID_FS;
if (!(ctx->flags & E2F_FLAG_TIME_INSANE))
- sb->s_lastcheck = ctx->now;
+ ext2fs_set_tstamp(sb, s_lastcheck, ctx->now);
sb->s_mnt_count = 0;
memset(((char *) sb) + EXT4_S_ERR_START, 0, EXT4_S_ERR_LEN);
pctx.errcode = ext2fs_set_gdt_csum(ctx->fs);
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 0b74aea2b..081ef9757 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -313,27 +313,23 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
if (sb->s_log_groups_per_flex)
fprintf(f, "Flex block group size: %u\n",
1U << sb->s_log_groups_per_flex);
- if (sb->s_mkfs_time) {
- tm = sb->s_mkfs_time;
+ tm = ext2fs_get_tstamp(sb, s_mkfs_time);
+ if (tm)
fprintf(f, "Filesystem created: %s", ctime(&tm));
- }
- tm = sb->s_mtime;
- fprintf(f, "Last mount time: %s",
- sb->s_mtime ? ctime(&tm) : "n/a\n");
- tm = sb->s_wtime;
+ tm = ext2fs_get_tstamp(sb, s_mtime);
+ fprintf(f, "Last mount time: %s", tm ? ctime(&tm) : "n/a\n");
+ tm = ext2fs_get_tstamp(sb, s_wtime);
fprintf(f, "Last write time: %s", ctime(&tm));
fprintf(f, "Mount count: %u\n", sb->s_mnt_count);
fprintf(f, "Maximum mount count: %d\n", sb->s_max_mnt_count);
- tm = sb->s_lastcheck;
+ tm = ext2fs_get_tstamp(sb, s_lastcheck);
fprintf(f, "Last checked: %s", ctime(&tm));
fprintf(f, "Check interval: %u (%s)\n", sb->s_checkinterval,
interval_string(sb->s_checkinterval));
if (sb->s_checkinterval)
{
- time_t next;
-
- next = sb->s_lastcheck + sb->s_checkinterval;
- fprintf(f, "Next check after: %s", ctime(&next));
+ tm += sb->s_checkinterval;
+ fprintf(f, "Next check after: %s", ctime(&tm));
}
#define POW2(x) ((__u64) 1 << (x))
if (sb->s_kbytes_written) {
@@ -419,8 +415,8 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
if (sb->s_error_count)
fprintf(f, "FS Error count: %u\n",
sb->s_error_count);
- if (sb->s_first_error_time) {
- tm = sb->s_first_error_time;
+ tm = ext2fs_get_tstamp(sb, s_first_error_time);
+ if (tm) {
fprintf(f, "First error time: %s", ctime(&tm));
fprintf(f, "First error function: %.*s\n",
EXT2_LEN_STR(sb->s_first_error_func));
@@ -436,8 +432,8 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
fprintf(f, "First error err: %s\n",
e2p_errcode2str(sb->s_first_error_errcode));
}
- if (sb->s_last_error_time) {
- tm = sb->s_last_error_time;
+ tm = ext2fs_get_tstamp(sb, s_last_error_time);
+ if (tm) {
fprintf(f, "Last error time: %s", ctime(&tm));
fprintf(f, "Last error function: %.*s\n",
EXT2_LEN_STR(sb->s_last_error_func));
diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c
index 11f10ebcd..927a4d41d 100644
--- a/lib/ext2fs/bb_inode.c
+++ b/lib/ext2fs/bb_inode.c
@@ -58,8 +58,9 @@ static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
{
errcode_t retval;
- struct set_badblock_record rec;
+ struct set_badblock_record rec;
struct ext2_inode inode;
+ time_t now;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -124,9 +125,11 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
if (retval)
goto cleanup;
- inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0);
- if (!inode.i_ctime)
- inode.i_ctime = fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ if (!ext2fs_inode_xtime_get(&inode, i_ctime))
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
retval = ext2fs_inode_size_set(fs, &inode,
rec.bad_block_count * fs->blocksize);
diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c
index 69cbdd8c1..42bda1fae 100644
--- a/lib/ext2fs/closefs.c
+++ b/lib/ext2fs/closefs.c
@@ -301,7 +301,7 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
fs_state = fs->super->s_state;
feature_incompat = fs->super->s_feature_incompat;
- fs->super->s_wtime = fs->now ? fs->now : time(NULL);
+ ext2fs_set_tstamp(fs->super, s_wtime, fs->now ? fs->now : time(NULL));
fs->super->s_block_group_nr = 0;
/*
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 0fc9c09a5..586141f89 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -512,9 +512,9 @@ struct ext2_inode_large {
#define i_checksum_lo osd2.linux2.l_i_checksum_lo
-#define inode_includes(size, field) \
- (size >= (sizeof(((struct ext2_inode_large *)0)->field) + \
- offsetof(struct ext2_inode_large, field)))
+#define ext2fs_inode_includes(size, field) \
+ ((size) >= (sizeof(((struct ext2_inode_large *)0)->field) + \
+ offsetof(struct ext2_inode_large, field)))
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 72c60d2b5..8953817ca 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -579,6 +579,58 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan;
*/
#define EXT2_I_SIZE(i) ((i)->i_size | ((__u64) (i)->i_size_high << 32))
+static inline __u32 __encode_extra_time(time_t seconds, __u32 nsec)
+{
+ __u32 extra = ((seconds - (__s32)seconds) >> 32) & EXT4_EPOCH_MASK;
+ return extra | (nsec << EXT4_EPOCH_BITS);
+}
+static inline time_t __decode_extra_sec(time_t seconds, __u32 extra)
+{
+ if (extra & EXT4_EPOCH_MASK)
+ seconds += ((time_t)(extra & EXT4_EPOCH_MASK) << 32);
+ return seconds;
+}
+static inline __u32 __decode_extra_nsec(__u32 extra)
+{
+ return (extra & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
+}
+#define ext2fs_inode_actual_size(inode) \
+ (EXT2_GOOD_OLD_INODE_SIZE + \
+ (sizeof(*inode) > EXT2_GOOD_OLD_INODE_SIZE ? \
+ ((struct ext2_inode_large *)(inode))->i_extra_isize : 0))
+#define clamp(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? \
+ (max) : (val)))
+#define ext2fs_inode_xtime_set(inode, field, sec) \
+do { \
+ if (ext2fs_inode_includes(ext2fs_inode_actual_size(inode), \
+ field ## _extra)) { \
+ (inode)->field = (__s32)sec; \
+ ((struct ext2_inode_large *)(inode))->field ## _extra = \
+ __encode_extra_time(sec, 0); \
+ } else { \
+ (inode)->field = clamp(sec, INT32_MIN, INT32_MAX); \
+ } \
+} while (0)
+#define ext2fs_inode_xtime_get(inode, field) \
+(ext2fs_inode_includes(ext2fs_inode_actual_size(inode), field ## _extra) ? \
+ __decode_extra_sec((inode)->field, \
+ ((struct ext2_inode_large *)(inode))->field ## _extra) : \
+ (time_t)(inode)->field)
+
+static inline void __sb_set_tstamp(__u32 *lo, __u8 *hi, time_t seconds)
+{
+ *lo = seconds & 0xffffffff;
+ *hi = seconds >> 32;
+}
+static inline time_t __sb_get_tstamp(__u32 *lo, __u8 *hi)
+{
+ return ((time_t)(*hi) << 32) | *lo;
+}
+#define ext2fs_set_tstamp(sb, field, seconds) \
+ __sb_set_tstamp(&(sb)->field, &(sb)->field ## _hi, seconds)
+#define ext2fs_get_tstamp(sb, field) \
+ __sb_get_tstamp(&(sb)->field, &(sb)->field ## _hi)
+
/*
* ext2_icount_t abstraction
*/
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index e96f3cabd..d5f9a0f5b 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -218,7 +218,8 @@ errcode_t ext2fs_initialize(const char *name, int flags,
}
set_field(s_checkinterval, 0);
- super->s_mkfs_time = super->s_lastcheck = fs->now ? fs->now : time(NULL);
+ ext2fs_set_tstamp(super, s_mkfs_time, fs->now ? fs->now : time(NULL));
+ ext2fs_set_tstamp(super, s_lastcheck, fs->now ? fs->now : time(NULL));
super->s_creator_os = CREATOR_OS;
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 957d5aa9f..8686f99c6 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -1039,17 +1039,17 @@ errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode)
{
struct ext2_inode *buf;
- int size = EXT2_INODE_SIZE(fs->super);
+ int size = EXT2_INODE_SIZE(fs->super);
struct ext2_inode_large *large_inode;
errcode_t retval;
- __u32 t = fs->now ? fs->now : time(NULL);
-
- if (!inode->i_ctime)
- inode->i_ctime = t;
- if (!inode->i_mtime)
- inode->i_mtime = t;
- if (!inode->i_atime)
- inode->i_atime = t;
+ time_t t = fs->now ? fs->now : time(NULL);
+
+ if (!ext2fs_inode_xtime_get(inode, i_atime))
+ ext2fs_inode_xtime_set(inode, i_atime, t);
+ if (!ext2fs_inode_xtime_get(inode, i_ctime))
+ ext2fs_inode_xtime_set(inode, i_ctime, t);
+ if (!ext2fs_inode_xtime_get(inode, i_mtime))
+ ext2fs_inode_xtime_set(inode, i_mtime, t);
if (size == sizeof(struct ext2_inode))
return ext2fs_write_inode_full(fs, ino, inode,
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
index 54772dd50..4a947b618 100644
--- a/lib/ext2fs/mkjournal.c
+++ b/lib/ext2fs/mkjournal.c
@@ -285,6 +285,7 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
unsigned long long inode_size;
int falloc_flags = EXT2_FALLOCATE_FORCE_INIT;
blk64_t zblk;
+ time_t now;
if ((retval = ext2fs_create_journal_superblock2(fs, jparams, flags,
&buf)))
@@ -312,7 +313,9 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
inode_size = (unsigned long long)fs->blocksize *
(jparams->num_journal_blocks + jparams->num_fc_blocks);
- inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c
index c2f83567f..ed897418b 100644
--- a/lib/ext2fs/orphan.c
+++ b/lib/ext2fs/orphan.c
@@ -126,6 +126,7 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
char *buf = NULL, *zerobuf = NULL;
struct mkorphan_info oi;
struct ext4_orphan_block_tail *ob_tail;
+ time_t now;
if (ino) {
err = ext2fs_read_inode(fs, ino, &inode);
@@ -184,8 +185,10 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
if (err)
goto out;
ext2fs_iblk_set(fs, &inode, 0);
- inode.i_atime = inode.i_mtime =
- inode.i_ctime = fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
ext2fs_iblk_add_blocks(fs, &inode, oi.alloc_blocks);
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index fa8d8d6be..9024165d6 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -227,7 +227,10 @@ out_inode:
EXT2_I_SIZE(&inode));
#endif
if (inode_dirty) {
- inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0);
+ time_t now = fs->now ? fs->now : time(0);
+
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
retval2 = ext2fs_write_new_inode(fs, EXT2_RESIZE_INO, &inode);
if (!retval)
retval = retval2;
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index fe764b9e0..d8d214079 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -345,21 +345,21 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
return; /* Illegal inode extra_isize */
inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
- if (inode_includes(inode_size, i_checksum_hi))
+ if (ext2fs_inode_includes(inode_size, i_checksum_hi))
t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi);
- if (inode_includes(inode_size, i_ctime_extra))
+ if (ext2fs_inode_includes(inode_size, i_ctime_extra))
t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra);
- if (inode_includes(inode_size, i_mtime_extra))
+ if (ext2fs_inode_includes(inode_size, i_mtime_extra))
t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra);
- if (inode_includes(inode_size, i_atime_extra))
+ if (ext2fs_inode_includes(inode_size, i_atime_extra))
t->i_atime_extra = ext2fs_swab32(f->i_atime_extra);
- if (inode_includes(inode_size, i_crtime))
+ if (ext2fs_inode_includes(inode_size, i_crtime))
t->i_crtime = ext2fs_swab32(f->i_crtime);
- if (inode_includes(inode_size, i_crtime_extra))
+ if (ext2fs_inode_includes(inode_size, i_crtime_extra))
t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra);
- if (inode_includes(inode_size, i_version_hi))
+ if (ext2fs_inode_includes(inode_size, i_version_hi))
t->i_version_hi = ext2fs_swab32(f->i_version_hi);
- if (inode_includes(inode_size, i_projid))
+ if (ext2fs_inode_includes(inode_size, i_projid))
t->i_projid = ext2fs_swab32(f->i_projid);
/* catch new static fields added after i_projid */
EXT2FS_BUILD_BUG_ON(sizeof(struct ext2_inode_large) != 160);
diff --git a/lib/support/mkquota.c b/lib/support/mkquota.c
index 9339c9943..81cfbf1fa 100644
--- a/lib/support/mkquota.c
+++ b/lib/support/mkquota.c
@@ -269,7 +269,7 @@ static inline qid_t get_qid(struct ext2_inode_large *inode, enum quota_type qtyp
case PRJQUOTA:
inode_size = EXT2_GOOD_OLD_INODE_SIZE +
inode->i_extra_isize;
- if (inode_includes(inode_size, i_projid))
+ if (ext2fs_inode_includes(inode_size, i_projid))
return inode_projid(*inode);
return 0;
default:
diff --git a/lib/support/plausible.c b/lib/support/plausible.c
index 65a6b2e14..eccba22a3 100644
--- a/lib/support/plausible.c
+++ b/lib/support/plausible.c
@@ -108,18 +108,15 @@ static void print_ext2_info(const char *device)
return;
sb = fs->super;
- if (sb->s_mtime) {
- tm = sb->s_mtime;
+ if ((tm = ext2fs_get_tstamp(sb, s_mtime))) {
if (sb->s_last_mounted[0])
printf(_("\tlast mounted on %.*s on %s"),
EXT2_LEN_STR(sb->s_last_mounted), ctime(&tm));
else
printf(_("\tlast mounted on %s"), ctime(&tm));
- } else if (sb->s_mkfs_time) {
- tm = sb->s_mkfs_time;
+ } else if ((tm = ext2fs_get_tstamp(sb, s_mkfs_time))) {
printf(_("\tcreated on %s"), ctime(&tm));
- } else if (sb->s_wtime) {
- tm = sb->s_wtime;
+ } else if ((tm = ext2fs_get_tstamp(sb, s_wtime))) {
printf(_("\tlast modified on %s"), ctime(&tm));
}
ext2fs_close_free(&fs);
diff --git a/lib/support/quotaio.c b/lib/support/quotaio.c
index b41bb7498..916e28cf5 100644
--- a/lib/support/quotaio.c
+++ b/lib/support/quotaio.c
@@ -272,6 +272,7 @@ static errcode_t quota_inode_init_new(ext2_filsys fs, ext2_ino_t ino)
{
struct ext2_inode inode;
errcode_t err = 0;
+ time_t now;
err = ext2fs_read_inode(fs, ino, &inode);
if (err) {
@@ -287,8 +288,10 @@ static errcode_t quota_inode_init_new(ext2_filsys fs, ext2_ino_t ino)
memset(&inode, 0, sizeof(struct ext2_inode));
ext2fs_iblk_set(fs, &inode, 0);
- inode.i_atime = inode.i_mtime =
- inode.i_ctime = fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
inode.i_flags |= EXT2_IMMUTABLE_FL;
diff --git a/misc/create_inode.c b/misc/create_inode.c
index a3a34cd9a..28f478c08 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -125,9 +125,9 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
inode.i_gid = st->st_gid;
ext2fs_set_i_gid_high(inode, st->st_gid >> 16);
inode.i_mode = (LINUX_S_IFMT & inode.i_mode) | (~S_IFMT & st->st_mode);
- inode.i_atime = st->st_atime;
- inode.i_mtime = st->st_mtime;
- inode.i_ctime = st->st_ctime;
+ ext2fs_inode_xtime_set(&inode, i_atime, st->st_atime);
+ ext2fs_inode_xtime_set(&inode, i_ctime, st->st_ctime);
+ ext2fs_inode_xtime_set(&inode, i_mtime, st->st_mtime);
retval = ext2fs_write_inode(fs, ino, &inode);
if (retval)
@@ -256,6 +256,7 @@ errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
struct ext2_inode inode;
unsigned long devmajor, devminor, mode;
int filetype;
+ time_t now;
switch(st_mode & S_IFMT) {
case S_IFCHR:
@@ -309,8 +310,10 @@ errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
memset(&inode, 0, sizeof(inode));
inode.i_mode = mode;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
if (filetype != S_IFIFO) {
devmajor = major(st_rdev);
@@ -631,6 +634,7 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
errcode_t retval;
struct ext2_inode inode;
char *cp;
+ time_t now;
fd = ext2fs_open_file(src, O_RDONLY, 0);
if (fd < 0) {
@@ -684,8 +688,10 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
ext2fs_inode_alloc_stats2(fs, newfile, +1, 0);
memset(&inode, 0, sizeof(inode));
inode.i_mode = (statbuf.st_mode & ~S_IFMT) | LINUX_S_IFREG;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
inode.i_links_count = 1;
retval = ext2fs_inode_size_set(fs, &inode, statbuf.st_size);
if (retval)
diff --git a/misc/e2undo.c b/misc/e2undo.c
index bc78fb2eb..4cbf8884e 100644
--- a/misc/e2undo.c
+++ b/misc/e2undo.c
@@ -154,9 +154,11 @@ static void print_undo_mismatch(struct ext2_super_block *fs_super,
if (memcmp(fs_super->s_uuid, undo_super->s_uuid,
sizeof(fs_super->s_uuid)))
printf("%s", _("UUID does not match.\n"));
- if (fs_super->s_mtime != undo_super->s_mtime)
+ if (ext2fs_get_tstamp(fs_super, s_mtime) !=
+ ext2fs_get_tstamp(undo_super, s_mtime))
printf("%s", _("Last mount time does not match.\n"));
- if (fs_super->s_wtime != undo_super->s_wtime)
+ if (ext2fs_get_tstamp(fs_super, s_wtime) !=
+ ext2fs_get_tstamp(undo_super, s_wtime))
printf("%s", _("Last write time does not match.\n"));
if (fs_super->s_kbytes_written != undo_super->s_kbytes_written)
printf("%s", _("Lifetime write counter does not match.\n"));
diff --git a/misc/findsuper.c b/misc/findsuper.c
index 7e78c1fc8..1f5c3e72f 100644
--- a/misc/findsuper.c
+++ b/misc/findsuper.c
@@ -230,10 +230,9 @@ int main(int argc, char *argv[])
WHY("free_inodes_count > inodes_count (%u > %u)\n",
ext2.s_free_inodes_count, ext2.s_inodes_count);
- if (ext2.s_mkfs_time != 0)
- tm = ext2.s_mkfs_time;
- else
- tm = ext2.s_mtime;
+ tm = ext2fs_get_tstamp(ext2, s_mkfs_time);
+ if (tm == 0)
+ tm = ext2fs_get_tstamp(ext2, s_mtime);
s = ctime(&tm);
s[24] = 0;
bsize = 1 << (ext2.s_log_block_size + 10);
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index 0dc77eadc..4133e0601 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -746,7 +746,7 @@ static void *op_init(struct fuse_conn_info *conn)
#endif
if (fs->flags & EXT2_FLAG_RW) {
fs->super->s_mnt_count++;
- fs->super->s_mtime = time(NULL);
+ ext2fs_set_tstamp(fs->super, s_mtime, time(NULL));
fs->super->s_state &= ~EXT2_VALID_FS;
ext2fs_mark_super_dirty(fs);
err = ext2fs_flush2(fs, 0);
@@ -3984,14 +3984,14 @@ no_translation:
/* Make a note in the error log */
get_now(&now);
- fs->super->s_last_error_time = now.tv_sec;
+ ext2fs_set_tstamp(fs->super, s_last_error_time, now.tv_sec);
fs->super->s_last_error_ino = ino;
fs->super->s_last_error_line = line;
fs->super->s_last_error_block = err; /* Yeah... */
strncpy((char *)fs->super->s_last_error_func, file,
sizeof(fs->super->s_last_error_func));
- if (fs->super->s_first_error_time == 0) {
- fs->super->s_first_error_time = now.tv_sec;
+ if (ext2fs_get_tstamp(fs->super, s_first_error_time) == 0) {
+ ext2fs_set_tstamp(fs->super, s_first_error_time, now.tv_sec);
fs->super->s_first_error_ino = ino;
fs->super->s_first_error_line = line;
fs->super->s_first_error_block = err;
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index f0af3cae8..5f077663c 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -470,7 +470,8 @@ static int check_fsck_needed(ext2_filsys fs, const char *prompt)
/* Refuse to modify anything but a freshly checked valid filesystem. */
if (!(fs->super->s_state & EXT2_VALID_FS) ||
(fs->super->s_state & EXT2_ERROR_FS) ||
- (fs->super->s_lastcheck < fs->super->s_mtime)) {
+ (ext2fs_get_tstamp(fs->super, s_lastcheck) <
+ ext2fs_get_tstamp(fs->super, s_mtime))) {
puts(_(fsck_explain));
puts(_(please_fsck));
if (mount_flags & EXT2_MF_READONLY)
@@ -524,7 +525,8 @@ static void convert_64bit(ext2_filsys fs, int direction)
if (!fsck_requested &&
((fs->super->s_state & EXT2_ERROR_FS) ||
!(fs->super->s_state & EXT2_VALID_FS) ||
- fs->super->s_lastcheck < fs->super->s_mtime))
+ ext2fs_get_tstamp(fs->super, s_lastcheck) <
+ ext2fs_get_tstamp(fs->super, s_mtime)))
request_fsck_afterwards(fs);
if (fsck_requested)
fprintf(stderr, _("After running e2fsck, please run `resize2fs %s %s"),