linux: jbd2: Add jbd2_journal_exit_global for clean shutdown

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>
This commit is contained in:
Simon Glass
2025-12-30 10:58:41 -07:00
parent ae723b8385
commit 5761cf33ab
2 changed files with 34 additions and 0 deletions

View File

@@ -3140,6 +3140,10 @@ static int __init journal_init(void)
return ret; return ret;
} }
#ifdef __UBOOT__
static bool jbd2_initialized;
#endif
/** /**
* jbd2_journal_init_global() - Initialize JBD2 global state * jbd2_journal_init_global() - Initialize JBD2 global state
* *
@@ -3150,18 +3154,47 @@ static int __init journal_init(void)
*/ */
int jbd2_journal_init_global(void) int jbd2_journal_init_global(void)
{ {
#ifdef __UBOOT__
if (jbd2_initialized)
return 0;
#else
static bool initialized; static bool initialized;
if (initialized) if (initialized)
return 0; return 0;
#endif
if (journal_init()) if (journal_init())
return -ENOMEM; return -ENOMEM;
#ifdef __UBOOT__
jbd2_initialized = true;
#else
initialized = true; initialized = true;
#endif
return 0; 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) static void __exit journal_exit(void)
{ {
#ifdef CONFIG_JBD2_DEBUG #ifdef CONFIG_JBD2_DEBUG

View File

@@ -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_alloc(size_t size, gfp_t flags);
extern void jbd2_free(void *ptr, size_t size); extern void jbd2_free(void *ptr, size_t size);
extern int jbd2_journal_init_global(void); extern int jbd2_journal_init_global(void);
extern void jbd2_journal_exit_global(void);
#define JBD2_MIN_JOURNAL_BLOCKS 1024 #define JBD2_MIN_JOURNAL_BLOCKS 1024
#define JBD2_DEFAULT_FAST_COMMIT_BLOCKS 256 #define JBD2_DEFAULT_FAST_COMMIT_BLOCKS 256