static int sockfs_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 sockfs_dentry_operations = {
        .d_delete = sockfs_delete_dentry,
 
        this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
        this.name = name;
-       this.hash = SOCK_INODE(sock)->i_ino;
+       this.hash = 0;
 
        file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
        if (unlikely(!file->f_dentry))
                return -ENOMEM;
 
        file->f_dentry->d_op = &sockfs_dentry_operations;
-       d_add(file->f_dentry, SOCK_INODE(sock));
+       /*
+        * We dont want to push 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 sockets
+        */
+       file->f_dentry->d_flags &= ~DCACHE_UNHASHED;
+       d_instantiate(file->f_dentry, SOCK_INODE(sock));
        file->f_vfsmnt = mntget(sock_mnt);
        file->f_mapping = file->f_dentry->d_inode->i_mapping;