The code for reading an event id currently uses file->f_inode->i_private to
store the value of trace_event_file->event_call->event.type, unlike all
other event files which use it to store a pointer to the associated
trace_event_file data. The event_id_read() function retrieves this id value
from i_private and checks if it is non-0/NULL to determine whether the
event is still valid. This approach worked in the past when
remove_event_file_dir() would set i_private to NULL for all files in an
event directory upon removal. However, with the introduction of eventfs,
i_private is assigned when an eventfs inode is allocated and remains set
throughout its lifetime. As a result, event_id_read() may fail to detect
that an event is being removed.
Fix this issue by changing the event id file to use i_private to store
a trace_event_file pointer and utilize event_file_file() to check for the
EVENT_FILE_FL_FREED flag.
Fixes: 6fdac58c560e ("tracing: Remove unused trace_event_file dir field")
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace_events.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index e8ed6ba155cf..3d272b3cd688 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2090,11 +2090,18 @@ static int trace_format_open(struct inode *inode, struct file *file)
static ssize_t
event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
- int id = (long)event_file_data(filp);
+ struct trace_event_file *file;
+ int id;
char buf[32];
int len;
- if (unlikely(!id))
+ mutex_lock(&event_mutex);
+ file = event_file_file(filp);
+ if (likely(file))
+ id = file->event_call->event.type;
+ mutex_unlock(&event_mutex);
+
+ if (!file)
return -ENODEV;
len = sprintf(buf, "%d\n", id);
@@ -2572,7 +2579,9 @@ static const struct file_operations ftrace_event_format_fops = {
#ifdef CONFIG_PERF_EVENTS
static const struct file_operations ftrace_event_id_fops = {
+ .open = tracing_open_file_tr,
.read = event_id_read,
+ .release = tracing_release_file_tr,
.llseek = default_llseek,
};
#endif
@@ -2936,7 +2945,6 @@ static int event_callback(const char *name, umode_t *mode, void **data,
if (call->event.type && call->class->reg &&
strcmp(name, "id") == 0) {
*mode = TRACE_MODE_READ;
- *data = (void *)(long)call->event.type;
*fops = &ftrace_event_id_fops;
return 1;
}
--
2.52.0
On Tue, 10 Feb 2026 12:28:17 +0100 Petr Pavlu <petr.pavlu@suse.com> wrote: > The code for reading an event id currently uses file->f_inode->i_private to > store the value of trace_event_file->event_call->event.type, unlike all > other event files which use it to store a pointer to the associated > trace_event_file data. The event_id_read() function retrieves this id value > from i_private and checks if it is non-0/NULL to determine whether the > event is still valid. This approach worked in the past when > remove_event_file_dir() would set i_private to NULL for all files in an > event directory upon removal. However, with the introduction of eventfs, > i_private is assigned when an eventfs inode is allocated and remains set > throughout its lifetime. As a result, event_id_read() may fail to detect > that an event is being removed. Who cares? It's just an id. If the event is being removed, there's nothing wrong with still returning its id. The code currently is very simple, I don't want to make it complex for something nobody cares about. -- Steve > > Fix this issue by changing the event id file to use i_private to store > a trace_event_file pointer and utilize event_file_file() to check for the > EVENT_FILE_FL_FREED flag.
On 2/11/26 5:37 PM, Steven Rostedt wrote: > On Tue, 10 Feb 2026 12:28:17 +0100 > Petr Pavlu <petr.pavlu@suse.com> wrote: > >> The code for reading an event id currently uses file->f_inode->i_private to >> store the value of trace_event_file->event_call->event.type, unlike all >> other event files which use it to store a pointer to the associated >> trace_event_file data. The event_id_read() function retrieves this id value >> from i_private and checks if it is non-0/NULL to determine whether the >> event is still valid. This approach worked in the past when >> remove_event_file_dir() would set i_private to NULL for all files in an >> event directory upon removal. However, with the introduction of eventfs, >> i_private is assigned when an eventfs inode is allocated and remains set > >> throughout its lifetime. As a result, event_id_read() may fail to detect >> that an event is being removed. > > Who cares? It's just an id. If the event is being removed, there's > nothing wrong with still returning its id. The code currently is very > simple, I don't want to make it complex for something nobody cares > about. I think one could argue that handling all event files in the same way is less complex. It would also allow for a minor simplification where event_callback() would no longer need to modify the data pointer and eventfs then wouldn't need to pass it down to lookup_file() because it could always use the default ei->data. However, this is all minor and I can see your point of view. I'll drop this patch. -- Thanks, Petr
© 2016 - 2026 Red Hat, Inc.