From 2c48b9c45579a9b5e3e74694eebf3d2451f3dbd3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 9 Aug 2009 00:52:35 +0400 Subject: 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 --- net/socket.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'net/socket.c') 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 = { static int sock_alloc_file(struct socket *sock, struct file **f, int flags) { struct qstr name = { .name = "" }; - struct dentry *dentry; + struct path path; struct file *file; int fd; @@ -366,28 +366,29 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags) if (unlikely(fd < 0)) return fd; - dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); - if (unlikely(!dentry)) { + path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); + if (unlikely(!path.dentry)) { put_unused_fd(fd); return -ENOMEM; } + path.mnt = mntget(sock_mnt); - dentry->d_op = &sockfs_dentry_operations; + path.dentry->d_op = &sockfs_dentry_operations; /* * 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 */ - dentry->d_flags &= ~DCACHE_UNHASHED; - d_instantiate(dentry, SOCK_INODE(sock)); + path.dentry->d_flags &= ~DCACHE_UNHASHED; + d_instantiate(path.dentry, SOCK_INODE(sock)); SOCK_INODE(sock)->i_fop = &socket_file_ops; - file = alloc_file(sock_mnt, dentry, FMODE_READ | FMODE_WRITE, + file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &socket_file_ops); if (unlikely(!file)) { /* drop dentry, keep inode */ atomic_inc(&path.dentry->d_inode->i_count); - dput(dentry); + path_put(&path); put_unused_fd(fd); return -ENFILE; } -- cgit v1.2.1