mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
8dce06e98c
In order for the dentries to stay up-to-date with the eventfs changes,
just add a 'd_revalidate' function that checks the 'is_freed' bit.
Also, clean up the dentry release to actually use d_release() rather
than the slightly odd d_iput() function. We don't care about the inode,
all we want to do is to get rid of the refcount to the eventfs data
added by dentry->d_fsdata.
It would probably be cleaner to make eventfs its own filesystem, or at
least set its own dentry ops when looking up eventfs files. But as it
is, only eventfs dentries use d_fsdata, so we don't really need to split
these things up by use.
Another thing that might be worth doing is to make all eventfs lookups
mark their dentries as not worth caching. We could do that with
d_delete(), but the DCACHE_DONTCACHE flag would likely be even better.
As it is, the dentries are all freeable, but they only tend to get freed
at memory pressure rather than more proactively. But that's a separate
issue.
Link: https://lore.kernel.org/linux-trace-kernel/202401291043.e62e89dc-oliver.sang@intel.com/
Link: https://lore.kernel.org/linux-trace-kernel/20240131185513.124644253@goodmis.org
Cc: stable@vger.kernel.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>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Fixes: c1504e5102
("eventfs: Implement eventfs dir creation functions")
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
85 lines
2.5 KiB
C
85 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _TRACEFS_INTERNAL_H
|
|
#define _TRACEFS_INTERNAL_H
|
|
|
|
enum {
|
|
TRACEFS_EVENT_INODE = BIT(1),
|
|
TRACEFS_EVENT_TOP_INODE = BIT(2),
|
|
TRACEFS_GID_PERM_SET = BIT(3),
|
|
TRACEFS_UID_PERM_SET = BIT(4),
|
|
TRACEFS_INSTANCE_INODE = BIT(5),
|
|
};
|
|
|
|
struct tracefs_inode {
|
|
struct inode vfs_inode;
|
|
/* The below gets initialized with memset_after(ti, 0, vfs_inode) */
|
|
unsigned long flags;
|
|
void *private;
|
|
};
|
|
|
|
/*
|
|
* struct eventfs_attr - cache the mode and ownership of a eventfs entry
|
|
* @mode: saved mode plus flags of what is saved
|
|
* @uid: saved uid if changed
|
|
* @gid: saved gid if changed
|
|
*/
|
|
struct eventfs_attr {
|
|
int mode;
|
|
kuid_t uid;
|
|
kgid_t gid;
|
|
};
|
|
|
|
/*
|
|
* struct eventfs_inode - hold the properties of the eventfs directories.
|
|
* @list: link list into the parent directory
|
|
* @entries: the array of entries representing the files in the directory
|
|
* @name: the name of the directory to create
|
|
* @children: link list into the child eventfs_inode
|
|
* @dentry: the dentry of the directory
|
|
* @d_children: The array of dentries to represent the files when created
|
|
* @entry_attrs: Saved mode and ownership of the @d_children
|
|
* @attr: Saved mode and ownership of eventfs_inode itself
|
|
* @data: The private data to pass to the callbacks
|
|
* @is_freed: Flag set if the eventfs is on its way to be freed
|
|
* Note if is_freed is set, then dentry is corrupted.
|
|
* @nr_entries: The number of items in @entries
|
|
*/
|
|
struct eventfs_inode {
|
|
struct list_head list;
|
|
const struct eventfs_entry *entries;
|
|
const char *name;
|
|
struct list_head children;
|
|
struct dentry *dentry; /* Check is_freed to access */
|
|
struct dentry **d_children;
|
|
struct eventfs_attr *entry_attrs;
|
|
struct eventfs_attr attr;
|
|
void *data;
|
|
unsigned int is_freed:1;
|
|
unsigned int is_events:1;
|
|
unsigned int nr_entries:30;
|
|
unsigned int ino;
|
|
/*
|
|
* Union - used for deletion
|
|
* @llist: for calling dput() if needed after RCU
|
|
* @rcu: eventfs_inode to delete in RCU
|
|
*/
|
|
union {
|
|
struct llist_node llist;
|
|
struct rcu_head rcu;
|
|
};
|
|
};
|
|
|
|
static inline struct tracefs_inode *get_tracefs(const struct inode *inode)
|
|
{
|
|
return container_of(inode, struct tracefs_inode, vfs_inode);
|
|
}
|
|
|
|
struct dentry *tracefs_start_creating(const char *name, struct dentry *parent);
|
|
struct dentry *tracefs_end_creating(struct dentry *dentry);
|
|
struct dentry *tracefs_failed_creating(struct dentry *dentry);
|
|
struct inode *tracefs_get_inode(struct super_block *sb);
|
|
|
|
void eventfs_d_release(struct dentry *dentry);
|
|
|
|
#endif /* _TRACEFS_INTERNAL_H */
|