@@ -310,7 +310,10 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
310310 parent = debugfs_mount -> mnt_root ;
311311
312312 inode_lock (d_inode (parent ));
313- dentry = lookup_one_len (name , parent , strlen (name ));
313+ if (unlikely (IS_DEADDIR (d_inode (parent ))))
314+ dentry = ERR_PTR (- ENOENT );
315+ else
316+ dentry = lookup_one_len (name , parent , strlen (name ));
314317 if (!IS_ERR (dentry ) && d_really_is_positive (dentry )) {
315318 dput (dentry );
316319 dentry = ERR_PTR (- EEXIST );
@@ -638,59 +641,15 @@ static void __debugfs_file_removed(struct dentry *dentry)
638641 wait_for_completion (& fsd -> active_users_drained );
639642}
640643
641- static int __debugfs_remove (struct dentry * dentry , struct dentry * parent )
642- {
643- int ret = 0 ;
644-
645- if (simple_positive (dentry )) {
646- dget (dentry );
647- if (d_is_dir (dentry )) {
648- ret = simple_rmdir (d_inode (parent ), dentry );
649- } else {
650- simple_unlink (d_inode (parent ), dentry );
651- }
652- if (!ret )
653- d_delete (dentry );
654- if (d_is_reg (dentry ))
655- __debugfs_file_removed (dentry );
656- dput (dentry );
657- }
658- return ret ;
659- }
660-
661- /**
662- * debugfs_remove - removes a file or directory from the debugfs filesystem
663- * @dentry: a pointer to a the dentry of the file or directory to be
664- * removed. If this parameter is NULL or an error value, nothing
665- * will be done.
666- *
667- * This function removes a file or directory in debugfs that was previously
668- * created with a call to another debugfs function (like
669- * debugfs_create_file() or variants thereof.)
670- *
671- * This function is required to be called in order for the file to be
672- * removed, no automatic cleanup of files will happen when a module is
673- * removed, you are responsible here.
674- */
675- void debugfs_remove (struct dentry * dentry )
644+ static void remove_one (struct dentry * victim )
676645{
677- struct dentry * parent ;
678- int ret ;
679-
680- if (IS_ERR_OR_NULL (dentry ))
681- return ;
682-
683- parent = dentry -> d_parent ;
684- inode_lock (d_inode (parent ));
685- ret = __debugfs_remove (dentry , parent );
686- inode_unlock (d_inode (parent ));
687- if (!ret )
688- simple_release_fs (& debugfs_mount , & debugfs_mount_count );
646+ if (d_is_reg (victim ))
647+ __debugfs_file_removed (victim );
648+ simple_release_fs (& debugfs_mount , & debugfs_mount_count );
689649}
690- EXPORT_SYMBOL_GPL (debugfs_remove );
691650
692651/**
693- * debugfs_remove_recursive - recursively removes a directory
652+ * debugfs_remove - recursively removes a directory
694653 * @dentry: a pointer to a the dentry of the directory to be removed. If this
695654 * parameter is NULL or an error value, nothing will be done.
696655 *
@@ -702,65 +661,16 @@ EXPORT_SYMBOL_GPL(debugfs_remove);
702661 * removed, no automatic cleanup of files will happen when a module is
703662 * removed, you are responsible here.
704663 */
705- void debugfs_remove_recursive (struct dentry * dentry )
664+ void debugfs_remove (struct dentry * dentry )
706665{
707- struct dentry * child , * parent ;
708-
709666 if (IS_ERR_OR_NULL (dentry ))
710667 return ;
711668
712- parent = dentry ;
713- down :
714- inode_lock (d_inode (parent ));
715- loop :
716- /*
717- * The parent->d_subdirs is protected by the d_lock. Outside that
718- * lock, the child can be unlinked and set to be freed which can
719- * use the d_u.d_child as the rcu head and corrupt this list.
720- */
721- spin_lock (& parent -> d_lock );
722- list_for_each_entry (child , & parent -> d_subdirs , d_child ) {
723- if (!simple_positive (child ))
724- continue ;
725-
726- /* perhaps simple_empty(child) makes more sense */
727- if (!list_empty (& child -> d_subdirs )) {
728- spin_unlock (& parent -> d_lock );
729- inode_unlock (d_inode (parent ));
730- parent = child ;
731- goto down ;
732- }
733-
734- spin_unlock (& parent -> d_lock );
735-
736- if (!__debugfs_remove (child , parent ))
737- simple_release_fs (& debugfs_mount , & debugfs_mount_count );
738-
739- /*
740- * The parent->d_lock protects agaist child from unlinking
741- * from d_subdirs. When releasing the parent->d_lock we can
742- * no longer trust that the next pointer is valid.
743- * Restart the loop. We'll skip this one with the
744- * simple_positive() check.
745- */
746- goto loop ;
747- }
748- spin_unlock (& parent -> d_lock );
749-
750- inode_unlock (d_inode (parent ));
751- child = parent ;
752- parent = parent -> d_parent ;
753- inode_lock (d_inode (parent ));
754-
755- if (child != dentry )
756- /* go up */
757- goto loop ;
758-
759- if (!__debugfs_remove (child , parent ))
760- simple_release_fs (& debugfs_mount , & debugfs_mount_count );
761- inode_unlock (d_inode (parent ));
669+ simple_pin_fs (& debug_fs_type , & debugfs_mount , & debugfs_mount_count );
670+ simple_recursive_removal (dentry , remove_one );
671+ simple_release_fs (& debugfs_mount , & debugfs_mount_count );
762672}
763- EXPORT_SYMBOL_GPL (debugfs_remove_recursive );
673+ EXPORT_SYMBOL_GPL (debugfs_remove );
764674
765675/**
766676 * debugfs_rename - rename a file/directory in the debugfs filesystem
0 commit comments