Commit c3137ab6 authored by Steven Rostedt (Google)'s avatar Steven Rostedt (Google)
Browse files

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
Loading
Loading
Loading
Loading
+55 −10
Original line number Diff line number Diff line
@@ -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,13 +84,19 @@ 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);
	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 NULL;

	return result;
}
	kref_init(&ei->kref);

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;

	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);

	/*
+0 −2
Original line number Diff line number Diff line
@@ -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;