* [PATCH 0/3] Add {init, exit}_sequence_fs() helper function
@ 2024-07-11 7:48 Youling Tang
2024-07-11 7:48 ` [PATCH 1/3] f2fs: make module init/exit match their sequence Youling Tang
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Youling Tang @ 2024-07-11 7:48 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu
Cc: linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, youling.tang
This series provides the {init, exit}_sequence_fs() helper functions and
applies to f2fs and ext4, similar to btrfs.
Youling Tang (3):
f2fs: make module init/exit match their sequence
ext4: make module init/exit match their sequence
fs: Add {init, exit}_sequence_fs() helper function
fs/btrfs/super.c | 36 +--------
fs/ext4/super.c | 142 +++++++++++++++---------------------
fs/f2fs/debug.c | 3 +-
fs/f2fs/f2fs.h | 4 +-
fs/f2fs/super.c | 178 ++++++++++++++++++---------------------------
include/linux/fs.h | 38 ++++++++++
6 files changed, 173 insertions(+), 228 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] f2fs: make module init/exit match their sequence
2024-07-11 7:48 [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Youling Tang
@ 2024-07-11 7:48 ` Youling Tang
2024-07-11 7:48 ` [PATCH 2/3] ext4: make ext4 " Youling Tang
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Youling Tang @ 2024-07-11 7:48 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu
Cc: linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, youling.tang, Youling Tang
From: Youling Tang <tangyouling@kylinos.cn>
Use init_sequence to ensure that modules init and exit are in sequence
and to simplify the code.
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
fs/f2fs/debug.c | 3 +-
fs/f2fs/f2fs.h | 4 +-
fs/f2fs/super.c | 210 ++++++++++++++++++++++++------------------------
3 files changed, 107 insertions(+), 110 deletions(-)
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index 8b0e1e71b667..c08ecf807066 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -727,7 +727,7 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
kfree(si);
}
-void __init f2fs_create_root_stats(void)
+int __init f2fs_create_root_stats(void)
{
#ifdef CONFIG_DEBUG_FS
f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL);
@@ -735,6 +735,7 @@ void __init f2fs_create_root_stats(void)
debugfs_create_file("status", 0444, f2fs_debugfs_root, NULL,
&stat_fops);
#endif
+ return 0;
}
void f2fs_destroy_root_stats(void)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 1974b6aff397..d546bd301565 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4086,7 +4086,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
int f2fs_build_stats(struct f2fs_sb_info *sbi);
void f2fs_destroy_stats(struct f2fs_sb_info *sbi);
-void __init f2fs_create_root_stats(void);
+int __init f2fs_create_root_stats(void);
void f2fs_destroy_root_stats(void);
void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
#else
@@ -4128,7 +4128,7 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; }
static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { }
-static inline void __init f2fs_create_root_stats(void) { }
+static inline int __init f2fs_create_root_stats(void) { }
static inline void f2fs_destroy_root_stats(void) { }
static inline void f2fs_update_sit_info(struct f2fs_sb_info *sbi) {}
#endif
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1f1b3647a998..19509942b837 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4940,120 +4940,116 @@ static void destroy_inodecache(void)
kmem_cache_destroy(f2fs_inode_cachep);
}
-static int __init init_f2fs_fs(void)
+static int register_f2fs(void)
{
- int err;
+ return register_filesystem(&f2fs_fs_type);
+}
- err = init_inodecache();
- if (err)
- goto fail;
- err = f2fs_create_node_manager_caches();
- if (err)
- goto free_inodecache;
- err = f2fs_create_segment_manager_caches();
- if (err)
- goto free_node_manager_caches;
- err = f2fs_create_checkpoint_caches();
- if (err)
- goto free_segment_manager_caches;
- err = f2fs_create_recovery_cache();
- if (err)
- goto free_checkpoint_caches;
- err = f2fs_create_extent_cache();
- if (err)
- goto free_recovery_cache;
- err = f2fs_create_garbage_collection_cache();
- if (err)
- goto free_extent_cache;
- err = f2fs_init_sysfs();
- if (err)
- goto free_garbage_collection_cache;
- err = f2fs_init_shrinker();
- if (err)
- goto free_sysfs;
- err = register_filesystem(&f2fs_fs_type);
- if (err)
- goto free_shrinker;
- f2fs_create_root_stats();
- err = f2fs_init_post_read_processing();
- if (err)
- goto free_root_stats;
- err = f2fs_init_iostat_processing();
- if (err)
- goto free_post_read;
- err = f2fs_init_bio_entry_cache();
- if (err)
- goto free_iostat;
- err = f2fs_init_bioset();
- if (err)
- goto free_bio_entry_cache;
- err = f2fs_init_compress_mempool();
- if (err)
- goto free_bioset;
- err = f2fs_init_compress_cache();
- if (err)
- goto free_compress_mempool;
- err = f2fs_create_casefold_cache();
- if (err)
- goto free_compress_cache;
- return 0;
-free_compress_cache:
- f2fs_destroy_compress_cache();
-free_compress_mempool:
- f2fs_destroy_compress_mempool();
-free_bioset:
- f2fs_destroy_bioset();
-free_bio_entry_cache:
- f2fs_destroy_bio_entry_cache();
-free_iostat:
- f2fs_destroy_iostat_processing();
-free_post_read:
- f2fs_destroy_post_read_processing();
-free_root_stats:
- f2fs_destroy_root_stats();
+static void unregister_f2fs(void)
+{
unregister_filesystem(&f2fs_fs_type);
-free_shrinker:
- f2fs_exit_shrinker();
-free_sysfs:
- f2fs_exit_sysfs();
-free_garbage_collection_cache:
- f2fs_destroy_garbage_collection_cache();
-free_extent_cache:
- f2fs_destroy_extent_cache();
-free_recovery_cache:
- f2fs_destroy_recovery_cache();
-free_checkpoint_caches:
- f2fs_destroy_checkpoint_caches();
-free_segment_manager_caches:
- f2fs_destroy_segment_manager_caches();
-free_node_manager_caches:
- f2fs_destroy_node_manager_caches();
-free_inodecache:
- destroy_inodecache();
-fail:
- return err;
+}
+
+/* Helper structure for long init/exit functions. */
+struct init_sequence {
+ int (*init_func)(void);
+ /* Can be NULL if the init_func doesn't need cleanup. */
+ void (*exit_func)(void);
+};
+
+static const struct init_sequence mod_init_seq[] = {
+ {
+ .init_func = init_inodecache,
+ .exit_func = destroy_inodecache,
+ }, {
+ .init_func = f2fs_create_node_manager_caches,
+ .exit_func = f2fs_destroy_node_manager_caches,
+ }, {
+ .init_func = f2fs_create_segment_manager_caches,
+ .exit_func = f2fs_destroy_segment_manager_caches,
+ }, {
+ .init_func = f2fs_create_checkpoint_caches,
+ .exit_func = f2fs_destroy_checkpoint_caches,
+ }, {
+ .init_func = f2fs_create_recovery_cache,
+ .exit_func = f2fs_destroy_recovery_cache,
+ }, {
+ .init_func = f2fs_create_extent_cache,
+ .exit_func = f2fs_destroy_extent_cache,
+ }, {
+ .init_func = f2fs_create_garbage_collection_cache,
+ .exit_func = f2fs_destroy_garbage_collection_cache,
+ }, {
+ .init_func = f2fs_init_sysfs,
+ .exit_func = f2fs_exit_sysfs,
+ }, {
+ .init_func = f2fs_init_shrinker,
+ .exit_func = f2fs_exit_shrinker,
+ }, {
+ .init_func = register_f2fs,
+ .exit_func = unregister_f2fs,
+ }, {
+ .init_func = f2fs_create_root_stats,
+ .exit_func = f2fs_destroy_root_stats,
+ }, {
+ .init_func = f2fs_init_post_read_processing,
+ .exit_func = f2fs_destroy_post_read_processing,
+ }, {
+ .init_func = f2fs_init_iostat_processing,
+ .exit_func = f2fs_destroy_iostat_processing,
+ }, {
+ .init_func = f2fs_init_bio_entry_cache,
+ .exit_func = f2fs_destroy_bio_entry_cache,
+ }, {
+ .init_func = f2fs_init_bioset,
+ .exit_func = f2fs_destroy_bioset,
+ }, {
+ .init_func = f2fs_init_compress_mempool,
+ .exit_func = f2fs_destroy_compress_mempool,
+ }, {
+ .init_func = f2fs_init_compress_cache,
+ .exit_func = f2fs_destroy_compress_cache,
+ }, {
+ .init_func = f2fs_create_casefold_cache,
+ .exit_func = f2fs_destroy_casefold_cache,
+ }
+};
+
+static bool mod_init_result[ARRAY_SIZE(mod_init_seq)];
+
+static __always_inline void f2fs_exit_f2fs_fs(void)
+{
+ int i;
+
+ for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) {
+ if (!mod_init_result[i])
+ continue;
+ if (mod_init_seq[i].exit_func)
+ mod_init_seq[i].exit_func();
+ mod_init_result[i] = false;
+ }
}
static void __exit exit_f2fs_fs(void)
{
- f2fs_destroy_casefold_cache();
- f2fs_destroy_compress_cache();
- f2fs_destroy_compress_mempool();
- f2fs_destroy_bioset();
- f2fs_destroy_bio_entry_cache();
- f2fs_destroy_iostat_processing();
- f2fs_destroy_post_read_processing();
- f2fs_destroy_root_stats();
- unregister_filesystem(&f2fs_fs_type);
- f2fs_exit_shrinker();
- f2fs_exit_sysfs();
- f2fs_destroy_garbage_collection_cache();
- f2fs_destroy_extent_cache();
- f2fs_destroy_recovery_cache();
- f2fs_destroy_checkpoint_caches();
- f2fs_destroy_segment_manager_caches();
- f2fs_destroy_node_manager_caches();
- destroy_inodecache();
+ f2fs_exit_f2fs_fs();
+}
+
+static int __init init_f2fs_fs(void)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) {
+ BUG_ON(mod_init_result[i]);
+ ret = mod_init_seq[i].init_func();
+ if (ret < 0) {
+ f2fs_exit_f2fs_fs();
+ return ret;
+ }
+ mod_init_result[i] = true;
+ }
+ return 0;
}
module_init(init_f2fs_fs)
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] ext4: make ext4 init/exit match their sequence
2024-07-11 7:48 [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Youling Tang
2024-07-11 7:48 ` [PATCH 1/3] f2fs: make module init/exit match their sequence Youling Tang
@ 2024-07-11 7:48 ` Youling Tang
2024-07-11 7:48 ` [PATCH 3/3] fs: Add {init, exit}_sequence_fs() helper functions Youling Tang
2024-07-11 8:26 ` [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Christoph Hellwig
3 siblings, 0 replies; 7+ messages in thread
From: Youling Tang @ 2024-07-11 7:48 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu
Cc: linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, youling.tang, Youling Tang
From: Youling Tang <tangyouling@kylinos.cn>
Use init_sequence to ensure that modules init and exit are in sequence
and to simplify the code.
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
fs/ext4/super.c | 175 +++++++++++++++++++++++++-----------------------
1 file changed, 93 insertions(+), 82 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index c682fb927b64..ec1e63facb10 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -7314,103 +7314,114 @@ static struct file_system_type ext4_fs_type = {
};
MODULE_ALIAS_FS("ext4");
-/* Shared across all ext4 file systems */
-wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
-
-static int __init ext4_init_fs(void)
+static int register_ext(void)
{
- int i, err;
-
- ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64);
- ext4_li_info = NULL;
+ register_as_ext3();
+ register_as_ext2();
+ return register_filesystem(&ext4_fs_type);
+}
- /* Build-time check for flags consistency */
- ext4_check_flag_values();
+static void unregister_ext(void)
+{
+ unregister_as_ext2();
+ unregister_as_ext3();
+ unregister_filesystem(&ext4_fs_type);
+}
- for (i = 0; i < EXT4_WQ_HASH_SZ; i++)
- init_waitqueue_head(&ext4__ioend_wq[i]);
+/* Helper structure for long init/exit functions. */
+struct init_sequence {
+ int (*init_func)(void);
+ /* Can be NULL if the init_func doesn't need cleanup. */
+ void (*exit_func)(void);
+};
- err = ext4_init_es();
- if (err)
- return err;
+static const struct init_sequence mod_init_seq[] = {
+ {
+ .init_func = ext4_init_es,
+ .exit_func = ext4_exit_es,
+ }, {
+ .init_func = ext4_init_pending,
+ .exit_func = ext4_exit_pending,
+ }, {
+ .init_func = ext4_init_post_read_processing,
+ .exit_func = ext4_exit_post_read_processing,
+ }, {
+ .init_func = ext4_init_pageio,
+ .exit_func = ext4_exit_pageio,
+ }, {
+ .init_func = ext4_init_system_zone,
+ .exit_func = ext4_exit_system_zone,
+ }, {
+ .init_func = ext4_init_sysfs,
+ .exit_func = ext4_exit_sysfs,
+ }, {
+ .init_func = ext4_init_mballoc,
+ .exit_func = ext4_exit_mballoc,
+ }, {
+ .init_func = init_inodecache,
+ .exit_func = destroy_inodecache,
+ }, {
+ .init_func = ext4_fc_init_dentry_cache,
+ .exit_func = ext4_fc_destroy_dentry_cache,
+ }, {
+ .init_func = register_ext,
+ .exit_func = unregister_ext,
+ }
+};
- err = ext4_init_pending();
- if (err)
- goto out7;
+static bool mod_init_result[ARRAY_SIZE(mod_init_seq)];
- err = ext4_init_post_read_processing();
- if (err)
- goto out6;
+static __always_inline void ext4_exit_ext4_fs(void)
+{
+ int i;
- err = ext4_init_pageio();
- if (err)
- goto out5;
+ for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) {
+ if (!mod_init_result[i])
+ continue;
+ if (mod_init_seq[i].exit_func)
+ mod_init_seq[i].exit_func();
+ mod_init_result[i] = false;
+ }
+}
- err = ext4_init_system_zone();
- if (err)
- goto out4;
+static void __exit ext4_exit_fs(void)
+{
+ ext4_destroy_lazyinit_thread();
+ ext4_exit_ext4_fs();
+}
- err = ext4_init_sysfs();
- if (err)
- goto out3;
+static __always_inline int ext4_init_ext4_fs(void)
+{
+ int ret;
+ int i;
- err = ext4_init_mballoc();
- if (err)
- goto out2;
- err = init_inodecache();
- if (err)
- goto out1;
+ for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) {
+ ASSERT(!mod_init_result[i]);
+ ret = mod_init_seq[i].init_func();
+ if (ret < 0) {
+ ext4_exit_ext4_fs();
+ return ret;
+ }
+ mod_init_result[i] = true;
+ }
+ return 0;
+}
- err = ext4_fc_init_dentry_cache();
- if (err)
- goto out05;
+/* Shared across all ext4 file systems */
+wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
- register_as_ext3();
- register_as_ext2();
- err = register_filesystem(&ext4_fs_type);
- if (err)
- goto out;
+static int __init ext4_init_fs(void)
+{
+ ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64);
+ ext4_li_info = NULL;
- return 0;
-out:
- unregister_as_ext2();
- unregister_as_ext3();
- ext4_fc_destroy_dentry_cache();
-out05:
- destroy_inodecache();
-out1:
- ext4_exit_mballoc();
-out2:
- ext4_exit_sysfs();
-out3:
- ext4_exit_system_zone();
-out4:
- ext4_exit_pageio();
-out5:
- ext4_exit_post_read_processing();
-out6:
- ext4_exit_pending();
-out7:
- ext4_exit_es();
+ /* Build-time check for flags consistency */
+ ext4_check_flag_values();
- return err;
-}
+ for (int i = 0; i < EXT4_WQ_HASH_SZ; i++)
+ init_waitqueue_head(&ext4__ioend_wq[i]);
-static void __exit ext4_exit_fs(void)
-{
- ext4_destroy_lazyinit_thread();
- unregister_as_ext2();
- unregister_as_ext3();
- unregister_filesystem(&ext4_fs_type);
- ext4_fc_destroy_dentry_cache();
- destroy_inodecache();
- ext4_exit_mballoc();
- ext4_exit_sysfs();
- ext4_exit_system_zone();
- ext4_exit_pageio();
- ext4_exit_post_read_processing();
- ext4_exit_es();
- ext4_exit_pending();
+ return ext4_init_ext4_fs();
}
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] fs: Add {init, exit}_sequence_fs() helper functions
2024-07-11 7:48 [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Youling Tang
2024-07-11 7:48 ` [PATCH 1/3] f2fs: make module init/exit match their sequence Youling Tang
2024-07-11 7:48 ` [PATCH 2/3] ext4: make ext4 " Youling Tang
@ 2024-07-11 7:48 ` Youling Tang
2024-07-11 8:26 ` [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Christoph Hellwig
3 siblings, 0 replies; 7+ messages in thread
From: Youling Tang @ 2024-07-11 7:48 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu
Cc: linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, youling.tang, Youling Tang
From: Youling Tang <tangyouling@kylinos.cn>
In theory init_sequence_fs() and exit_sequence_fs() should match their
sequence, thus normally they should look like this:
init_sequence_fs() | exit_sequence_fs()
-------------------------+------------------------
init_A(); |
init_B(); |
init_C(); |
| exit_C();
| exit_B();
| exit_A();
Providing {init, exit}_sequence_fs() helps functions ensure that modules
init/exit match their order, while also simplifying the code.
For more details see commit 5565b8e0adcd ("btrfs: make module init/exit
match their sequence").
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
fs/btrfs/super.c | 36 ++----------------------------------
fs/ext4/super.c | 41 ++---------------------------------------
fs/f2fs/super.c | 36 ++----------------------------------
include/linux/fs.h | 38 ++++++++++++++++++++++++++++++++++++++
4 files changed, 44 insertions(+), 107 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f05cce7c8b8d..1101991a9a63 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -2478,13 +2478,6 @@ static void unregister_btrfs(void)
unregister_filesystem(&btrfs_fs_type);
}
-/* Helper structure for long init/exit functions. */
-struct init_sequence {
- int (*init_func)(void);
- /* Can be NULL if the init_func doesn't need cleanup. */
- void (*exit_func)(void);
-};
-
static const struct init_sequence mod_init_seq[] = {
{
.init_func = btrfs_props_init,
@@ -2551,40 +2544,15 @@ static const struct init_sequence mod_init_seq[] = {
static bool mod_init_result[ARRAY_SIZE(mod_init_seq)];
-static __always_inline void btrfs_exit_btrfs_fs(void)
-{
- int i;
-
- for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) {
- if (!mod_init_result[i])
- continue;
- if (mod_init_seq[i].exit_func)
- mod_init_seq[i].exit_func();
- mod_init_result[i] = false;
- }
-}
-
static void __exit exit_btrfs_fs(void)
{
- btrfs_exit_btrfs_fs();
+ exit_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
btrfs_cleanup_fs_uuids();
}
static int __init init_btrfs_fs(void)
{
- int ret;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) {
- ASSERT(!mod_init_result[i]);
- ret = mod_init_seq[i].init_func();
- if (ret < 0) {
- btrfs_exit_btrfs_fs();
- return ret;
- }
- mod_init_result[i] = true;
- }
- return 0;
+ return init_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
}
late_initcall(init_btrfs_fs);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ec1e63facb10..cb5b7449c80b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -7328,13 +7328,6 @@ static void unregister_ext(void)
unregister_filesystem(&ext4_fs_type);
}
-/* Helper structure for long init/exit functions. */
-struct init_sequence {
- int (*init_func)(void);
- /* Can be NULL if the init_func doesn't need cleanup. */
- void (*exit_func)(void);
-};
-
static const struct init_sequence mod_init_seq[] = {
{
.init_func = ext4_init_es,
@@ -7371,40 +7364,10 @@ static const struct init_sequence mod_init_seq[] = {
static bool mod_init_result[ARRAY_SIZE(mod_init_seq)];
-static __always_inline void ext4_exit_ext4_fs(void)
-{
- int i;
-
- for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) {
- if (!mod_init_result[i])
- continue;
- if (mod_init_seq[i].exit_func)
- mod_init_seq[i].exit_func();
- mod_init_result[i] = false;
- }
-}
-
static void __exit ext4_exit_fs(void)
{
ext4_destroy_lazyinit_thread();
- ext4_exit_ext4_fs();
-}
-
-static __always_inline int ext4_init_ext4_fs(void)
-{
- int ret;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) {
- ASSERT(!mod_init_result[i]);
- ret = mod_init_seq[i].init_func();
- if (ret < 0) {
- ext4_exit_ext4_fs();
- return ret;
- }
- mod_init_result[i] = true;
- }
- return 0;
+ exit_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
}
/* Shared across all ext4 file systems */
@@ -7421,7 +7384,7 @@ static int __init ext4_init_fs(void)
for (int i = 0; i < EXT4_WQ_HASH_SZ; i++)
init_waitqueue_head(&ext4__ioend_wq[i]);
- return ext4_init_ext4_fs();
+ return init_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
}
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 19509942b837..b4be24865ab3 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4950,13 +4950,6 @@ static void unregister_f2fs(void)
unregister_filesystem(&f2fs_fs_type);
}
-/* Helper structure for long init/exit functions. */
-struct init_sequence {
- int (*init_func)(void);
- /* Can be NULL if the init_func doesn't need cleanup. */
- void (*exit_func)(void);
-};
-
static const struct init_sequence mod_init_seq[] = {
{
.init_func = init_inodecache,
@@ -5017,39 +5010,14 @@ static const struct init_sequence mod_init_seq[] = {
static bool mod_init_result[ARRAY_SIZE(mod_init_seq)];
-static __always_inline void f2fs_exit_f2fs_fs(void)
-{
- int i;
-
- for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) {
- if (!mod_init_result[i])
- continue;
- if (mod_init_seq[i].exit_func)
- mod_init_seq[i].exit_func();
- mod_init_result[i] = false;
- }
-}
-
static void __exit exit_f2fs_fs(void)
{
- f2fs_exit_f2fs_fs();
+ exit_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
}
static int __init init_f2fs_fs(void)
{
- int ret;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) {
- BUG_ON(mod_init_result[i]);
- ret = mod_init_seq[i].init_func();
- if (ret < 0) {
- f2fs_exit_f2fs_fs();
- return ret;
- }
- mod_init_result[i] = true;
- }
- return 0;
+ return init_sequence_fs(mod_init_seq, mod_init_result, ARRAY_SIZE(mod_init_seq));
}
module_init(init_f2fs_fs)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0283cf366c2a..b173194b7f14 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2598,6 +2598,44 @@ extern void iput(struct inode *);
int inode_update_timestamps(struct inode *inode, int flags);
int generic_update_time(struct inode *, int);
+/* Helper structure for long init/exit functions. */
+struct init_sequence {
+ int (*init_func)(void);
+ /* Can be NULL if the init_func doesn't need cleanup. */
+ void (*exit_func)(void);
+};
+
+static __always_inline void exit_sequence_fs(const struct init_sequence *mod_init_seq,
+ bool *mod_init_result, int num)
+{
+ int i;
+
+ for (i = num - 1; i >= 0; i--) {
+ if (!mod_init_result[i])
+ continue;
+ if (mod_init_seq[i].exit_func)
+ mod_init_seq[i].exit_func();
+ mod_init_result[i] = false;
+ }
+}
+
+static __always_inline int init_sequence_fs(const struct init_sequence *mod_init_seq,
+ bool *mod_init_result, int num)
+{
+ int ret, i;
+
+ for (i = 0; i < num; i++) {
+ BUG_ON(mod_init_result[i]);
+ ret = mod_init_seq[i].init_func();
+ if (ret < 0) {
+ exit_sequence_fs(mod_init_seq, mod_init_result, num);
+ return ret;
+ }
+ mod_init_result[i] = true;
+ }
+ return 0;
+}
+
/* /sys/fs */
extern struct kobject *fs_kobj;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] Add {init, exit}_sequence_fs() helper function
2024-07-11 7:48 [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Youling Tang
` (2 preceding siblings ...)
2024-07-11 7:48 ` [PATCH 3/3] fs: Add {init, exit}_sequence_fs() helper functions Youling Tang
@ 2024-07-11 8:26 ` Christoph Hellwig
2024-07-23 8:44 ` Youling Tang
3 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2024-07-11 8:26 UTC (permalink / raw)
To: Youling Tang
Cc: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu, linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, Luis Chamberlain, linux-modules
Can we please stop this boilerplate code an instead our __init/__exit
sections to supper multiple entires per module. This should be mostly
trivial, except that we'd probably want a single macro that has the
init and exit calls so that the order in the section is the same and
the unroll on failure can walk back form the given offset. e.g.
something like:
module_subinit(foo_bar_init, foo_bar_exit);
module_subinit(foo_bar2_init, foo_bar2_exit);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] Add {init, exit}_sequence_fs() helper function
2024-07-11 8:26 ` [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Christoph Hellwig
@ 2024-07-23 8:44 ` Youling Tang
2024-07-23 13:37 ` Christoph Hellwig
0 siblings, 1 reply; 7+ messages in thread
From: Youling Tang @ 2024-07-23 8:44 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Alexander Viro, Christian Brauner, Jan Kara, Chris Mason,
Josef Bacik, David Sterba, tytso, Andreas Dilger, Jaegeuk Kim,
Chao Yu, linux-fsdevel, linux-btrfs, linux-ext4, linux-f2fs-devel,
linux-kernel, Luis Chamberlain, linux-modules
Hi, Christoph
On 11/07/2024 16:26, Christoph Hellwig wrote:
> Can we please stop this boilerplate code an instead our __init/__exit
> sections to supper multiple entires per module. This should be mostly
> trivial, except that we'd probably want a single macro that has the
> init and exit calls so that the order in the section is the same and
> the unroll on failure can walk back form the given offset. e.g.
> something like:
>
> module_subinit(foo_bar_init, foo_bar_exit);
> module_subinit(foo_bar2_init, foo_bar2_exit);
>
>
Thanks for your suggestion, I re-implemented it using section mode,
and the new patch set [1] has been sent.
[1]:
https://lore.kernel.org/all/20240723083239.41533-1-youling.tang@linux.dev/T/#md81aaefe0c1fef70a0592d1580cbbb10ec9989b0
Thanks,
Youling.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] Add {init, exit}_sequence_fs() helper function
2024-07-23 8:44 ` Youling Tang
@ 2024-07-23 13:37 ` Christoph Hellwig
0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2024-07-23 13:37 UTC (permalink / raw)
To: Youling Tang
Cc: Christoph Hellwig, Alexander Viro, Christian Brauner, Jan Kara,
Chris Mason, Josef Bacik, David Sterba, tytso, Andreas Dilger,
Jaegeuk Kim, Chao Yu, linux-fsdevel, linux-btrfs, linux-ext4,
linux-f2fs-devel, linux-kernel, Luis Chamberlain, linux-modules
On Tue, Jul 23, 2024 at 04:44:14PM +0800, Youling Tang wrote:
> Thanks for your suggestion, I re-implemented it using section mode,
> and the new patch set [1] has been sent.
Nice! I'll review it.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-07-23 13:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-11 7:48 [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Youling Tang
2024-07-11 7:48 ` [PATCH 1/3] f2fs: make module init/exit match their sequence Youling Tang
2024-07-11 7:48 ` [PATCH 2/3] ext4: make ext4 " Youling Tang
2024-07-11 7:48 ` [PATCH 3/3] fs: Add {init, exit}_sequence_fs() helper functions Youling Tang
2024-07-11 8:26 ` [PATCH 0/3] Add {init, exit}_sequence_fs() helper function Christoph Hellwig
2024-07-23 8:44 ` Youling Tang
2024-07-23 13:37 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).