From b6e2913061577ad981464e435026d71a48fd5caf Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 25 Apr 2024 10:42:09 -0400 Subject: [PATCH] libext2fs: add support for the SOURCE_DATE_EPOCH environment variable Add SOURCE_DATE_EPOCH support as documented in [1]. [1] https://reproducible-builds.org/specs/source-date-epoch Signed-off-by: Theodore Ts'o --- lib/ext2fs/bb_inode.c | 5 ++--- lib/ext2fs/closefs.c | 2 +- lib/ext2fs/ext2fs.h | 8 +++++++- lib/ext2fs/ext2fsP.h | 7 +++++++ lib/ext2fs/ext_attr.c | 4 ++-- lib/ext2fs/initialize.c | 16 +++++++++++----- lib/ext2fs/inode.c | 2 +- lib/ext2fs/mkjournal.c | 5 ++--- lib/ext2fs/openfs.c | 10 ++++++++-- lib/ext2fs/orphan.c | 2 +- lib/ext2fs/res_gdt.c | 6 +++--- 11 files changed, 45 insertions(+), 22 deletions(-) diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c index 927a4d4..8b29e1c 100644 --- a/lib/ext2fs/bb_inode.c +++ b/lib/ext2fs/bb_inode.c @@ -20,7 +20,6 @@ #include #endif #include -#include #if HAVE_SYS_STAT_H #include #endif @@ -29,7 +28,7 @@ #endif #include "ext2_fs.h" -#include "ext2fs.h" +#include "ext2fsP.h" struct set_badblock_record { ext2_badblocks_iterate bb_iter; @@ -125,7 +124,7 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list) if (retval) goto cleanup; - now = fs->now ? fs->now : time(0); + now = ext2fsP_get_time(fs); ext2fs_inode_xtime_set(&inode, i_atime, now); if (!ext2fs_inode_xtime_get(&inode, i_ctime)) ext2fs_inode_xtime_set(&inode, i_ctime, now); diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c index 42bda1f..8e5bec0 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; - ext2fs_set_tstamp(fs->super, s_wtime, fs->now ? fs->now : time(NULL)); + ext2fs_set_tstamp(fs->super, s_wtime, ext2fsP_get_time(fs)); fs->super->s_block_group_nr = 0; /* diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index f3d98f6..c2638b8 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -222,6 +222,11 @@ typedef struct ext2_file *ext2_file_t; #define EXT2_FLAG_IGNORE_SWAP_DIRENT 0x8000000 /* + * Internal flags for use by the ext2fs library only + */ +#define EXT2_FLAG2_USE_FAKE_TIME 0x000000001 + +/* * Special flag in the ext2 inode i_flag field that means that this is * a new inode. (So that ext2_write_inode() can clear extra fields.) */ @@ -275,10 +280,11 @@ struct struct_ext2_filsys { int cluster_ratio_bits; __u16 default_bitmap_type; __u16 pad; + __u32 flags2; /* * Reserved for future expansion */ - __u32 reserved[5]; + __u32 reserved[4]; /* * Reserved for the use of the calling application. diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h index 0687384..d1f2105 100644 --- a/lib/ext2fs/ext2fsP.h +++ b/lib/ext2fs/ext2fsP.h @@ -26,6 +26,13 @@ static inline int ext2fsP_is_disk_device(mode_t mode) #endif } +static inline time_t ext2fsP_get_time(ext2_filsys fs) +{ + if (fs->now || (fs->flags2 & EXT2_FLAG2_USE_FAKE_TIME)) + return fs->now; + return time(NULL); +} + /* * Badblocks list */ diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index 3494046..b33bcce 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -23,7 +23,7 @@ #include "ext2_ext_attr.h" #include "ext4_acl.h" -#include "ext2fs.h" +#include "ext2fsP.h" static errcode_t read_ea_inode_hash(ext2_filsys fs, ext2_ino_t ino, __u32 *hash) { @@ -1342,7 +1342,7 @@ static errcode_t xattr_inode_dec_ref(ext2_filsys fs, ext2_ino_t ino) goto write_out; inode.i_links_count = 0; - inode.i_dtime = fs->now ? fs->now : time(0); + inode.i_dtime = ext2fsP_get_time(fs); ret = ext2fs_free_ext_attr(fs, ino, &inode); if (ret) diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index 513bf5a..b9cfd1b 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -26,7 +26,7 @@ #endif #include "ext2_fs.h" -#include "ext2fs.h" +#include "ext2fsP.h" #ifndef O_BINARY #define O_BINARY 0 @@ -125,9 +125,15 @@ errcode_t ext2fs_initialize(const char *name, int flags, fs->flags |= EXT2_FLAG_SWAP_BYTES; #endif - time_env = ext2fs_safe_getenv("E2FSPROGS_FAKE_TIME"); - if (time_env) + time_env = ext2fs_safe_getenv("SOURCE_DATE_EPOCH"); + if (time_env) { fs->now = strtoul(time_env, NULL, 0); + fs->flags2 |= EXT2_FLAG2_USE_FAKE_TIME; + } else { + time_env = ext2fs_safe_getenv("E2FSPROGS_FAKE_TIME"); + if (time_env) + fs->now = strtoul(time_env, NULL, 0); + } io_flags = IO_FLAG_RW; if (flags & EXT2_FLAG_EXCLUSIVE) @@ -218,8 +224,8 @@ errcode_t ext2fs_initialize(const char *name, int flags, } set_field(s_checkinterval, 0); - 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)); + ext2fs_set_tstamp(super, s_mkfs_time, ext2fsP_get_time(fs)); + ext2fs_set_tstamp(super, s_lastcheck, ext2fsP_get_time(fs)); super->s_creator_os = CREATOR_OS; diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c index 8686f99..c9389a2 100644 --- a/lib/ext2fs/inode.c +++ b/lib/ext2fs/inode.c @@ -1042,7 +1042,7 @@ errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino, int size = EXT2_INODE_SIZE(fs->super); struct ext2_inode_large *large_inode; errcode_t retval; - time_t t = fs->now ? fs->now : time(NULL); + time_t t = ext2fsP_get_time(fs); if (!ext2fs_inode_xtime_get(inode, i_atime)) ext2fs_inode_xtime_set(inode, i_atime, t); diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c index 4a947b6..27cdfa0 100644 --- a/lib/ext2fs/mkjournal.c +++ b/lib/ext2fs/mkjournal.c @@ -20,7 +20,6 @@ #include #endif #include -#include #if HAVE_SYS_STAT_H #include #endif @@ -36,7 +35,7 @@ #include "ext2_fs.h" #include "e2p/e2p.h" -#include "ext2fs.h" +#include "ext2fsP.h" #include "kernel-jbd.h" @@ -313,7 +312,7 @@ 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); - now = fs->now ? fs->now : time(0); + now = ext2fsP_get_time(fs); ext2fs_inode_xtime_set(&inode, i_mtime, now); ext2fs_inode_xtime_set(&inode, i_ctime, now); inode.i_links_count = 1; diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index ed2f7c3..2b8e0e7 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -149,9 +149,15 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; fs->umask = 022; - time_env = ext2fs_safe_getenv("E2FSPROGS_FAKE_TIME"); - if (time_env) + time_env = ext2fs_safe_getenv("SOURCE_DATE_EPOCH"); + if (time_env) { fs->now = strtoul(time_env, NULL, 0); + fs->flags2 |= EXT2_FLAG2_USE_FAKE_TIME; + } else { + time_env = ext2fs_safe_getenv("E2FSPROGS_FAKE_TIME"); + if (time_env) + fs->now = strtoul(time_env, NULL, 0); + } retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name); if (retval) diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c index ed89741..913eb9a 100644 --- a/lib/ext2fs/orphan.c +++ b/lib/ext2fs/orphan.c @@ -185,7 +185,7 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks) if (err) goto out; ext2fs_iblk_set(fs, &inode, 0); - now = fs->now ? fs->now : time(0); + now = ext2fsP_get_time(fs); ext2fs_inode_xtime_set(&inode, i_atime, now); ext2fs_inode_xtime_set(&inode, i_ctime, now); ext2fs_inode_xtime_set(&inode, i_mtime, now); diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c index 8d2a086..3349648 100644 --- a/lib/ext2fs/res_gdt.c +++ b/lib/ext2fs/res_gdt.c @@ -15,7 +15,7 @@ #include #include #include "ext2_fs.h" -#include "ext2fs.h" +#include "ext2fsP.h" /* * Iterate through the groups which hold BACKUP superblock/GDT copies in an @@ -143,7 +143,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs) retval = ext2fs_inode_size_set(fs, &inode, inode_size); if (retval) goto out_free; - inode.i_ctime = fs->now ? fs->now : time(0); + inode.i_ctime = ext2fsP_get_time(fs); } for (rsv_off = 0, gdt_off = fs->desc_blocks, @@ -235,7 +235,7 @@ out_inode: EXT2_I_SIZE(&inode)); #endif if (inode_dirty) { - time_t now = fs->now ? fs->now : time(0); + time_t now = ext2fsP_get_time(fs); ext2fs_inode_xtime_set(&inode, i_atime, now); ext2fs_inode_xtime_set(&inode, i_mtime, now); -- 1.8.3.1