]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Add post-2038 timestamp support to e2fsprogs
authorAndreas Dilger <adilger@dilger.ca>
Wed, 27 Sep 2023 05:40:16 +0000 (23:40 -0600)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 31 Mar 2024 17:54:33 +0000 (13:54 -0400)
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>
29 files changed:
debugfs/debugfs.c
debugfs/debugfs.h
debugfs/journal.c
debugfs/set_fields.c
debugfs/util.c
e2fsck/message.c
e2fsck/pass1.c
e2fsck/pass3.c
e2fsck/super.c
e2fsck/unix.c
lib/e2p/ls.c
lib/ext2fs/bb_inode.c
lib/ext2fs/closefs.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h
lib/ext2fs/initialize.c
lib/ext2fs/inode.c
lib/ext2fs/mkjournal.c
lib/ext2fs/orphan.c
lib/ext2fs/res_gdt.c
lib/ext2fs/swapfs.c
lib/support/mkquota.c
lib/support/plausible.c
lib/support/quotaio.c
misc/create_inode.c
misc/e2undo.c
misc/findsuper.c
misc/fuse2fs.c
misc/tune2fs.c

index 9b6321dc4262aba21ecf7efe17e8f1291fbe336b..965511739e37eebf533455e0ebb8dfea87a6dab4 100644 (file)
@@ -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);
        }
index 39bc0247f527148477055bbb0afad24da5280c66..85c82b950366334936ae0d829ed87245024e1838 100644 (file)
@@ -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,
index 79e3fff86ba1dd4ed76fb6997368137531730a30..04611acf760e4facde49d8b7bfbd3ed17dbf3ce8 100644 (file)
@@ -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);
 }
 
index f916deab8cea90e2f7c05e6373c53247900cd7c0..ef137b0f22150a1c6477d643946ee77619acd65f 100644 (file)
@@ -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:
index 9e8805481b7bd2b9e0c65d2228d01be80562171a..d3ef63c68b3b6a566ed4860609ab4f36c54ce1b0 100644 (file)
@@ -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
index ba38038cf39bb823e0ff0cf59ef6d6d4f761ce56..9c42b13fb38aacb43a36af15edc130e87ed71b13 100644 (file)
@@ -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);
index a341c72ac56e51bd061a6871d354781efcfc08c6..078bcb9bfe4ce2ce7d64d22de63c2dcd083b1948 100644 (file)
@@ -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");
                }
index 16d243f6c76f9bbd3fa41536183df40d366d20a7..ba794165b98d5d5d2e6a15bf2c26db6679a1962f 100644 (file)
@@ -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;
index be40dd8fb64d86af4e119ad3efe5c0a3aa380568..757a475de1ab234f3d44bf5c6041a81a5573f877 100644 (file)
@@ -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;
                }
        }
index e5b672a2e58acb7167376ead6a63a3349ccd65a3..bc6b518d5b46b7fce245d5157e42391cd0eaf3e3 100644 (file)
@@ -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);
index 0b74aea2b452ee0c6d501aa3cfa9abe386e942d7..081ef9757ced49e64500c96b869d76e95bcf6058 100644 (file)
@@ -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));
index 11f10ebcd7a78c9892c3a678249f15493ae080ae..927a4d41db2884d088f14c62ac0fbe2bbf18d6fa 100644 (file)
@@ -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);
index 69cbdd8c19e8e99479fb479287ed209643590a22..42bda1fae15bdd7a63b0965182cca0fe24c45f61 100644 (file)
@@ -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;
 
        /*
index 0fc9c09a592551cf8e4ec0c7d89fe998eb8e9373..586141f895c7a19a8ea40dc4b9aec8d066ff24d8 100644 (file)
@@ -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
index 72c60d2b54d57adb3147eb09e9a8628f19a48776..8953817cae591a47f1e6ed9a7ecb95a99ad7c622 100644 (file)
@@ -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
  */
index e96f3cabd328a8a16162c80bcde05efb317f3499..d5f9a0f5b856bc4f8384118941449e9d7e81d3e3 100644 (file)
@@ -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;
 
index 957d5aa9f9d695298c8e0f39108db44a2661960b..8686f99c660962a5f393d5ff37e5108463c58f51 100644 (file)
@@ -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,
index 54772dd50e35498398a22b12b0a4386d1fd21cf6..4a947b618f73727973ae6245664efa7a2114ad0a 100644 (file)
@@ -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);
index c2f83567f4ddc12d92f841c420367a92003c476b..ed897418b64c2538ff691bf692c422c4023f7238 100644 (file)
@@ -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);
index fa8d8d6bedab9f255c0ee109812053f6a5713048..9024165d60a6a6fb8361f65e861e359724bbf508 100644 (file)
@@ -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;
index fe764b9e0528a96bec88fb6f379a016448892094..d8d21407984b9352469dbea06a5ebab071878137 100644 (file)
@@ -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);
index 9339c9943f49192908d76951d1d511f7d9389b26..81cfbf1fae955f49c93ec428de227cd3709f5c47 100644 (file)
@@ -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:
index 65a6b2e1419b387a6fc2abf58cc1fd78cfde9b6c..eccba22a317315a52f80aa3e2afb237dc8bc3afc 100644 (file)
@@ -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);
index b41bb7498bc3aff4d3b3f60796d4897c5fa91427..916e28cf50f1e890e6b0e1699823aa3b56cc52ee 100644 (file)
@@ -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;
index a3a34cd9ae8f5c99b147e4d7695b62226272ee61..28f478c081b142528b448ad8a58fe2e6e73b43a9 100644 (file)
@@ -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)
index bc78fb2eb9de6cce1b0386b9fefa2c20c03f6b28..4cbf8884e46b0ecd2b72ab80be84e74a54c9b76b 100644 (file)
@@ -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"));
index 7e78c1fc819a3d3156cb114b63ac70fd02642673..1f5c3e72f8b2f5ee7bc36dea980c10354d81c27e 100644 (file)
@@ -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);
index 0dc77eadc53c3b22aea3a0a5ed1923d67ea96633..4133e06013a9d7ee6ad6f90eeb754375452dd3a5 100644 (file)
@@ -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;
index f0af3cae83df24bf52418514820b4a7720b976c4..5f077663c08d01ae4506cbf890f79ff96ed3a06f 100644 (file)
@@ -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"),