[Concept,09/14] linux: jbd2: Add jbd2_journal_exit_global for clean shutdown

Message ID 20251230205157.3383926-10-sjg@u-boot.org
State New
Headers
Series ext4l: Linux adaptation patches for ext4 write support |

Commit Message

Simon Glass Dec. 30, 2025, 8:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

In U-Boot, filesystems may be mounted and unmounted multiple times in a
single session. The JBD2 global state (caches) was only initialized once
and never cleaned up, preventing proper reinitialization.

Add jbd2_journal_exit_global() to properly destroy caches and reset the
initialization flag. This allows the JBD2 subsystem to be cleanly
reinitialized on subsequent mounts.

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

 fs/jbd2/journal.c    | 33 +++++++++++++++++++++++++++++++++
 include/linux/jbd2.h |  1 +
 2 files changed, 34 insertions(+)
  

Patch

diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 138b650fae9..f6478c6ca94 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -3140,6 +3140,10 @@  static int __init journal_init(void)
 	return ret;
 }
 
+#ifdef __UBOOT__
+static bool jbd2_initialized;
+#endif
+
 /**
  * jbd2_journal_init_global() - Initialize JBD2 global state
  *
@@ -3150,18 +3154,47 @@  static int __init journal_init(void)
  */
 int jbd2_journal_init_global(void)
 {
+#ifdef __UBOOT__
+	if (jbd2_initialized)
+		return 0;
+#else
 	static bool initialized;
 
 	if (initialized)
 		return 0;
+#endif
 
 	if (journal_init())
 		return -ENOMEM;
 
+#ifdef __UBOOT__
+	jbd2_initialized = true;
+#else
 	initialized = true;
+#endif
 	return 0;
 }
 
+#ifdef __UBOOT__
+/**
+ * jbd2_journal_exit_global() - Clean up JBD2 global state
+ *
+ * This should be called when unmounting the last ext4 filesystem to
+ * properly clean up all JBD2 caches and reset global state. This is
+ * important in U-Boot where we may mount/unmount filesystems multiple
+ * times in a single session.
+ */
+void jbd2_journal_exit_global(void)
+{
+	if (!jbd2_initialized)
+		return;
+
+	jbd2_remove_jbd_stats_proc_entry();
+	jbd2_journal_destroy_caches();
+	jbd2_initialized = false;
+}
+#endif
+
 static void __exit journal_exit(void)
 {
 #ifdef CONFIG_JBD2_DEBUG
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 41725fb42af..796d896f70f 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -75,6 +75,7 @@  void __jbd2_debug(int level, const char *file, const char *func,
 extern void *jbd2_alloc(size_t size, gfp_t flags);
 extern void jbd2_free(void *ptr, size_t size);
 extern int jbd2_journal_init_global(void);
+extern void jbd2_journal_exit_global(void);
 
 #define JBD2_MIN_JOURNAL_BLOCKS 1024
 #define JBD2_DEFAULT_FAST_COMMIT_BLOCKS 256