diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 3c88f13f1..d9c222ff0 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -418,6 +418,16 @@ static void configfs_remove_dir(struct dentry *d) pr_warn("remove_dir (%pd): attributes remain", d); } + /* + * The dentry can still have external references (e.g. from a + * concurrent configfs_symlink() path lookup), in which case + * simple_rmdir() will not have unhashed it yet. Make sure the + * dentry is unreachable before the caller drops the last + * reference to the config_item, since configfs_symlink() resolves + * targets by taking a reference through a hashed dentry. + */ + d_drop(d); + pr_debug(" o %pd removing done (%d)\n", d, d_count(d)); dput(parent);