[Concept,30/34] fat: Add fat_statfs() to report filesystem statistics

Message ID 20260403140523.1998228-31-sjg@u-boot.org
State New
Headers
Series Add a virtual filesystem (VFS) layer to U-Boot |

Commit Message

Simon Glass April 3, 2026, 2:04 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Add fat_statfs() which reads the FAT metadata and scans the FAT table
to count free clusters, filling in block size, total blocks and free
blocks. This is used by the FAT VFS driver's statfs operation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 fs/fat/fat.c  | 27 +++++++++++++++++++++++++++
 include/fat.h |  8 ++++++++
 2 files changed, 35 insertions(+)
  

Patch

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 42bc7bffb0f..53f610ff2f3 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -697,6 +697,33 @@  static int get_fs_info(struct fsdata *mydata)
 	return 0;
 }
 
+int fat_statfs(struct fs_statfs *stats)
+{
+	struct fsdata fsdata;
+	u32 total_clust, free_clust, entry;
+	int ret;
+
+	ret = get_fs_info(&fsdata);
+	if (ret)
+		return ret;
+
+	total_clust = (fsdata.total_sect - fsdata.data_begin) /
+		      fsdata.clust_size;
+	free_clust = 0;
+	for (entry = 2; entry < total_clust + 2; entry++) {
+		if (!get_fatent(&fsdata, entry))
+			free_clust++;
+	}
+
+	stats->bsize = fsdata.clust_size * fsdata.sect_size;
+	stats->blocks = total_clust;
+	stats->bfree = free_clust;
+
+	free(fsdata.fatbuf);
+
+	return 0;
+}
+
 int fat_itr_root(struct fat_itr *itr, struct fsdata *fsdata)
 {
 	if (get_fs_info(fsdata))
diff --git a/include/fat.h b/include/fat.h
index d08cd5d1c47..e6370c3afb0 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -413,6 +413,14 @@  int fat_rename(const char *old_path, const char *new_path);
  */
 int fat_mkdir(const char *dirname);
 
+/**
+ * fat_statfs() - get filesystem statistics
+ *
+ * @stats: pointer to struct fs_statfs to fill
+ * Return: 0 on success, -ve on error
+ */
+int fat_statfs(struct fs_statfs *stats);
+
 /**
  * fat_close() - close FAT filesystem and release resources
  */