24
24
#include <linux/delay.h>
25
25
#include "internal.h"
26
26
27
+ /*
28
+ * eventfs_mutex protects the eventfs_inode (ei) dentry. Any access
29
+ * to the ei->dentry must be done under this mutex and after checking
30
+ * if ei->is_freed is not set. The ei->dentry is released under the
31
+ * mutex at the same time ei->is_freed is set. If ei->is_freed is set
32
+ * then the ei->dentry is invalid.
33
+ */
27
34
static DEFINE_MUTEX (eventfs_mutex );
35
+
36
+ /*
37
+ * The eventfs_inode (ei) itself is protected by SRCU. It is released from
38
+ * its parent's list and will have is_freed set (under eventfs_mutex).
39
+ * After the SRCU grace period is over, the ei may be freed.
40
+ */
28
41
DEFINE_STATIC_SRCU (eventfs_srcu );
29
42
30
43
static struct dentry * eventfs_root_lookup (struct inode * dir ,
@@ -239,6 +252,10 @@ create_file_dentry(struct eventfs_inode *ei, struct dentry **e_dentry,
239
252
bool invalidate = false;
240
253
241
254
mutex_lock (& eventfs_mutex );
255
+ if (ei -> is_freed ) {
256
+ mutex_unlock (& eventfs_mutex );
257
+ return NULL ;
258
+ }
242
259
/* If the e_dentry already has a dentry, use it */
243
260
if (* e_dentry ) {
244
261
/* lookup does not need to up the ref count */
@@ -312,6 +329,8 @@ static void eventfs_post_create_dir(struct eventfs_inode *ei)
312
329
struct eventfs_inode * ei_child ;
313
330
struct tracefs_inode * ti ;
314
331
332
+ lockdep_assert_held (& eventfs_mutex );
333
+
315
334
/* srcu lock already held */
316
335
/* fill parent-child relation */
317
336
list_for_each_entry_srcu (ei_child , & ei -> children , list ,
@@ -325,19 +344,25 @@ static void eventfs_post_create_dir(struct eventfs_inode *ei)
325
344
326
345
/**
327
346
* create_dir_dentry - Create a directory dentry for the eventfs_inode
347
+ * @pei: The eventfs_inode parent of ei.
328
348
* @ei: The eventfs_inode to create the directory for
329
349
* @parent: The dentry of the parent of this directory
330
350
* @lookup: True if this is called by the lookup code
331
351
*
332
352
* This creates and attaches a directory dentry to the eventfs_inode @ei.
333
353
*/
334
354
static struct dentry *
335
- create_dir_dentry (struct eventfs_inode * ei , struct dentry * parent , bool lookup )
355
+ create_dir_dentry (struct eventfs_inode * pei , struct eventfs_inode * ei ,
356
+ struct dentry * parent , bool lookup )
336
357
{
337
358
bool invalidate = false;
338
359
struct dentry * dentry = NULL ;
339
360
340
361
mutex_lock (& eventfs_mutex );
362
+ if (pei -> is_freed || ei -> is_freed ) {
363
+ mutex_unlock (& eventfs_mutex );
364
+ return NULL ;
365
+ }
341
366
if (ei -> dentry ) {
342
367
/* If the dentry already has a dentry, use it */
343
368
dentry = ei -> dentry ;
@@ -440,7 +465,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
440
465
*/
441
466
mutex_lock (& eventfs_mutex );
442
467
ei = READ_ONCE (ti -> private );
443
- if (ei )
468
+ if (ei && ! ei -> is_freed )
444
469
ei_dentry = READ_ONCE (ei -> dentry );
445
470
mutex_unlock (& eventfs_mutex );
446
471
@@ -454,7 +479,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
454
479
if (strcmp (ei_child -> name , name ) != 0 )
455
480
continue ;
456
481
ret = simple_lookup (dir , dentry , flags );
457
- create_dir_dentry (ei_child , ei_dentry , true);
482
+ create_dir_dentry (ei , ei_child , ei_dentry , true);
458
483
created = true;
459
484
break ;
460
485
}
@@ -588,7 +613,7 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)
588
613
589
614
list_for_each_entry_srcu (ei_child , & ei -> children , list ,
590
615
srcu_read_lock_held (& eventfs_srcu )) {
591
- d = create_dir_dentry (ei_child , parent , false);
616
+ d = create_dir_dentry (ei , ei_child , parent , false);
592
617
if (d ) {
593
618
ret = add_dentries (& dentries , d , cnt );
594
619
if (ret < 0 )
@@ -705,12 +730,20 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
705
730
ei -> nr_entries = size ;
706
731
ei -> data = data ;
707
732
INIT_LIST_HEAD (& ei -> children );
733
+ INIT_LIST_HEAD (& ei -> list );
708
734
709
735
mutex_lock (& eventfs_mutex );
710
- list_add_tail (& ei -> list , & parent -> children );
711
- ei -> d_parent = parent -> dentry ;
736
+ if (!parent -> is_freed ) {
737
+ list_add_tail (& ei -> list , & parent -> children );
738
+ ei -> d_parent = parent -> dentry ;
739
+ }
712
740
mutex_unlock (& eventfs_mutex );
713
741
742
+ /* Was the parent freed? */
743
+ if (list_empty (& ei -> list )) {
744
+ free_ei (ei );
745
+ ei = NULL ;
746
+ }
714
747
return ei ;
715
748
}
716
749
0 commit comments