summaryrefslogtreecommitdiff
path: root/fs/debugfs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2025-01-12 08:06:45 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-01-15 13:14:35 +0100
commit268b36116f2f048d2fb0cd13aa3036705fcac068 (patch)
tree8653ef6c0458d6456f5ec2f2941bacebe35f8590 /fs/debugfs
parentee9c69388e3bad6c595fe38f34aa1126d2d07a11 (diff)
debugfs: separate cache for debugfs inodes
Embed them into container (struct debugfs_inode_info, with nothing else in it at the moment), set the cache up, etc. Just the infrastructure changes letting us augment debugfs inodes here; adding stuff will come at the next step. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Reviewed-by: Christian Brauner <brauner@kernel.org> Link: https://lore.kernel.org/r/20250112080705.141166-1-viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/debugfs')
-rw-r--r--fs/debugfs/inode.c40
-rw-r--r--fs/debugfs/internal.h9
2 files changed, 43 insertions, 6 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index e752009de929..5d423bd92f93 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -208,16 +208,34 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
+static struct kmem_cache *debugfs_inode_cachep __ro_after_init;
+
+static void init_once(void *foo)
+{
+ struct debugfs_inode_info *info = foo;
+ inode_init_once(&info->vfs_inode);
+}
+
+static struct inode *debugfs_alloc_inode(struct super_block *sb)
+{
+ struct debugfs_inode_info *info;
+ info = alloc_inode_sb(sb, debugfs_inode_cachep, GFP_KERNEL);
+ if (!info)
+ return NULL;
+ return &info->vfs_inode;
+}
+
static void debugfs_free_inode(struct inode *inode)
{
if (S_ISLNK(inode->i_mode))
kfree(inode->i_link);
- free_inode_nonrcu(inode);
+ kmem_cache_free(debugfs_inode_cachep, DEBUGFS_I(inode));
}
static const struct super_operations debugfs_super_operations = {
.statfs = simple_statfs,
.show_options = debugfs_show_options,
+ .alloc_inode = debugfs_alloc_inode,
.free_inode = debugfs_free_inode,
};
@@ -939,12 +957,22 @@ static int __init debugfs_init(void)
if (retval)
return retval;
- retval = register_filesystem(&debug_fs_type);
- if (retval)
+ debugfs_inode_cachep = kmem_cache_create("debugfs_inode_cache",
+ sizeof(struct debugfs_inode_info), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
+ init_once);
+ if (debugfs_inode_cachep == NULL) {
sysfs_remove_mount_point(kernel_kobj, "debug");
- else
- debugfs_registered = true;
+ return -ENOMEM;
+ }
- return retval;
+ retval = register_filesystem(&debug_fs_type);
+ if (retval) { // Really not going to happen
+ sysfs_remove_mount_point(kernel_kobj, "debug");
+ kmem_cache_destroy(debugfs_inode_cachep);
+ return retval;
+ }
+ debugfs_registered = true;
+ return 0;
}
core_initcall(debugfs_init);
diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h
index bbae4a228ef4..5cb940b0b8f6 100644
--- a/fs/debugfs/internal.h
+++ b/fs/debugfs/internal.h
@@ -11,6 +11,15 @@
struct file_operations;
+struct debugfs_inode_info {
+ struct inode vfs_inode;
+};
+
+static inline struct debugfs_inode_info *DEBUGFS_I(struct inode *inode)
+{
+ return container_of(inode, struct debugfs_inode_info, vfs_inode);
+}
+
/* declared over in file.c */
extern const struct file_operations debugfs_noop_file_operations;
extern const struct file_operations debugfs_open_proxy_file_operations;