[Concept,4/8] ext4l: Rename ext4l_probe() to ext4l_mount()

Message ID 20260411003647.2592586-5-sjg@u-boot.org
State New
Headers
Series ext4l: Support multiple concurrent VFS mounts |

Commit Message

Simon Glass April 11, 2026, 12:36 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

The name ext4l_probe() comes from the legacy filesystem interface
where each operation re-mounts the filesystem. Rename the internal
function to ext4l_mount() which better describes what it does.

ext4l_mount() takes a struct ext4l_state pointer and a struct udevice
so the caller can provide per-mount state and a proper block device.
It zeroes the state at entry so callers do not need to pre-initialise
it.

The legacy ext4l_probe() wrapper allocates the global state, handles
auto-unmount of any previous mount, and converts blk_desc to udevice
before calling ext4l_mount()

Also handle unmount in the same way.

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

 fs/ext4l/interface.c | 77 ++++++++++++++++++++++++++------------------
 include/ext4l.h      | 24 ++++++++++++--
 2 files changed, 67 insertions(+), 34 deletions(-)
  

Patch

diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c
index 7cc739042eb..5a7d65fafdc 100644
--- a/fs/ext4l/interface.c
+++ b/fs/ext4l/interface.c
@@ -10,6 +10,7 @@ 
  */
 
 #include <blk.h>
+#include <dm.h>
 #include <env.h>
 #include <ext4l.h>
 #include <fs.h>
@@ -108,15 +109,14 @@  int ext4l_statfs(struct fs_statfs *stats)
 }
 
 /**
- * ext4l_set_blk_dev() - Set the block device for ext4l operations
+ * ext4l_set_blk() - Set the block device for ext4l operations
  *
- * @blk_dev: Block device descriptor
+ * @blk: Block device descriptor
  * @partition: Partition info (can be NULL for whole disk)
  */
-void ext4l_set_blk_dev(struct udevice *blk_dev,
-		       struct disk_partition *partition)
+void ext4l_set_blk(struct udevice *blk, struct disk_partition *partition)
 {
-	efs.blk = blk_dev;
+	efs.blk = blk;
 	if (partition)
 		memcpy(&efs.partition, partition, sizeof(efs.partition));
 	else
@@ -125,9 +125,9 @@  void ext4l_set_blk_dev(struct udevice *blk_dev,
 }
 
 /**
- * ext4l_clear_blk_dev() - Clear block device (unmount)
+ * ext4l_clear_blk() - Clear block device (unmount)
  */
-void ext4l_clear_blk_dev(void)
+void ext4l_clear_blk(void)
 {
 	/* Clear buffer cache before unmounting */
 	bh_cache_clear();
@@ -207,31 +207,32 @@  static void ext4l_free_sb(struct super_block *sb, bool skip_io)
 	kfree(sbi->s_blockgroup_lock);
 	kfree(sbi);
 
-	/* Free structures allocated in ext4l_probe() */
+	/* Free structures allocated in ext4l_mount() */
 	kfree(sb->s_bdev->bd_mapping);
 	kfree(sb->s_bdev);
 	kfree(sb);
 }
 
 /**
- * ext4l_close_internal() - Internal close function
+ * ext4l_umount_internal() - Internal close function
+ * @state: Per-mount state to initialise
  * @skip_io: If true, skip all I/O operations (for forced close)
  *
- * When called from the safeguard in ext4l_probe(), the device may be
+ * When called from the safeguard in ext4l_mount(), the device may be
  * invalid (rebound to a different file), so skip_io should be true to
  * avoid crashes when trying to write to the device.
  */
-static void ext4l_close_internal(bool skip_io)
+static void ext4l_umount_internal(struct ext4l_state *state, bool skip_io)
 {
-	struct super_block *sb = efs.sb;
+	struct super_block *sb = state->sb;
 
-	if (efs.open_dirs > 0)
+	if (state->open_dirs > 0)
 		return;
 
 	if (sb)
 		ext4l_free_sb(sb, skip_io);
 
-	efs.sb = NULL;
+	state->sb = NULL;
 
 	/*
 	 * Force cleanup of any remaining journal_heads before clearing
@@ -242,7 +243,7 @@  static void ext4l_close_internal(bool skip_io)
 	 */
 	bh_cache_release_jbd();
 
-	ext4l_clear_blk_dev();
+	ext4l_clear_blk();
 
 	/*
 	 * Clean up ext4 and JBD2 global state so it can be properly
@@ -263,9 +264,10 @@  static void ext4l_close_internal(bool skip_io)
 	destroy_inodecache();
 }
 
-int ext4l_probe(struct blk_desc *fs_dev_desc,
+int ext4l_mount(struct ext4l_state *state, struct udevice *dev,
 		struct disk_partition *fs_partition)
 {
+	struct blk_desc *fs_dev_desc = dev_get_uclass_plat(dev);
 	struct ext4_fs_context *ctx;
 	struct super_block *sb;
 	struct fs_context *fc;
@@ -274,19 +276,10 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 	u8 *buf;
 	int ret;
 
-	if (!fs_dev_desc)
-		return -EINVAL;
+	memset(state, '\0', sizeof(*state));
 
-	/*
-	 * Ensure any previous mount is properly closed before mounting again.
-	 * This prevents resource leaks if probe is called without close.
-	 *
-	 * Since we're being called while a previous mount exists, we can't
-	 * trust the old device state (it may have been rebound to a different
-	 * file). Use skip_io=true to skip all I/O during close.
-	 */
-	if (efs.sb)
-		ext4l_close_internal(true);
+	if (!dev)
+		return -EINVAL;
 
 	/* Initialise message buffer for recording ext4 messages */
 	ext4l_msg_init();
@@ -393,7 +386,7 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 	}
 
 	/* Set block device for buffer I/O */
-	ext4l_set_blk_dev(fs_dev_desc->bdev, fs_partition);
+	ext4l_set_blk(dev, fs_partition);
 
 	/*
 	 * Test if device supports writes by writing back the same data.
@@ -415,7 +408,7 @@  int ext4l_probe(struct blk_desc *fs_dev_desc,
 	}
 
 	/* Store super_block for later operations */
-	efs.sb = sb;
+	state->sb = sb;
 
 	/* Free mount context - no longer needed after successful mount */
 	kfree(ctx);
@@ -444,6 +437,23 @@  err_exit_es:
 	return ret;
 }
 
