static struct vfsmount *pipe_mnt __read_mostly;
 static int pipefs_delete_dentry(struct dentry *dentry)
 {
-       return 1;
+       /*
+        * At creation time, we pretended this dentry was hashed
+        * (by clearing DCACHE_UNHASHED bit in d_flags)
+        * At delete time, we restore the truth : not hashed.
+        * (so that dput() can proceed correctly)
+        */
+       dentry->d_flags |= DCACHE_UNHASHED;
+       return 0;
 }
 
 static struct dentry_operations pipefs_dentry_operations = {
        if (!inode)
                goto err_file;
 
-       sprintf(name, "[%lu]", inode->i_ino);
+       this.len = sprintf(name, "[%lu]", inode->i_ino);
        this.name = name;
-       this.len = strlen(name);
-       this.hash = inode->i_ino; /* will go */
+       this.hash = 0;
        err = -ENOMEM;
        dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
        if (!dentry)
                goto err_inode;
 
        dentry->d_op = &pipefs_dentry_operations;
-       d_add(dentry, inode);
+       /*
+        * We dont want to publish this dentry into global dentry hash table.
+        * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
+        * This permits a working /proc/$pid/fd/XXX on pipes
+        */
+       dentry->d_flags &= ~DCACHE_UNHASHED;
+       d_instantiate(dentry, inode);
        f->f_vfsmnt = mntget(pipe_mnt);
        f->f_dentry = dentry;
        f->f_mapping = inode->i_mapping;