[PATCH 2/9] fs: print change date in directory listing for FAT
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Mon May 18 07:57:21 CEST 2026
fs_ls_generic() displays file sizes but no timestamps. The FAT
filesystem stores a change date in every directory entry and already
populates fs_dirent::change_time in fat_readdir(). Print the date
alongside the file size for filesystems that provide it.
Add a u32 capability bitmap (caps) to struct fstype_info. Each bit
documents a property that the filesystem's readdir() implementation
guarantees:
FS_CAP_DATE BIT(0) change_time in fs_dirent is valid
fs_ls_generic() tests FS_CAP_DATE once before the loop to select a
consistent output format for the entire listing:
12345678 2024-03-15 09:30 filename.txt (FAT)
12345678 filename.txt (ext4, squashfs, ...)
Set FS_CAP_DATE for FAT. fat2rtc() loses the __maybe_unused annotation
since it is now called unconditionally outside XPL builds. The attr,
create_time, change_time, and access_time fields that were previously
only populated under CONFIG_EFI_LOADER are now populated whenever
CONFIG_XPL_BUILD is not set.
Extending the feature to another filesystem requires only adding
.caps = FS_CAP_DATE to its fstype_info entry and ensuring its readdir()
fills in fs_dirent::change_time.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
fs/fat/fat.c | 2 +-
fs/fs.c | 38 +++++++++++++++++++++++++++++++++++---
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index c1ccf30771a..7443f5952af 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -1539,7 +1539,7 @@ int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp)
memset(dent, 0, sizeof(*dent));
strcpy(dent->name, dir->itr.name);
- if (CONFIG_IS_ENABLED(EFI_LOADER)) {
+ if (!IS_ENABLED(CONFIG_XPL_BUILD)) {
dent->attr = dir->itr.dent->attr;
fat2rtc(le16_to_cpu(dir->itr.dent->cdate),
le16_to_cpu(dir->itr.dent->ctime), &dent->create_time);
diff --git a/fs/fs.c b/fs/fs.c
index fe62b71c83c..f8e4794c10e 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -38,6 +38,11 @@ static int fs_dev_part;
static struct disk_partition fs_partition;
static int fs_type = FS_TYPE_ANY;
+/*
+ * define FS_CAP_DATE - readdir() populates fs_dirent::change_time
+ */
+#define FS_CAP_DATE BIT(0)
+
struct fstype_info {
int fstype;
char *name;
@@ -50,6 +55,10 @@ struct fstype_info {
* filesystem.
*/
bool null_dev_desc_ok;
+#if !IS_ENABLED(CONFIG_XPL_BUILD)
+ /* Capability flags (FS_CAP_*) */
+ u32 caps;
+#endif
int (*probe)(struct blk_desc *fs_dev_desc,
struct disk_partition *fs_partition);
int (*ls)(const char *dirname);
@@ -98,10 +107,19 @@ static inline int fs_ls_unsupported(const char *dirname)
return -1;
}
+/* Forward declaration - defined after fstypes[] */
+static struct fstype_info *fs_get_info(int fstype);
+
/* generic implementation of ls in terms of opendir/readdir/closedir */
__maybe_unused
static int fs_ls_generic(const char *dirname)
{
+#if !IS_ENABLED(CONFIG_XPL_BUILD)
+ struct fstype_info *info = fs_get_info(fs_type);
+ bool has_date = !!(info->caps & FS_CAP_DATE);
+#else
+ bool has_date = false;
+#endif
struct fs_dir_stream *dirs;
struct fs_dirent *dent;
int nfiles = 0, ndirs = 0;
@@ -112,15 +130,26 @@ static int fs_ls_generic(const char *dirname)
while ((dent = fs_readdir(dirs))) {
if (dent->type == FS_DT_DIR) {
- printf(" %s/\n", dent->name);
+ printf(" ");
ndirs++;
} else if (dent->type == FS_DT_LNK) {
- printf(" <SYM> %s\n", dent->name);
+ printf(" <SYM> ");
nfiles++;
} else {
- printf(" %8lld %s\n", dent->size, dent->name);
+ printf(" %8lld ", dent->size);
nfiles++;
}
+ if (has_date)
+ printf("%04d-%02d-%02d %02d:%02d ",
+ dent->change_time.tm_year,
+ dent->change_time.tm_mon,
+ dent->change_time.tm_mday,
+ dent->change_time.tm_hour,
+ dent->change_time.tm_min);
+ if (dent->type == FS_DT_DIR)
+ printf("%s/\n", dent->name);
+ else
+ printf("%s\n", dent->name);
}
fs_closedir(dirs);
@@ -196,6 +225,9 @@ static struct fstype_info fstypes[] = {
.fstype = FS_TYPE_FAT,
.name = "fat",
.null_dev_desc_ok = false,
+#if !IS_ENABLED(CONFIG_XPL_BUILD)
+ .caps = FS_CAP_DATE,
+#endif
.probe = fat_set_blk_dev,
.close = fat_close,
.ls = fs_ls_generic,
--
2.53.0
More information about the U-Boot
mailing list