[PATCH 5/9] fs: ext4: set inode timestamps on write
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Mon May 18 07:57:24 CEST 2026
Replace the hardcoded zero timestamp in ext4fs_write() with the actual
current time obtained from the RTC when CONFIG_DM_RTC is enabled.
Per the ext2/3/4 specification (ext2 design document, section 4.2):
i_mtime last data modification time
i_ctime last inode change time (the 'c' stands for 'change', not
'create'; this is not a creation timestamp)
i_atime last access time
All three fields are set to the same value since writing data modifies
both the file content (mtime) and the inode metadata (ctime), and any
write also constitutes an access (atime). If no RTC is available, the
timestamp falls back to 2000-01-01 00:00:00 UTC, matching the FAT
write driver behaviour.
The ext4 i_crtime field (true file creation time, added in ext4) is
stored in the extra inode area beyond the base 128-byte inode and is
not modelled by struct ext2_inode, so it cannot be set here.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
fs/ext4/ext4_write.c | 41 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 1abedcede72..c8a1ca63605 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -21,14 +21,47 @@
*/
#include <blk.h>
+#include <dm/uclass.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
#include <part.h>
+#include <rtc.h>
#include <linux/stat.h>
#include <div64.h>
#include "ext4_common.h"
+/**
+ * define EXT4_TIMESTAMP_Y2K - 2000-01-01 00:00:00 UTC as a POSIX timestamp
+ *
+ * Used as a fallback timestamp when no RTC is available.
+ */
+#define EXT4_TIMESTAMP_Y2K 946684800
+
+/**
+ * ext4_current_timestamp() - get current time as a POSIX timestamp
+ *
+ * Returns the current time as seconds since the Unix epoch.
+ * Falls back to 2000-01-01 00:00:00 UTC if the RTC is unavailable,
+ * matching the behaviour of the FAT write driver.
+ */
+static time_t ext4_current_timestamp(void)
+{
+ if (CONFIG_IS_ENABLED(DM_RTC)) {
+ struct udevice *dev;
+ struct rtc_time tm;
+
+ uclass_first_device(UCLASS_RTC, &dev);
+ if (!dev)
+ goto fallback;
+ if (dm_rtc_get(dev, &tm))
+ goto fallback;
+ return rtc_mktime(&tm);
+ }
+fallback:
+ return EXT4_TIMESTAMP_Y2K;
+}
+
static inline void ext4fs_sb_free_inodes_inc(struct ext2_sblock *sb)
{
sb->free_inodes = cpu_to_le32(le32_to_cpu(sb->free_inodes) + 1);
@@ -854,7 +887,7 @@ int ext4fs_write(const char *fname, const char *buffer,
unsigned char *inode_buffer = NULL;
int parent_inodeno;
int inodeno;
- time_t timestamp = 0;
+ time_t timestamp = ext4_current_timestamp();
uint64_t bytes_reqd_for_file;
unsigned int blks_reqd_for_file;
@@ -979,7 +1012,11 @@ int ext4fs_write(const char *fname, const char *buffer,
}
if (existing_file_inode)
free(existing_file_inode);
- /* ToDo: Update correct time */
+ /*
+ * Note: ext4 i_crtime (true creation time) lives in the extended
+ * inode area beyond the base 128-byte inode and is not modelled
+ * by struct ext2_inode, so it cannot be set here.
+ */
file_inode->mtime = cpu_to_le32(timestamp);
file_inode->atime = cpu_to_le32(timestamp);
file_inode->ctime = cpu_to_le32(timestamp);
--
2.53.0
More information about the U-Boot
mailing list