aboutsummaryrefslogtreecommitdiffstats
path: root/fs/anon_inodes.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 /fs/anon_inodes.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 'fs/anon_inodes.c')
-rw-r--r--fs/anon_inodes.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 2ca7a7cafdbf..94f5110c4655 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -88,7 +88,7 @@ struct file *anon_inode_getfile(const char *name,
88 void *priv, int flags) 88 void *priv, int flags)
89{ 89{
90 struct qstr this; 90 struct qstr this;
91 struct dentry *dentry; 91 struct path path;
92 struct file *file; 92 struct file *file;
93 int error; 93 int error;
94 94
@@ -106,10 +106,11 @@ struct file *anon_inode_getfile(const char *name,
106 this.name = name; 106 this.name = name;
107 this.len = strlen(name); 107 this.len = strlen(name);
108 this.hash = 0; 108 this.hash = 0;
109 dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this); 109 path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
110 if (!dentry) 110 if (!path.dentry)
111 goto err_module; 111 goto err_module;
112 112
113 path.mnt = mntget(anon_inode_mnt);
113 /* 114 /*
114 * We know the anon_inode inode count is always greater than zero, 115 * We know the anon_inode inode count is always greater than zero,
115 * so we can avoid doing an igrab() and we can use an open-coded 116 * so we can avoid doing an igrab() and we can use an open-coded
@@ -117,14 +118,13 @@ struct file *anon_inode_getfile(const char *name,
117 */ 118 */
118 atomic_inc(&anon_inode_inode->i_count); 119 atomic_inc(&anon_inode_inode->i_count);
119 120
120 dentry->d_op = &anon_inodefs_dentry_operations; 121 path.dentry->d_op = &anon_inodefs_dentry_operations;
121 /* Do not publish this dentry inside the global dentry hash table */ 122 /* Do not publish this dentry inside the global dentry hash table */
122 dentry->d_flags &= ~DCACHE_UNHASHED; 123 path.dentry->d_flags &= ~DCACHE_UNHASHED;
123 d_instantiate(dentry, anon_inode_inode); 124 d_instantiate(path.dentry, anon_inode_inode);
124 125
125 error = -ENFILE; 126 error = -ENFILE;
126 file = alloc_file(anon_inode_mnt, dentry, 127 file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops);
127 FMODE_READ | FMODE_WRITE, fops);
128 if (!file) 128 if (!file)
129 goto err_dput; 129 goto err_dput;
130 file->f_mapping = anon_inode_inode->i_mapping; 130 file->f_mapping = anon_inode_inode->i_mapping;
@@ -137,7 +137,7 @@ struct file *anon_inode_getfile(const char *name,
137 return file; 137 return file;
138 138
139err_dput: 139err_dput:
140 dput(dentry); 140 path_put(&path);
141err_module: 141err_module:
142 module_put(fops->owner); 142 module_put(fops->owner);
143 return ERR_PTR(error); 143 return ERR_PTR(error);