@@ -85,8 +85,7 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
85
85
86
86
mutex_lock (& eventfs_mutex );
87
87
ei = dentry -> d_fsdata ;
88
- /* The LSB is set when the eventfs_inode is being freed */
89
- if (((unsigned long )ei & 1UL ) || ei -> is_freed ) {
88
+ if (ei -> is_freed ) {
90
89
/* Do not allow changes if the event is about to be removed. */
91
90
mutex_unlock (& eventfs_mutex );
92
91
return - ENODEV ;
@@ -276,35 +275,17 @@ static void free_ei(struct eventfs_inode *ei)
276
275
void eventfs_set_ei_status_free (struct tracefs_inode * ti , struct dentry * dentry )
277
276
{
278
277
struct tracefs_inode * ti_parent ;
279
- struct eventfs_inode * ei_child , * tmp ;
280
278
struct eventfs_inode * ei ;
281
279
int i ;
282
280
283
281
/* The top level events directory may be freed by this */
284
282
if (unlikely (ti -> flags & TRACEFS_EVENT_TOP_INODE )) {
285
- LIST_HEAD (ef_del_list );
286
-
287
283
mutex_lock (& eventfs_mutex );
288
-
289
284
ei = ti -> private ;
290
-
291
- /* Record all the top level files */
292
- list_for_each_entry_srcu (ei_child , & ei -> children , list ,
293
- lockdep_is_held (& eventfs_mutex )) {
294
- list_add_tail (& ei_child -> del_list , & ef_del_list );
295
- }
296
-
297
285
/* Nothing should access this, but just in case! */
298
286
ti -> private = NULL ;
299
-
300
287
mutex_unlock (& eventfs_mutex );
301
288
302
- /* Now safely free the top level files and their children */
303
- list_for_each_entry_safe (ei_child , tmp , & ef_del_list , del_list ) {
304
- list_del (& ei_child -> del_list );
305
- eventfs_remove_dir (ei_child );
306
- }
307
-
308
289
free_ei (ei );
309
290
return ;
310
291
}
@@ -319,14 +300,6 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
319
300
if (!ei )
320
301
goto out ;
321
302
322
- /*
323
- * If ei was freed, then the LSB bit is set for d_fsdata.
324
- * But this should not happen, as it should still have a
325
- * ref count that prevents it. Warn in case it does.
326
- */
327
- if (WARN_ON_ONCE ((unsigned long )ei & 1 ))
328
- goto out ;
329
-
330
303
/* This could belong to one of the files of the ei */
331
304
if (ei -> dentry != dentry ) {
332
305
for (i = 0 ; i < ei -> nr_entries ; i ++ ) {
@@ -336,6 +309,8 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
336
309
if (WARN_ON_ONCE (i == ei -> nr_entries ))
337
310
goto out ;
338
311
ei -> d_children [i ] = NULL ;
312
+ } else if (ei -> is_freed ) {
313
+ free_ei (ei );
339
314
} else {
340
315
ei -> dentry = NULL ;
341
316
}
@@ -962,13 +937,65 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
962
937
return ERR_PTR (- ENOMEM );
963
938
}
964
939
940
+ static LLIST_HEAD (free_list );
941
+
942
+ static void eventfs_workfn (struct work_struct * work )
943
+ {
944
+ struct eventfs_inode * ei , * tmp ;
945
+ struct llist_node * llnode ;
946
+
947
+ llnode = llist_del_all (& free_list );
948
+ llist_for_each_entry_safe (ei , tmp , llnode , llist ) {
949
+ /* This dput() matches the dget() from unhook_dentry() */
950
+ for (int i = 0 ; i < ei -> nr_entries ; i ++ ) {
951
+ if (ei -> d_children [i ])
952
+ dput (ei -> d_children [i ]);
953
+ }
954
+ /* This should only get here if it had a dentry */
955
+ if (!WARN_ON_ONCE (!ei -> dentry ))
956
+ dput (ei -> dentry );
957
+ }
958
+ }
959
+
960
+ static DECLARE_WORK (eventfs_work , eventfs_workfn ) ;
961
+
965
962
static void free_rcu_ei (struct rcu_head * head )
966
963
{
967
964
struct eventfs_inode * ei = container_of (head , struct eventfs_inode , rcu );
968
965
966
+ if (ei -> dentry ) {
967
+ /* Do not free the ei until all references of dentry are gone */
968
+ if (llist_add (& ei -> llist , & free_list ))
969
+ queue_work (system_unbound_wq , & eventfs_work );
970
+ return ;
971
+ }
972
+
973
+ /* If the ei doesn't have a dentry, neither should its children */
974
+ for (int i = 0 ; i < ei -> nr_entries ; i ++ ) {
975
+ WARN_ON_ONCE (ei -> d_children [i ]);
976
+ }
977
+
969
978
free_ei (ei );
970
979
}
971
980
981
+ static void unhook_dentry (struct dentry * dentry )
982
+ {
983
+ if (!dentry )
984
+ return ;
985
+
986
+ /* Keep the dentry from being freed yet (see eventfs_workfn()) */
987
+ dget (dentry );
988
+
989
+ dentry -> d_fsdata = NULL ;
990
+ d_invalidate (dentry );
991
+ mutex_lock (& eventfs_mutex );
992
+ /* dentry should now have at least a single reference */
993
+ WARN_ONCE ((int )d_count (dentry ) < 1 ,
994
+ "dentry %px (%s) less than one reference (%d) after invalidate\n" ,
995
+ dentry , dentry -> d_name .name , d_count (dentry ));
996
+ mutex_unlock (& eventfs_mutex );
997
+ }
998
+
972
999
/**
973
1000
* eventfs_remove_rec - remove eventfs dir or file from list
974
1001
* @ei: eventfs_inode to be removed.
@@ -1006,33 +1033,6 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, struct list_head *head,
1006
1033
list_add_tail (& ei -> del_list , head );
1007
1034
}
1008
1035
1009
- static void unhook_dentry (struct dentry * * dentry , struct dentry * * list )
1010
- {
1011
- if (* dentry ) {
1012
- unsigned long ptr = (unsigned long )* list ;
1013
-
1014
- /* Keep the dentry from being freed yet */
1015
- dget (* dentry );
1016
-
1017
- /*
1018
- * Paranoid: The dget() above should prevent the dentry
1019
- * from being freed and calling eventfs_set_ei_status_free().
1020
- * But just in case, set the link list LSB pointer to 1
1021
- * and have eventfs_set_ei_status_free() check that to
1022
- * make sure that if it does happen, it will not think
1023
- * the d_fsdata is an eventfs_inode.
1024
- *
1025
- * For this to work, no eventfs_inode should be allocated
1026
- * on a odd space, as the ef should always be allocated
1027
- * to be at least word aligned. Check for that too.
1028
- */
1029
- WARN_ON_ONCE (ptr & 1 );
1030
-
1031
- (* dentry )-> d_fsdata = (void * )(ptr | 1 );
1032
- * list = * dentry ;
1033
- * dentry = NULL ;
1034
- }
1035
- }
1036
1036
/**
1037
1037
* eventfs_remove_dir - remove eventfs dir or file from list
1038
1038
* @ei: eventfs_inode to be removed.
@@ -1043,40 +1043,28 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
1043
1043
{
1044
1044
struct eventfs_inode * tmp ;
1045
1045
LIST_HEAD (ei_del_list );
1046
- struct dentry * dentry_list = NULL ;
1047
- struct dentry * dentry ;
1048
- int i ;
1049
1046
1050
1047
if (!ei )
1051
1048
return ;
1052
1049
1050
+ /*
1051
+ * Move the deleted eventfs_inodes onto the ei_del_list
1052
+ * which will also set the is_freed value. Note, this has to be
1053
+ * done under the eventfs_mutex, but the deletions of
1054
+ * the dentries must be done outside the eventfs_mutex.
1055
+ * Hence moving them to this temporary list.
1056
+ */
1053
1057
mutex_lock (& eventfs_mutex );
1054
1058
eventfs_remove_rec (ei , & ei_del_list , 0 );
1059
+ mutex_unlock (& eventfs_mutex );
1055
1060
1056
1061
list_for_each_entry_safe (ei , tmp , & ei_del_list , del_list ) {
1057
- for (i = 0 ; i < ei -> nr_entries ; i ++ )
1058
- unhook_dentry (& ei -> d_children [i ], & dentry_list );
1059
- unhook_dentry (& ei -> dentry , & dentry_list );
1062
+ for (int i = 0 ; i < ei -> nr_entries ; i ++ )
1063
+ unhook_dentry (ei -> d_children [i ]);
1064
+ unhook_dentry (ei -> dentry );
1065
+ list_del (& ei -> del_list );
1060
1066
call_srcu (& eventfs_srcu , & ei -> rcu , free_rcu_ei );
1061
1067
}
1062
- mutex_unlock (& eventfs_mutex );
1063
-
1064
- while (dentry_list ) {
1065
- unsigned long ptr ;
1066
-
1067
- dentry = dentry_list ;
1068
- ptr = (unsigned long )dentry -> d_fsdata & ~1UL ;
1069
- dentry_list = (struct dentry * )ptr ;
1070
- dentry -> d_fsdata = NULL ;
1071
- d_invalidate (dentry );
1072
- mutex_lock (& eventfs_mutex );
1073
- /* dentry should now have at least a single reference */
1074
- WARN_ONCE ((int )d_count (dentry ) < 1 ,
1075
- "dentry %px (%s) less than one reference (%d) after invalidate\n" ,
1076
- dentry , dentry -> d_name .name , d_count (dentry ));
1077
- mutex_unlock (& eventfs_mutex );
1078
- dput (dentry );
1079
- }
1080
1068
}
1081
1069
1082
1070
/**
0 commit comments