[PATCH v5] erofs-utils: lib: fix incorrect mtime under -Edot-omitted

zhaoyifan (H) zhaoyifan28 at huawei.com
Mon Jan 19 19:47:00 AEDT 2026


On 2026/1/19 14:55, Gao Xiang wrote:
> From: Yifan Zhao <zhaoyifan28 at huawei.com>
>
> `-Edot-omitted` enables `-E48bits`, which requires specific
> configurations for g_sbi.{epoch, build_time}. Currently, the call to
> `erofs_sb_set_48bit()` occurs too late in the execution flow, causing
> the aforementioned logic to be bypassed and resulting in incorrect
> mtimes for all inodes.
>
> This patch moves time initialization logic into `erofs_importer_init()`
> to resolve this issue.
>
> Signed-off-by: Yifan Zhao <zhaoyifan28 at huawei.com>
> Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>

Tested-by: Yifan Zhao <zhaoyifan28 at huawei.com>


Thanks,

Yifan

> ---
> it seems the previous reply version was broken due to invalid formats.
>
>   include/erofs/config.h   |  1 -
>   include/erofs/importer.h |  1 +
>   lib/config.c             |  1 -
>   lib/importer.c           | 11 +++++++++++
>   mkfs/main.c              | 26 +++++++++++---------------
>   5 files changed, 23 insertions(+), 17 deletions(-)
>
> diff --git a/include/erofs/config.h b/include/erofs/config.h
> index 525a8cd5ebfb..2a84fb515868 100644
> --- a/include/erofs/config.h
> +++ b/include/erofs/config.h
> @@ -58,7 +58,6 @@ struct erofs_configure {
>   	char c_force_chunkformat;
>   	u8 c_mkfs_metabox_algid;
>   	u32 c_max_decompressed_extent_bytes;
> -	u64 c_unix_timestamp;
>   	const char *mount_point;
>   	u32 c_root_xattr_isize;
>   #ifdef EROFS_MT_ENABLED
> diff --git a/include/erofs/importer.h b/include/erofs/importer.h
> index a525b474f1d5..15e247e51b9c 100644
> --- a/include/erofs/importer.h
> +++ b/include/erofs/importer.h
> @@ -41,6 +41,7 @@ struct erofs_importer_params {
>   	u32 pclusterblks_def;
>   	u32 pclusterblks_packed;
>   	s32 pclusterblks_metabox;
> +	s64 build_time;
>   	char force_inodeversion;
>   	bool ignore_mtime;
>   	bool no_datainline;
> diff --git a/lib/config.c b/lib/config.c
> index 16b34fa840d3..5eb0ddeaa851 100644
> --- a/lib/config.c
> +++ b/lib/config.c
> @@ -29,7 +29,6 @@ void erofs_init_configure(void)
>   	cfg.c_dbg_lvl  = EROFS_WARN;
>   	cfg.c_version  = PACKAGE_VERSION;
>   	cfg.c_dry_run  = false;
> -	cfg.c_unix_timestamp = -1;
>   	cfg.c_max_decompressed_extent_bytes = -1;
>   	erofs_stdout_tty = isatty(STDOUT_FILENO);
>   }
> diff --git a/lib/importer.c b/lib/importer.c
> index 958a433b9eaa..d686c519676b 100644
> --- a/lib/importer.c
> +++ b/lib/importer.c
> @@ -23,6 +23,7 @@ void erofs_importer_preset(struct erofs_importer_params *params)
>   		.fixed_uid = -1,
>   		.fixed_gid = -1,
>   		.fsalignblks = 1,
> +		.build_time = -1,
>   	};
>   }
>   
> @@ -83,6 +84,16 @@ int erofs_importer_init(struct erofs_importer *im)
>   
>   	if (params->dot_omitted)
>   		erofs_sb_set_48bit(sbi);
> +
> +	if (params->build_time != -1) {
> +		if (erofs_sb_has_48bit(sbi)) {
> +			sbi->epoch = max_t(s64, 0, params->build_time - UINT32_MAX);
> +			sbi->build_time = params->build_time - sbi->epoch;
> +		} else {
> +			sbi->epoch = params->build_time;
> +		}
> +	}
> +
>   	return 0;
>   
>   out_err:
> diff --git a/mkfs/main.c b/mkfs/main.c
> index b45368f301f3..683c650db519 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -274,8 +274,10 @@ static struct erofsmkfs_cfg {
>   	/* < 0, xattr disabled and >= INT_MAX, always use inline xattrs */
>   	long inlinexattr_tolerance;
>   	bool inode_metazone;
> +	u64 unix_timestamp;
>   } mkfscfg = {
>   	.inlinexattr_tolerance = 2,
> +	.unix_timestamp = -1,
>   };
>   
>   static unsigned int pclustersize_packed, pclustersize_max;
> @@ -1096,8 +1098,8 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
>   			break;
>   
>   		case 'T':
> -			cfg.c_unix_timestamp = strtoull(optarg, &endptr, 0);
> -			if (cfg.c_unix_timestamp == -1 || *endptr != '\0') {
> +			mkfscfg.unix_timestamp = strtoull(optarg, &endptr, 0);
> +			if (mkfscfg.unix_timestamp == -1 || *endptr != '\0') {
>   				erofs_err("invalid UNIX timestamp %s", optarg);
>   				return -EINVAL;
>   			}
> @@ -1576,7 +1578,7 @@ int parse_source_date_epoch(void)
>   			  source_date_epoch);
>   		return -EINVAL;
>   	}
> -	cfg.c_unix_timestamp = epoch;
> +	mkfscfg.unix_timestamp = epoch;
>   	cfg.c_timeinherit = TIMESTAMP_CLAMPING;
>   	return 0;
>   }
> @@ -1702,7 +1704,6 @@ int main(int argc, char **argv)
>   	bool tar_index_512b = false;
>   	struct timeval t;
>   	FILE *blklst = NULL;
> -	s64 mkfs_time = 0;
>   	int err;
>   	u32 crc;
>   
> @@ -1727,17 +1728,12 @@ int main(int argc, char **argv)
>   	}
>   
>   	g_sbi.fixed_nsec = 0;
> -	if (cfg.c_unix_timestamp != -1) {
> -		mkfs_time = cfg.c_unix_timestamp;
> -	} else if (!gettimeofday(&t, NULL)) {
> -		mkfs_time = t.tv_sec;
> -	}
> -	if (erofs_sb_has_48bit(&g_sbi)) {
> -		g_sbi.epoch = max_t(s64, 0, mkfs_time - UINT32_MAX);
> -		g_sbi.build_time = mkfs_time - g_sbi.epoch;
> -	} else {
> -		g_sbi.epoch = mkfs_time;
> -	}
> +	if (mkfscfg.unix_timestamp != -1)
> +		importer_params.build_time = mkfscfg.unix_timestamp;
> +	else if (!gettimeofday(&t, NULL))
> +		importer_params.build_time = t.tv_sec;
> +	else
> +		importer_params.build_time = 0;
>   
>   	err = erofs_dev_open(&g_sbi, cfg.c_img_path, O_RDWR |
>   				(incremental_mode ? 0 : O_TRUNC));


More information about the Linux-erofs mailing list