@@ -85,8 +85,7 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
8585
8686 mutex_lock (& eventfs_mutex );
8787 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 ) {
9089 /* Do not allow changes if the event is about to be removed. */
9190 mutex_unlock (& eventfs_mutex );
9291 return - ENODEV ;
@@ -276,35 +275,17 @@ static void free_ei(struct eventfs_inode *ei)
276275void eventfs_set_ei_status_free (struct tracefs_inode * ti , struct dentry * dentry )
277276{
278277 struct tracefs_inode * ti_parent ;
279- struct eventfs_inode * ei_child , * tmp ;
280278 struct eventfs_inode * ei ;
281279 int i ;
282280
283281 /* The top level events directory may be freed by this */
284282 if (unlikely (ti -> flags & TRACEFS_EVENT_TOP_INODE )) {
285- LIST_HEAD (ef_del_list );
286-
287283 mutex_lock (& eventfs_mutex );
288-
289284 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-
297285 /* Nothing should access this, but just in case! */
298286 ti -> private = NULL ;
299-
300287 mutex_unlock (& eventfs_mutex );
301288
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-
308289 free_ei (ei );
309290 return ;
310291 }
@@ -319,14 +300,6 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
319300 if (!ei )
320301 goto out ;
321302
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-
330303 /* This could belong to one of the files of the ei */
331304 if (ei -> dentry != dentry ) {
332305 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)
336309 if (WARN_ON_ONCE (i == ei -> nr_entries ))
337310 goto out ;
338311 ei -> d_children [i ] = NULL ;
312+ } else if (ei -> is_freed ) {
313+ free_ei (ei );
339314 } else {
340315 ei -> dentry = NULL ;
341316 }
@@ -962,13 +937,65 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
962937 return ERR_PTR (- ENOMEM );
963938}
964939
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+
965962static void free_rcu_ei (struct rcu_head * head )
966963{
967964 struct eventfs_inode * ei = container_of (head , struct eventfs_inode , rcu );
968965
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+
969978 free_ei (ei );
970979}
971980
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+
972999/**
9731000 * eventfs_remove_rec - remove eventfs dir or file from list
9741001 * @ei: eventfs_inode to be removed.
@@ -1006,33 +1033,6 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, struct list_head *head,
10061033 list_add_tail (& ei -> del_list , head );
10071034}
10081035
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- }
10361036/**
10371037 * eventfs_remove_dir - remove eventfs dir or file from list
10381038 * @ei: eventfs_inode to be removed.
@@ -1043,40 +1043,28 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
10431043{
10441044 struct eventfs_inode * tmp ;
10451045 LIST_HEAD (ei_del_list );
1046- struct dentry * dentry_list = NULL ;
1047- struct dentry * dentry ;
1048- int i ;
10491046
10501047 if (!ei )
10511048 return ;
10521049
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+ */
10531057 mutex_lock (& eventfs_mutex );
10541058 eventfs_remove_rec (ei , & ei_del_list , 0 );
1059+ mutex_unlock (& eventfs_mutex );
10551060
10561061 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 );
10601066 call_srcu (& eventfs_srcu , & ei -> rcu , free_rcu_ei );
10611067 }
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- }
10801068}
10811069
10821070/**
0 commit comments