mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
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: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
04204cd9b0
commit
c3137ab631
@ -35,6 +35,17 @@ static DEFINE_MUTEX(eventfs_mutex);
|
||||
/* Choose something "unique" ;-) */
|
||||
#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 */
|
||||
static int eventfs_dir_ino(struct eventfs_inode *ei)
|
||||
{
|
||||
@ -73,12 +84,18 @@ enum {
|
||||
static void release_ei(struct kref *ref)
|
||||
{
|
||||
struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
|
||||
struct eventfs_root_inode *rei;
|
||||
|
||||
WARN_ON_ONCE(!ei->is_freed);
|
||||
|
||||
kfree(ei->entry_attrs);
|
||||
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)
|
||||
@ -408,19 +425,43 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
|
||||
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)
|
||||
{
|
||||
struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL);
|
||||
struct eventfs_inode *result;
|
||||
|
||||
if (!ei)
|
||||
return NULL;
|
||||
|
||||
ei->name = kstrdup_const(name, GFP_KERNEL);
|
||||
if (!ei->name) {
|
||||
result = init_ei(ei, name);
|
||||
if (!result)
|
||||
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;
|
||||
}
|
||||
kref_init(&ei->kref);
|
||||
|
||||
rei->ei.is_events = 1;
|
||||
ei = init_ei(&rei->ei, name);
|
||||
if (!ei)
|
||||
kfree(rei);
|
||||
|
||||
return ei;
|
||||
}
|
||||
|
||||
@ -710,6 +751,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
|
||||
int size, void *data)
|
||||
{
|
||||
struct dentry *dentry = tracefs_start_creating(name, parent);
|
||||
struct eventfs_root_inode *rei;
|
||||
struct eventfs_inode *ei;
|
||||
struct tracefs_inode *ti;
|
||||
struct inode *inode;
|
||||
@ -722,7 +764,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
|
||||
if (IS_ERR(dentry))
|
||||
return ERR_CAST(dentry);
|
||||
|
||||
ei = alloc_ei(name);
|
||||
ei = alloc_root_ei(name);
|
||||
if (!ei)
|
||||
goto fail;
|
||||
|
||||
@ -731,10 +773,11 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
|
||||
goto fail;
|
||||
|
||||
// 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->nr_entries = size;
|
||||
ei->is_events = 1;
|
||||
ei->data = data;
|
||||
|
||||
/* Save the ownership of this directory */
|
||||
@ -845,13 +888,15 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
|
||||
*/
|
||||
void eventfs_remove_events_dir(struct eventfs_inode *ei)
|
||||
{
|
||||
struct eventfs_root_inode *rei;
|
||||
struct dentry *dentry;
|
||||
|
||||
dentry = ei->events_dir;
|
||||
rei = get_root_inode(ei);
|
||||
dentry = rei->events_dir;
|
||||
if (!dentry)
|
||||
return;
|
||||
|
||||
ei->events_dir = NULL;
|
||||
rei->events_dir = NULL;
|
||||
eventfs_remove_dir(ei);
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,6 @@ struct eventfs_attr {
|
||||
* @children: link list into the child eventfs_inode
|
||||
* @entries: the array of entries representing the files in the directory
|
||||
* @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
|
||||
* @data: The private data to pass to the callbacks
|
||||
* @attr: Saved mode and ownership of eventfs_inode itself
|
||||
@ -54,7 +53,6 @@ struct eventfs_inode {
|
||||
struct list_head children;
|
||||
const struct eventfs_entry *entries;
|
||||
const char *name;
|
||||
struct dentry *events_dir;
|
||||
struct eventfs_attr *entry_attrs;
|
||||
void *data;
|
||||
struct eventfs_attr attr;
|
||||
|
Loading…
Reference in New Issue
Block a user