eventfs: Create eventfs_root_inode to store dentry

Only the root "events" directory stores a dentry. There's no reason to
hold a dentry pointer for every eventfs_inode as it is never set except
for the root "events" eventfs_inode.

Create a eventfs_root_inode structure that holds the events_dir dentry.
The "events" eventfs_inode *is* special, let it have its own descriptor.

Link: https://lore.kernel.org/linux-trace-kernel/20240201161617.658992558@goodmis.org

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Ajay Kaher <ajay.kaher@broadcom.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 04204cd9
...@@ -35,6 +35,17 @@ static DEFINE_MUTEX(eventfs_mutex); ...@@ -35,6 +35,17 @@ static DEFINE_MUTEX(eventfs_mutex);
/* Choose something "unique" ;-) */ /* Choose something "unique" ;-) */
#define EVENTFS_FILE_INODE_INO 0x12c4e37 #define EVENTFS_FILE_INODE_INO 0x12c4e37
struct eventfs_root_inode {
struct eventfs_inode ei;
struct dentry *events_dir;
};
static struct eventfs_root_inode *get_root_inode(struct eventfs_inode *ei)
{
WARN_ON_ONCE(!ei->is_events);
return container_of(ei, struct eventfs_root_inode, ei);
}
/* Just try to make something consistent and unique */ /* Just try to make something consistent and unique */
static int eventfs_dir_ino(struct eventfs_inode *ei) static int eventfs_dir_ino(struct eventfs_inode *ei)
{ {
...@@ -73,12 +84,18 @@ enum { ...@@ -73,12 +84,18 @@ enum {
static void release_ei(struct kref *ref) static void release_ei(struct kref *ref)
{ {
struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref); struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
struct eventfs_root_inode *rei;
WARN_ON_ONCE(!ei->is_freed); WARN_ON_ONCE(!ei->is_freed);
kfree(ei->entry_attrs); kfree(ei->entry_attrs);
kfree_const(ei->name); kfree_const(ei->name);
kfree_rcu(ei, rcu); if (ei->is_events) {
rei = get_root_inode(ei);
kfree_rcu(rei, ei.rcu);
} else {
kfree_rcu(ei, rcu);
}
} }
static inline void put_ei(struct eventfs_inode *ei) static inline void put_ei(struct eventfs_inode *ei)
...@@ -408,19 +425,43 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry, ...@@ -408,19 +425,43 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
return NULL; return NULL;
} }
static inline struct eventfs_inode *init_ei(struct eventfs_inode *ei, const char *name)
{
ei->name = kstrdup_const(name, GFP_KERNEL);
if (!ei->name)
return NULL;
kref_init(&ei->kref);
return ei;
}
static inline struct eventfs_inode *alloc_ei(const char *name) static inline struct eventfs_inode *alloc_ei(const char *name)
{ {
struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL); struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL);
struct eventfs_inode *result;
if (!ei) if (!ei)
return NULL; return NULL;
ei->name = kstrdup_const(name, GFP_KERNEL); result = init_ei(ei, name);
if (!ei->name) { if (!result)
kfree(ei); kfree(ei);
return result;
}
static inline struct eventfs_inode *alloc_root_ei(const char *name)
{
struct eventfs_root_inode *rei = kzalloc(sizeof(*rei), GFP_KERNEL);
struct eventfs_inode *ei;
if (!rei)
return NULL; return NULL;
}
kref_init(&ei->kref); rei->ei.is_events = 1;
ei = init_ei(&rei->ei, name);
if (!ei)
kfree(rei);
return ei; return ei;
} }
...@@ -710,6 +751,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry ...@@ -710,6 +751,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
int size, void *data) int size, void *data)
{ {
struct dentry *dentry = tracefs_start_creating(name, parent); struct dentry *dentry = tracefs_start_creating(name, parent);
struct eventfs_root_inode *rei;
struct eventfs_inode *ei; struct eventfs_inode *ei;
struct tracefs_inode *ti; struct tracefs_inode *ti;
struct inode *inode; struct inode *inode;
...@@ -722,7 +764,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry ...@@ -722,7 +764,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
if (IS_ERR(dentry)) if (IS_ERR(dentry))
return ERR_CAST(dentry); return ERR_CAST(dentry);
ei = alloc_ei(name); ei = alloc_root_ei(name);
if (!ei) if (!ei)
goto fail; goto fail;
...@@ -731,10 +773,11 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry ...@@ -731,10 +773,11 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
goto fail; goto fail;
// Note: we have a ref to the dentry from tracefs_start_creating() // Note: we have a ref to the dentry from tracefs_start_creating()
ei->events_dir = dentry; rei = get_root_inode(ei);
rei->events_dir = dentry;
ei->entries = entries; ei->entries = entries;
ei->nr_entries = size; ei->nr_entries = size;
ei->is_events = 1;
ei->data = data; ei->data = data;
/* Save the ownership of this directory */ /* Save the ownership of this directory */
...@@ -845,13 +888,15 @@ void eventfs_remove_dir(struct eventfs_inode *ei) ...@@ -845,13 +888,15 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
*/ */
void eventfs_remove_events_dir(struct eventfs_inode *ei) void eventfs_remove_events_dir(struct eventfs_inode *ei)
{ {
struct eventfs_root_inode *rei;
struct dentry *dentry; struct dentry *dentry;
dentry = ei->events_dir; rei = get_root_inode(ei);
dentry = rei->events_dir;
if (!dentry) if (!dentry)
return; return;
ei->events_dir = NULL; rei->events_dir = NULL;
eventfs_remove_dir(ei); eventfs_remove_dir(ei);
/* /*
......
...@@ -36,7 +36,6 @@ struct eventfs_attr { ...@@ -36,7 +36,6 @@ struct eventfs_attr {
* @children: link list into the child eventfs_inode * @children: link list into the child eventfs_inode
* @entries: the array of entries representing the files in the directory * @entries: the array of entries representing the files in the directory
* @name: the name of the directory to create * @name: the name of the directory to create
* @events_dir: the dentry of the events directory
* @entry_attrs: Saved mode and ownership of the @d_children * @entry_attrs: Saved mode and ownership of the @d_children
* @data: The private data to pass to the callbacks * @data: The private data to pass to the callbacks
* @attr: Saved mode and ownership of eventfs_inode itself * @attr: Saved mode and ownership of eventfs_inode itself
...@@ -54,7 +53,6 @@ struct eventfs_inode { ...@@ -54,7 +53,6 @@ struct eventfs_inode {
struct list_head children; struct list_head children;
const struct eventfs_entry *entries; const struct eventfs_entry *entries;
const char *name; const char *name;
struct dentry *events_dir;
struct eventfs_attr *entry_attrs; struct eventfs_attr *entry_attrs;
void *data; void *data;
struct eventfs_attr attr; struct eventfs_attr attr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment