hfs currently has some function tracking points, which are helpful for problem analysis, but rely on modifying the DBG_MASK macro. Modifying the macro requires recompiling the kernel, and the control of the log is more troublesome. Let's export this debug facility to debugfs so that it can be easily controlled through the node. node: /sys/kernel/debug/hfs/dbg_flags for_each_bit: DBG_BNODE_REFS 0x00000001 DBG_BNODE_MOD 0x00000002 DBG_CAT_MOD 0x00000004 DBG_INODE 0x00000008 DBG_SUPER 0x00000010 DBG_EXTENT 0x00000020 DBG_BITMAP 0x00000040 Signed-off-by: Yangtao Li <frank.li@xxxxxxxx> --- fs/hfs/Makefile | 4 ++-- fs/hfs/debug.c | 30 ++++++++++++++++++++++++++++++ fs/hfs/hfs_fs.h | 19 ++++++++++++------- fs/hfs/super.c | 8 ++++++-- 4 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 fs/hfs/debug.c diff --git a/fs/hfs/Makefile b/fs/hfs/Makefile index b65459bf3dc4..a6b8091449d7 100644 --- a/fs/hfs/Makefile +++ b/fs/hfs/Makefile @@ -7,5 +7,5 @@ obj-$(CONFIG_HFS_FS) += hfs.o hfs-objs := bitmap.o bfind.o bnode.o brec.o btree.o \ catalog.o dir.o extent.o inode.o attr.o mdb.o \ - part_tbl.o string.o super.o sysdep.o trans.o - + part_tbl.o string.o super.o sysdep.o trans.o \ + debug.o diff --git a/fs/hfs/debug.c b/fs/hfs/debug.c new file mode 100644 index 000000000000..4e98f7a3bc74 --- /dev/null +++ b/fs/hfs/debug.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * hfs debug support + * + * Copyright (c) 2025 Yangtao Li <frank.li@xxxxxxxx> + */ + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +#include "hfs_fs.h" + +#if IS_ENABLED(CONFIG_DEBUG_FS) +static struct dentry *hfs_debugfs_root; +u8 dbg_flags; + +void __init hfs_debug_init(void) +{ + hfs_debugfs_root = debugfs_create_dir("hfs", NULL); + debugfs_create_u8("dbg_flags", 0600, hfs_debugfs_root, &dbg_flags); +} + +void hfs_debug_exit(void) +{ + debugfs_remove_recursive(hfs_debugfs_root); +} +#else +void __init hfs_debug_init(void) {} +void hfs_debug_exit(void) {} +#endif diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index a0c7cb0f79fc..bfcf1441e26b 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h @@ -27,6 +27,7 @@ #include "hfs.h" +#if IS_ENABLED(CONFIG_DEBUG_FS) #define DBG_BNODE_REFS 0x00000001 #define DBG_BNODE_MOD 0x00000002 #define DBG_CAT_MOD 0x00000004 @@ -35,23 +36,23 @@ #define DBG_EXTENT 0x00000020 #define DBG_BITMAP 0x00000040 -//#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD|DBG_CAT_MOD|DBG_BITMAP) -//#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE) -//#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) -#define DBG_MASK (0) +extern u8 dbg_flags; #define hfs_dbg(flg, fmt, ...) \ do { \ - if (DBG_##flg & DBG_MASK) \ + if (DBG_##flg & dbg_flags) \ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) #define hfs_dbg_cont(flg, fmt, ...) \ do { \ - if (DBG_##flg & DBG_MASK) \ + if (DBG_##flg & dbg_flags) \ pr_cont(fmt, ##__VA_ARGS__); \ } while (0) - +#else +#define hfs_dbg(flg, fmt, ...) do {} while (0) +#define hfs_dbg_cont(flg, fmt, ...) do {} while (0) +#endif /* * struct hfs_inode_info @@ -184,6 +185,10 @@ extern int hfs_cat_move(u32, struct inode *, const struct qstr *, struct inode *, const struct qstr *); extern void hfs_cat_build_key(struct super_block *, btree_key *, u32, const struct qstr *); +/* debug.c */ +extern void __init hfs_debug_init(void); +extern void hfs_debug_exit(void); + /* dir.c */ extern const struct file_operations hfs_dir_operations; extern const struct inode_operations hfs_dir_inode_operations; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index fe09c2093a93..8403f3bc89b1 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -452,16 +452,20 @@ static int __init init_hfs_fs(void) SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, hfs_init_once); if (!hfs_inode_cachep) return -ENOMEM; + hfs_debug_init(); err = register_filesystem(&hfs_fs_type); - if (err) + if (err) { + hfs_debug_exit(); kmem_cache_destroy(hfs_inode_cachep); - return err; + } + return 0; } static void __exit exit_hfs_fs(void) { unregister_filesystem(&hfs_fs_type); + hfs_debug_exit(); /* * Make sure all delayed rcu free inodes are flushed before we * destroy cache. -- 2.48.1