[Concept,01/26] fs: ext4l: Add minimal probe support

Message ID 20251222115639.700578-2-sjg@u-boot.org
State New
Headers
Series fs: ext4l: Add support for mounting ext4 filesystems (part G) |

Commit Message

Simon Glass Dec. 22, 2025, 11:56 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add a minimal ext4l probe function that:
- Reads the superblock from the block device
- Validates the ext4 magic number
- Returns proper error codes (-EINVAL, -ENOMEM, -EIO)

Create include/ext4l.h header with function declarations and
documentation. Update fs_legacy.c to use the header.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/interface.c | 57 ++++++++++++++++++++++++++++++++++++++++++--
 fs/fs_legacy.c       |  5 ++--
 include/ext4l.h      | 31 ++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 4 deletions(-)
 create mode 100644 include/ext4l.h
  

Patch

diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c
index 455e101b65f..eb625e0b1a5 100644
--- a/fs/ext4l/interface.c
+++ b/fs/ext4l/interface.c
@@ -2,19 +2,72 @@ 
 /*
  * U-Boot interface for ext4l filesystem (Linux port)
  *
+ * Copyright 2025 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ *
  * This provides the minimal interface between U-Boot and the ext4l driver.
- * Currently just stubs - the filesystem doesn't work yet.
  */
 
 #include <blk.h>
 #include <part.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#include "ext4_uboot.h"
+#include "ext4.h"
+
+/* Global state */
+static struct blk_desc *ext4l_dev_desc;
+static struct disk_partition ext4l_part;
 
 int ext4l_probe(struct blk_desc *fs_dev_desc,
 		struct disk_partition *fs_partition)
 {
-	return -1;
+	loff_t part_offset;
+	__le16 *magic;
+	u8 *buf;
+	int ret;
+
+	if (!fs_dev_desc)
+		return -EINVAL;
+
+	buf = malloc(BLOCK_SIZE + 512);
+	if (!buf)
+		return -ENOMEM;
+
+	/* Calculate partition offset in bytes */
+	part_offset = fs_partition ? (loff_t)fs_partition->start * fs_dev_desc->blksz : 0;
+
+	/* Read sectors containing the superblock */
+	if (blk_dread(fs_dev_desc,
+		      (part_offset + BLOCK_SIZE) / fs_dev_desc->blksz,
+		      2, buf) != 2) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Check magic number within superblock */
+	magic = (__le16 *)(buf + (BLOCK_SIZE % fs_dev_desc->blksz) +
+			   offsetof(struct ext4_super_block, s_magic));
+	if (le16_to_cpu(*magic) != EXT4_SUPER_MAGIC) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* Save device info for later operations */
+	ext4l_dev_desc = fs_dev_desc;
+	if (fs_partition)
+		memcpy(&ext4l_part, fs_partition, sizeof(ext4l_part));
+
+	ret = 0;
+out:
+	free(buf);
+	return ret;
 }
 
 void ext4l_close(void)
 {
+	ext4l_dev_desc = NULL;
 }
diff --git a/fs/fs_legacy.c b/fs/fs_legacy.c
index 405aa8aba54..5b96e1465d8 100644
--- a/fs/fs_legacy.c
+++ b/fs/fs_legacy.c
@@ -18,6 +18,7 @@ 
 #include <mapmem.h>
 #include <part.h>
 #include <ext4fs.h>
+#include <ext4l.h>
 #include <fat.h>
 #include <fs_legacy.h>
 #include <sandboxfs.h>
@@ -262,8 +263,8 @@  static struct fstype_info fstypes[] = {
 		.fstype = FS_TYPE_EXT,
 		.name = "ext4",
 		.null_dev_desc_ok = false,
-		.probe = fs_probe_unsupported,
-		.close = fs_close_unsupported,
+		.probe = ext4l_probe,
+		.close = ext4l_close,
 		.ls = fs_ls_unsupported,
 		.exists = fs_exists_unsupported,
 		.size = fs_size_unsupported,
diff --git a/include/ext4l.h b/include/ext4l.h
new file mode 100644
index 00000000000..5a300fd6559
--- /dev/null
+++ b/include/ext4l.h
@@ -0,0 +1,31 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * ext4l filesystem interface
+ *
+ * Copyright 2025 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#ifndef __EXT4L_H__
+#define __EXT4L_H__
+
+struct blk_desc;
+struct disk_partition;
+
+/**
+ * ext4l_probe() - Probe a block device for an ext4 filesystem
+ *
+ * @fs_dev_desc: Block device descriptor
+ * @fs_partition: Partition information
+ * Return: 0 on success, -EINVAL if no device or invalid magic,
+ *	   -ENOMEM on allocation failure, -EIO on read error
+ */
+int ext4l_probe(struct blk_desc *fs_dev_desc,
+		struct disk_partition *fs_partition);
+
+/**
+ * ext4l_close() - Close the ext4 filesystem
+ */
+void ext4l_close(void);
+
+#endif /* __EXT4L_H__ */