[Concept,13/14] linux: ext4l: Make cache init/exit functions reentrant for U-Boot
Commit Message
From: Simon Glass <simon.glass@canonical.com>
In U-Boot, filesystems may be mounted and unmounted multiple times in a
single session. The ext4 cache initialization functions would fail on
subsequent mounts because the caches were already initialized but pointers
were not reset on exit.
Add early return checks in init functions when already initialized, and
reset cache pointers to NULL in exit functions to allow clean
reinitialization.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
fs/ext4l/block_validity.c | 10 ++++++++++
fs/ext4l/extents_status.c | 6 ++++++
fs/ext4l/mballoc.c | 13 +++++++++++++
3 files changed, 29 insertions(+)
@@ -23,6 +23,12 @@ static struct kmem_cache *ext4_system_zone_cachep;
int __init ext4_init_system_zone(void)
{
+#ifdef __UBOOT__
+ /* Already initialized - skip in multiple mount scenarios */
+ if (ext4_system_zone_cachep)
+ return 0;
+#endif
+
ext4_system_zone_cachep = KMEM_CACHE(ext4_system_zone, 0);
if (ext4_system_zone_cachep == NULL)
return -ENOMEM;
@@ -33,6 +39,10 @@ void ext4_exit_system_zone(void)
{
rcu_barrier();
kmem_cache_destroy(ext4_system_zone_cachep);
+#ifdef __UBOOT__
+ /* Reset pointer for clean reinitialization */
+ ext4_system_zone_cachep = NULL;
+#endif
}
static inline int can_merge(struct ext4_system_zone *entry1,
@@ -189,6 +189,12 @@ static int __revise_pending(struct inode *inode, ext4_lblk_t lblk,
int __init ext4_init_es(void)
{
+#ifdef __UBOOT__
+ /* Already initialized - skip in multiple mount scenarios */
+ if (ext4_es_cachep)
+ return 0;
+#endif
+
ext4_es_cachep = KMEM_CACHE(extent_status, SLAB_RECLAIM_ACCOUNT);
if (ext4_es_cachep == NULL)
return -ENOMEM;
@@ -4008,6 +4008,12 @@ void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid)
int __init ext4_init_mballoc(void)
{
+#ifdef __UBOOT__
+ /* Already initialized - skip in multiple mount scenarios */
+ if (ext4_pspace_cachep)
+ return 0;
+#endif
+
ext4_pspace_cachep = KMEM_CACHE(ext4_prealloc_space,
SLAB_RECLAIM_ACCOUNT);
if (ext4_pspace_cachep == NULL)
@@ -4044,6 +4050,13 @@ void ext4_exit_mballoc(void)
kmem_cache_destroy(ext4_ac_cachep);
kmem_cache_destroy(ext4_free_data_cachep);
ext4_groupinfo_destroy_slabs();
+
+#ifdef __UBOOT__
+ /* Reset pointers for clean reinitialization */
+ ext4_pspace_cachep = NULL;
+ ext4_ac_cachep = NULL;
+ ext4_free_data_cachep = NULL;
+#endif
}
#define EXT4_MB_BITMAP_MARKED_CHECK 0x0001