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 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__ */ -- 2.43.0