[Concept,18/26] fs: ext4l: Initialise super_block and call ext4_fill_super()

Message ID 20251222115639.700578-19-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>

Set up essential super_block fields after allocation:
- Link bd_super back to super_block
- Set initial blocksize to 1024 (will be updated by ext4_fill_super)
- Clear flags for read-write mount
- Clear s_fs_info (will be set by ext4_fill_super)

Add the call to ext4_fill_super() which performs the actual filesystem
mount. This requires making ext4_fill_super() non-static in super.c.

Also fix an uninitialised variable warning in
ext4_journalled_submit_inode_data_buffers().

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

 fs/ext4l/ext4_uboot.h     |  9 ++++++---
 fs/ext4l/extents_status.c |  5 ++++-
 fs/ext4l/interface.c      | 22 ++++++++++++++++------
 fs/ext4l/super.c          |  4 ++--
 4 files changed, 28 insertions(+), 12 deletions(-)
  

Patch

diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index 1f823ba6ea3..7c65aa8567e 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -457,8 +457,8 @@  int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
 /* Memory allocation - use linux/slab.h which is already available */
 #include <linux/slab.h>
 
-/* KMEM_CACHE macro - not in U-Boot's slab.h */
-#define KMEM_CACHE(s, flags)		((struct kmem_cache *)1)
+/* KMEM_CACHE macro - use kmem_cache_create */
+#define KMEM_CACHE(s, flags)		kmem_cache_create(#s, sizeof(struct s), 0, flags, NULL)
 
 /* RB tree operations - stubs */
 #define rb_entry(ptr, type, member) \
@@ -650,7 +650,7 @@  struct super_block {
 	struct rw_semaphore s_umount;
 	struct sb_writers s_writers;
 	struct block_device *s_bdev;
-	const char *s_id;
+	char s_id[32];
 	struct dentry *s_root;
 	uuid_t s_uuid;
 	struct file_system_type *s_type;
@@ -2026,6 +2026,9 @@  struct fs_context {
 	bool silent;
 };
 
+/* ext4 superblock initialisation */
+int ext4_fill_super(struct super_block *sb, struct fs_context *fc);
+
 /* fs_parameter stubs */
 struct fs_parameter {
 	const char *key;
diff --git a/fs/ext4l/extents_status.c b/fs/ext4l/extents_status.c
index 485f3a2f5cc..a3ab26624e7 100644
--- a/fs/ext4l/extents_status.c
+++ b/fs/ext4l/extents_status.c
@@ -197,7 +197,10 @@  int __init ext4_init_es(void)
 
 void ext4_exit_es(void)
 {
-	kmem_cache_destroy(ext4_es_cachep);
+	if (ext4_es_cachep) {
+		kmem_cache_destroy(ext4_es_cachep);
+		ext4_es_cachep = NULL;
+	}
 }
 
 void ext4_es_init_tree(struct ext4_es_tree *tree)
diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c
index 20fdf3c908c..4652f8c835f 100644
--- a/fs/ext4l/interface.c
+++ b/fs/ext4l/interface.c
@@ -76,6 +76,15 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 		goto err_free_bdev;
 	}
 
+	/* Initialise super_block fields */
+	sb->s_bdev->bd_super = sb;
+	sb->s_blocksize = 1024;
+	sb->s_blocksize_bits = 10;
+	snprintf(sb->s_id, sizeof(sb->s_id), "ext4l_mmc%d",
+		 fs_dev_desc->devnum);
+	sb->s_flags = 0;
+	sb->s_fs_info = NULL;
+
 	/* Allocate fs_context */
 	fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL);
 	if (!fc) {
@@ -93,6 +102,7 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 	/* Initialise fs_context fields */
 	fc->fs_private = ctx;
 	fc->sb_flags |= SB_I_VERSION;
+	fc->root = (struct dentry *)sb;	/* Hack: store sb for ext4_fill_super */
 
 	buf = malloc(BLOCK_SIZE + 512);
 	if (!buf) {
@@ -119,17 +129,17 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 		goto err_free_buf;
 	}
 
+	free(buf);
+
 	/* Save device info for later operations */
 	ext4l_dev_desc = fs_dev_desc;
 	if (fs_partition)
 		memcpy(&ext4l_part, fs_partition, sizeof(ext4l_part));
 
-	free(buf);
-	kfree(ctx);
-	kfree(fc);
-	kfree(sb->s_bdev->bd_mapping);
-	kfree(sb->s_bdev);
-	kfree(sb);
+	/* Mount the filesystem */
+	ret = ext4_fill_super(sb, fc);
+	if (ret)
+		goto err_free_ctx;
 
 	return 0;
 
diff --git a/fs/ext4l/super.c b/fs/ext4l/super.c
index af5b9b1986d..f986ca6e0b6 100644
--- a/fs/ext4l/super.c
+++ b/fs/ext4l/super.c
@@ -526,7 +526,7 @@  static int ext4_journalled_submit_inode_data_buffers(struct jbd2_inode *jinode)
 		.range_end = jinode->i_dirty_end,
         };
 	struct folio *folio = NULL;
-	int error;
+	int error = 0;
 
 	/*
 	 * writeback_iter() already checks for dirty pages and calls
@@ -5654,7 +5654,7 @@  out_fail:
 	return err;
 }
 
-static int ext4_fill_super(struct super_block *sb, struct fs_context *fc)
+int ext4_fill_super(struct super_block *sb, struct fs_context *fc)
 {
 	struct ext4_fs_context *ctx = fc->fs_private;
 	struct ext4_sb_info *sbi;