}
 EXPORT_SYMBOL_GPL(kernfs_put);
 
-static int kernfs_dop_delete(const struct dentry *dentry)
-{
-       struct kernfs_node *kn = dentry->d_fsdata;
-       return !(kn && !(kn->flags & KERNFS_REMOVED));
-}
-
 static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct kernfs_node *kn;
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 
+       /* Always perform fresh lookup for negatives */
+       if (!dentry->d_inode)
+               goto out_bad_unlocked;
+
        kn = dentry->d_fsdata;
        mutex_lock(&kernfs_mutex);
 
 out_valid:
        return 1;
 out_bad:
-       /*
-        * Remove the dentry from the dcache hashes.
-        * If this is a deleted dentry we use d_drop instead of d_delete
-        * so kernfs doesn't need to cope with negative dentries.
-        *
-        * If this is a dentry that has simply been renamed we
-        * use d_drop to remove it from the dcache lookup on its
-        * old parent.  If this dentry persists later when a lookup
-        * is performed at its new name the dentry will be readded
-        * to the dcache hashes.
-        */
        mutex_unlock(&kernfs_mutex);
-
-       /* If we have submounts we must allow the vfs caches
-        * to lie about the state of the filesystem to prevent
-        * leaks and other nasty things.
+out_bad_unlocked:
+       /*
+        * @dentry doesn't match the underlying kernfs node, drop the
+        * dentry and force lookup.  If we have submounts we must allow the
+        * vfs caches to lie about the state of the filesystem to prevent
+        * leaks and other nasty things, so use check_submounts_and_drop()
+        * instead of d_drop().
         */
        if (check_submounts_and_drop(dentry) != 0)
                goto out_valid;
 
 const struct dentry_operations kernfs_dops = {
        .d_revalidate   = kernfs_dop_revalidate,
-       .d_delete       = kernfs_dop_delete,
        .d_release      = kernfs_dop_release,
 };
 
                                        struct dentry *dentry,
                                        unsigned int flags)
 {
-       struct dentry *ret = NULL;
+       struct dentry *ret;
        struct kernfs_node *parent = dentry->d_parent->d_fsdata;
        struct kernfs_node *kn;
        struct inode *inode;
 
        /* no such entry */
        if (!kn) {
-               ret = ERR_PTR(-ENOENT);
+               ret = NULL;
                goto out_unlock;
        }
        kernfs_get(kn);