@@ -195,17 +195,39 @@ void eventfs_set_ef_status_free(struct tracefs_inode *ti, struct dentry *dentry)
195
195
{
196
196
struct tracefs_inode * ti_parent ;
197
197
struct eventfs_inode * ei ;
198
- struct eventfs_file * ef ;
199
-
200
- mutex_lock (& eventfs_mutex );
198
+ struct eventfs_file * ef , * tmp ;
201
199
202
200
/* The top level events directory may be freed by this */
203
201
if (unlikely (ti -> flags & TRACEFS_EVENT_TOP_INODE )) {
202
+ LIST_HEAD (ef_del_list );
203
+
204
+ mutex_lock (& eventfs_mutex );
205
+
204
206
ei = ti -> private ;
207
+
208
+ /* Record all the top level files */
209
+ list_for_each_entry_srcu (ef , & ei -> e_top_files , list ,
210
+ lockdep_is_held (& eventfs_mutex )) {
211
+ list_add_tail (& ef -> del_list , & ef_del_list );
212
+ }
213
+
214
+ /* Nothing should access this, but just in case! */
215
+ ti -> private = NULL ;
216
+
217
+ mutex_unlock (& eventfs_mutex );
218
+
219
+ /* Now safely free the top level files and their children */
220
+ list_for_each_entry_safe (ef , tmp , & ef_del_list , del_list ) {
221
+ list_del (& ef -> del_list );
222
+ eventfs_remove (ef );
223
+ }
224
+
205
225
kfree (ei );
206
- goto out ;
226
+ return ;
207
227
}
208
228
229
+ mutex_lock (& eventfs_mutex );
230
+
209
231
ti_parent = get_tracefs (dentry -> d_parent -> d_inode );
210
232
if (!ti_parent || !(ti_parent -> flags & TRACEFS_EVENT_INODE ))
211
233
goto out ;
0 commit comments