+int ext4l_probe(struct blk_desc *fs_dev_desc,
+		struct disk_partition *fs_partition)
+{
+	if (!fs_dev_desc)
+		return -EINVAL;
+
+	/*
+	 * The legacy interface may call probe without a preceding close.
+	 * Clean up any previous mount to prevent resource leaks. Use
+	 * skip_io=true because the old device may have been rebound.
+	 */
+	if (efs.sb)
+		ext4l_umount_internal(&efs, true);
+
+	return ext4l_mount(&efs, fs_dev_desc->bdev, fs_partition);
+}
+
 /**
  * ext4l_read_symlink() - Read the target of a symlink inode
  *
@@ -1347,9 +1357,14 @@  out_old:
 	return ret;
 }
 
+void ext4l_umount(struct ext4l_state *state)
+{
+	ext4l_umount_internal(state, false);
+}
+
 void ext4l_close(void)
 {
-	ext4l_close_internal(false);
+	ext4l_umount(&efs);
 }
 
 /**
diff --git a/include/ext4l.h b/include/ext4l.h
index 19fbe8a7fa2..5ef1cc0a30f 100644
--- a/include/ext4l.h
+++ b/include/ext4l.h
@@ -43,18 +43,36 @@  struct ext4l_state {
 #endif
 
 /**
- * ext4l_probe() - Probe a block device for an ext4 filesystem
+ * ext4l_mount() - Mount an ext4 filesystem
  *
- * @fs_dev_desc: Block device descriptor
+ * @state: Per-mount state to initialise
+ * @dev: Block device (struct udevice)
  * @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_mount(struct ext4l_state *state, struct udevice *dev,
+		struct disk_partition *fs_partition);
+
+/**
+ * ext4l_probe() - Legacy probe: mount using the global state
+ *
+ * @fs_dev_desc: Block device descriptor
+ * @fs_partition: Partition information
+ * Return: 0 on success, negative on error
+ */
 int ext4l_probe(struct blk_desc *fs_dev_desc,
 		struct disk_partition *fs_partition);
 
 /**
- * ext4l_close() - Close the ext4 filesystem
+ * ext4l_umount() - Unmount an ext4 filesystem
+ *
+ * @state: Per-mount state to tear down
+ */
+void ext4l_umount(struct ext4l_state *state);
+
+/**
+ * ext4l_close() - Legacy close: unmount using the global state
  */
 void ext4l_close(void);