aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/socket.c b/net/socket.c
index e8db54702a69..29ea1de43ecb 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -230,13 +230,13 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
230 230
231#define SOCKFS_MAGIC 0x534F434B 231#define SOCKFS_MAGIC 0x534F434B
232 232
233static kmem_cache_t *sock_inode_cachep __read_mostly; 233static struct kmem_cache *sock_inode_cachep __read_mostly;
234 234
235static struct inode *sock_alloc_inode(struct super_block *sb) 235static struct inode *sock_alloc_inode(struct super_block *sb)
236{ 236{
237 struct socket_alloc *ei; 237 struct socket_alloc *ei;
238 238
239 ei = kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL); 239 ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
240 if (!ei) 240 if (!ei)
241 return NULL; 241 return NULL;
242 init_waitqueue_head(&ei->socket.wait); 242 init_waitqueue_head(&ei->socket.wait);
@@ -257,7 +257,7 @@ static void sock_destroy_inode(struct inode *inode)
257 container_of(inode, struct socket_alloc, vfs_inode)); 257 container_of(inode, struct socket_alloc, vfs_inode));
258} 258}
259 259
260static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) 260static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
261{ 261{
262 struct socket_alloc *ei = (struct socket_alloc *)foo; 262 struct socket_alloc *ei = (struct socket_alloc *)foo;
263 263
@@ -305,7 +305,14 @@ static struct file_system_type sock_fs_type = {
305 305
306static int sockfs_delete_dentry(struct dentry *dentry) 306static int sockfs_delete_dentry(struct dentry *dentry)
307{ 307{
308 return 1; 308 /*
309 * At creation time, we pretended this dentry was hashed
310 * (by clearing DCACHE_UNHASHED bit in d_flags)
311 * At delete time, we restore the truth : not hashed.
312 * (so that dput() can proceed correctly)
313 */
314 dentry->d_flags |= DCACHE_UNHASHED;
315 return 0;
309} 316}
310static struct dentry_operations sockfs_dentry_operations = { 317static struct dentry_operations sockfs_dentry_operations = {
311 .d_delete = sockfs_delete_dentry, 318 .d_delete = sockfs_delete_dentry,
@@ -353,14 +360,20 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
353 360
354 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); 361 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
355 this.name = name; 362 this.name = name;
356 this.hash = SOCK_INODE(sock)->i_ino; 363 this.hash = 0;
357 364
358 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); 365 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
359 if (unlikely(!file->f_dentry)) 366 if (unlikely(!file->f_dentry))
360 return -ENOMEM; 367 return -ENOMEM;
361 368
362 file->f_dentry->d_op = &sockfs_dentry_operations; 369 file->f_dentry->d_op = &sockfs_dentry_operations;
363 d_add(file->f_dentry, SOCK_INODE(sock)); 370 /*
371 * We dont want to push this dentry into global dentry hash table.
372 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
373 * This permits a working /proc/$pid/fd/XXX on sockets
374 */
375 file->f_dentry->d_flags &= ~DCACHE_UNHASHED;
376 d_instantiate(file->f_dentry, SOCK_INODE(sock));
364 file->f_vfsmnt = mntget(sock_mnt); 377 file->f_vfsmnt = mntget(sock_mnt);
365 file->f_mapping = file->f_dentry->d_inode->i_mapping; 378 file->f_mapping = file->f_dentry->d_inode->i_mapping;
366 379