aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-08-08 16:52:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:42 -0500
commit2c48b9c45579a9b5e3e74694eebf3d2451f3dbd3 (patch)
treececbf786ae0650368a8136bdd90910e05d9b95c3 /net/socket.c
parenta95161aaa801c18c52b2e7cf3d6b4b141c00a20a (diff)
switch alloc_file() to passing struct path
... and have the caller grab both mnt and dentry; kill leak in infiniband, while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/socket.c b/net/socket.c
index eaaba3510e81..dbfdfa96d29b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -358,7 +358,7 @@ static const struct dentry_operations sockfs_dentry_operations = {
358static int sock_alloc_file(struct socket *sock, struct file **f, int flags) 358static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
359{ 359{
360 struct qstr name = { .name = "" }; 360 struct qstr name = { .name = "" };
361 struct dentry *dentry; 361 struct path path;
362 struct file *file; 362 struct file *file;
363 int fd; 363 int fd;
364 364
@@ -366,28 +366,29 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
366 if (unlikely(fd < 0)) 366 if (unlikely(fd < 0))
367 return fd; 367 return fd;
368 368
369 dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 369 path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
370 if (unlikely(!dentry)) { 370 if (unlikely(!path.dentry)) {
371 put_unused_fd(fd); 371 put_unused_fd(fd);
372 return -ENOMEM; 372 return -ENOMEM;
373 } 373 }
374 path.mnt = mntget(sock_mnt);
374 375
375 dentry->d_op = &sockfs_dentry_operations; 376 path.dentry->d_op = &sockfs_dentry_operations;
376 /* 377 /*
377 * We dont want to push this dentry into global dentry hash table. 378 * We dont want to push this dentry into global dentry hash table.
378 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED 379 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
379 * This permits a working /proc/$pid/fd/XXX on sockets 380 * This permits a working /proc/$pid/fd/XXX on sockets
380 */ 381 */
381 dentry->d_flags &= ~DCACHE_UNHASHED; 382 path.dentry->d_flags &= ~DCACHE_UNHASHED;
382 d_instantiate(dentry, SOCK_INODE(sock)); 383 d_instantiate(path.dentry, SOCK_INODE(sock));
383 SOCK_INODE(sock)->i_fop = &socket_file_ops; 384 SOCK_INODE(sock)->i_fop = &socket_file_ops;
384 385
385 file = alloc_file(sock_mnt, dentry, FMODE_READ | FMODE_WRITE, 386 file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
386 &socket_file_ops); 387 &socket_file_ops);
387 if (unlikely(!file)) { 388 if (unlikely(!file)) {
388 /* drop dentry, keep inode */ 389 /* drop dentry, keep inode */
389 atomic_inc(&path.dentry->d_inode->i_count); 390 atomic_inc(&path.dentry->d_inode->i_count);
390 dput(dentry); 391 path_put(&path);
391 put_unused_fd(fd); 392 put_unused_fd(fd);
392 return -ENFILE; 393 return -ENFILE;
393 } 394 }