diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 5d88c184f0fc..6a698b524338 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -112,7 +112,7 @@ static void release_ei(struct kref *ref) entry->release(entry->name, ei->data); } - call_rcu(&ei->rcu, free_ei_rcu); + call_srcu(&eventfs_srcu, &ei->rcu, free_ei_rcu); } static inline void put_ei(struct eventfs_inode *ei) @@ -334,6 +334,7 @@ static struct inode *eventfs_get_inode(struct dentry *dentry, struct eventfs_att ti = get_tracefs(inode); ti->private = ei; + WARN(ti->flags, "ti-flags = %lx\n", ti->flags); ti->flags |= TRACEFS_EVENT_INODE; /* Find the top dentry that holds the "events" directory */ @@ -736,7 +737,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode /* Was the parent freed? */ if (list_empty(&ei->list)) { cleanup_ei(ei); - ei = NULL; + ei = ERR_PTR(-EBUSY); } return ei; } @@ -802,6 +803,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry INIT_LIST_HEAD(&ei->list); ti = get_tracefs(inode); + WARN(ti->flags, "ti-flags = %lx\n", ti->flags); ti->flags |= TRACEFS_EVENT_INODE; ti->private = ei; diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 6ef29eba90ce..5fbfa1c885de 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -1627,12 +1627,14 @@ static int f_show(struct seq_file *m, void *v) static void *f_start(struct seq_file *m, loff_t *pos) { + struct trace_event_file *file; void *p = (void *)FORMAT_HEADER; loff_t l = 0; /* ->stop() is called even if ->start() fails */ mutex_lock(&event_mutex); - if (!event_file_data(m->private)) + file = event_file_data(m->private); + if (!file || (file->flags & EVENT_FILE_FL_FREED)) return ERR_PTR(-ENODEV); while (l < *pos && p)