diff mbox series

[1/1] fs: fat: fill creation and change date

Message ID 20240409200607.61893-1-heinrich.schuchardt@canonical.com
State Accepted
Commit ba23c378c54470923c5dc33f8daff8598da8e2be
Delegated to: Tom Rini
Headers show
Series [1/1] fs: fat: fill creation and change date | expand

Commit Message

Heinrich Schuchardt April 9, 2024, 8:06 p.m. UTC
The FAT specification requires that the change date is set.

If a DM RTC device exists, set the creation and change date to the current
date when updating the directory entry. Otherwise use the date 2020-01-01.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
---
 fs/fat/fat_write.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

Comments

Tom Rini April 18, 2024, 3:40 a.m. UTC | #1
On Tue, 09 Apr 2024 22:06:07 +0200, Heinrich Schuchardt wrote:

> The FAT specification requires that the change date is set.
> 
> If a DM RTC device exists, set the creation and change date to the current
> date when updating the directory entry. Otherwise use the date 2020-01-01.
> 
> 

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 8b5d669b005..c8e0fbf1a3b 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -18,6 +18,7 @@ 
 #include <rand.h>
 #include <asm/byteorder.h>
 #include <asm/cache.h>
+#include <dm/uclass.h>
 #include <linux/ctype.h>
 #include <linux/math64.h>
 #include "fat.c"
@@ -1151,6 +1152,41 @@  getit:
 	return 0;
 }
 
+/**
+ * dentry_set_time() - set change time
+ *
+ * @dentptr:	directory entry
+ */
+static void dentry_set_time(dir_entry *dentptr)
+{
+	if (CONFIG_IS_ENABLED(DM_RTC)) {
+		struct udevice *dev;
+		struct rtc_time tm;
+		u16 date;
+		u16 time;
+
+		uclass_first_device(UCLASS_RTC, &dev);
+		if (!dev)
+			goto err;
+		if (dm_rtc_get(dev, &tm))
+			goto err;
+		if (tm.tm_year < 1980 || tm.tm_year > 2107)
+			goto err;
+		date = (tm.tm_mday & 0x1f) |
+		       ((tm.tm_mon & 0xf) << 5) |
+		       ((tm.tm_year - 1980) << 9);
+		time = (tm.tm_sec > 1) |
+		       ((tm.tm_min & 0x3f) << 5) |
+		(tm.tm_hour << 11);
+		dentptr->date = date;
+		dentptr->time = time;
+		return;
+	}
+err:
+	dentptr->date = 0x2821; /* 2000-01-01 */
+	dentptr->time = 0;
+}
+
 /**
  * fill_dentry() - fill directory entry with shortname
  *
@@ -1171,6 +1207,12 @@  static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
 
 	dentptr->attr = attr;
 
+	/* Set change date */
+	dentry_set_time(dentptr);
+	/* Set creation date */
+	dentptr->cdate = dentptr->date;
+	dentptr->ctime = dentptr->time;
+
 	memcpy(&dentptr->nameext, shortname, SHORT_NAME_SIZE);
 }
 
@@ -1376,6 +1418,8 @@  int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
 
 		/* Update file size in a directory entry */
 		retdent->size = cpu_to_le32(pos + size);
+		/* Update change date */
+		dentry_set_time(retdent);
 	} else {
 		/* Create a new file */
 		char shortname[SHORT_NAME_SIZE];