diff options
author | Abhishek Kulkarni <adkulkar@umail.iu.edu> | 2009-07-19 15:41:56 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@strongmad.austin.ibm.com> | 2009-08-17 17:27:57 -0400 |
commit | 2bb541157fe2602af7b9952096d0524f6f9c1e73 (patch) | |
tree | 79ee0fbdded9918298fbd37b1b56232b9f5f81d0 /fs/9p | |
parent | 50fb6d2bd7062708892ae7147f30c3ee905b7a3d (diff) |
9p: Fix possible inode leak in v9fs_get_inode.
Add a missing iput when cleaning up if v9fs_get_inode
fails after returning a valid inode.
Signed-off-by: Abhishek Kulkarni <adkulkar@umail.iu.edu>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/vfs_inode.c | 105 |
1 files changed, 56 insertions, 49 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 1fa5f15eadd..0c8af1abf60 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -207,65 +207,72 @@ v9fs_blank_wstat(struct p9_wstat *wstat) | |||
207 | 207 | ||
208 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) | 208 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) |
209 | { | 209 | { |
210 | int err; | ||
210 | struct inode *inode; | 211 | struct inode *inode; |
211 | struct v9fs_session_info *v9ses = sb->s_fs_info; | 212 | struct v9fs_session_info *v9ses = sb->s_fs_info; |
212 | 213 | ||
213 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); | 214 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); |
214 | 215 | ||
215 | inode = new_inode(sb); | 216 | inode = new_inode(sb); |
216 | if (inode) { | 217 | if (!inode) { |
217 | inode->i_mode = mode; | 218 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); |
218 | inode->i_uid = current_fsuid(); | 219 | return -ENOMEM; |
219 | inode->i_gid = current_fsgid(); | 220 | } |
220 | inode->i_blocks = 0; | 221 | |
221 | inode->i_rdev = 0; | 222 | inode->i_mode = mode; |
222 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 223 | inode->i_uid = current_fsuid(); |
223 | inode->i_mapping->a_ops = &v9fs_addr_operations; | 224 | inode->i_gid = current_fsgid(); |
224 | 225 | inode->i_blocks = 0; | |
225 | switch (mode & S_IFMT) { | 226 | inode->i_rdev = 0; |
226 | case S_IFIFO: | 227 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
227 | case S_IFBLK: | 228 | inode->i_mapping->a_ops = &v9fs_addr_operations; |
228 | case S_IFCHR: | 229 | |
229 | case S_IFSOCK: | 230 | switch (mode & S_IFMT) { |
230 | if (!v9fs_extended(v9ses)) { | 231 | case S_IFIFO: |
231 | P9_DPRINTK(P9_DEBUG_ERROR, | 232 | case S_IFBLK: |
232 | "special files without extended mode\n"); | 233 | case S_IFCHR: |
233 | return ERR_PTR(-EINVAL); | 234 | case S_IFSOCK: |
234 | } | 235 | if (!v9fs_extended(v9ses)) { |
235 | init_special_inode(inode, inode->i_mode, | ||
236 | inode->i_rdev); | ||
237 | break; | ||
238 | case S_IFREG: | ||
239 | inode->i_op = &v9fs_file_inode_operations; | ||
240 | inode->i_fop = &v9fs_file_operations; | ||
241 | break; | ||
242 | case S_IFLNK: | ||
243 | if (!v9fs_extended(v9ses)) { | ||
244 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
245 | "extended modes used w/o 9P2000.u\n"); | ||
246 | return ERR_PTR(-EINVAL); | ||
247 | } | ||
248 | inode->i_op = &v9fs_symlink_inode_operations; | ||
249 | break; | ||
250 | case S_IFDIR: | ||
251 | inc_nlink(inode); | ||
252 | if (v9fs_extended(v9ses)) | ||
253 | inode->i_op = &v9fs_dir_inode_operations_ext; | ||
254 | else | ||
255 | inode->i_op = &v9fs_dir_inode_operations; | ||
256 | inode->i_fop = &v9fs_dir_operations; | ||
257 | break; | ||
258 | default: | ||
259 | P9_DPRINTK(P9_DEBUG_ERROR, | 236 | P9_DPRINTK(P9_DEBUG_ERROR, |
260 | "BAD mode 0x%x S_IFMT 0x%x\n", | 237 | "special files without extended mode\n"); |
261 | mode, mode & S_IFMT); | 238 | err = -EINVAL; |
262 | return ERR_PTR(-EINVAL); | 239 | goto error; |
263 | } | 240 | } |
264 | } else { | 241 | init_special_inode(inode, inode->i_mode, inode->i_rdev); |
265 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); | 242 | break; |
266 | return ERR_PTR(-ENOMEM); | 243 | case S_IFREG: |
244 | inode->i_op = &v9fs_file_inode_operations; | ||
245 | inode->i_fop = &v9fs_file_operations; | ||
246 | break; | ||
247 | case S_IFLNK: | ||
248 | if (!v9fs_extended(v9ses)) { | ||
249 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
250 | "extended modes used w/o 9P2000.u\n"); | ||
251 | err = -EINVAL; | ||
252 | goto error; | ||
253 | } | ||
254 | inode->i_op = &v9fs_symlink_inode_operations; | ||
255 | break; | ||
256 | case S_IFDIR: | ||
257 | inc_nlink(inode); | ||
258 | if (v9fs_extended(v9ses)) | ||
259 | inode->i_op = &v9fs_dir_inode_operations_ext; | ||
260 | else | ||
261 | inode->i_op = &v9fs_dir_inode_operations; | ||
262 | inode->i_fop = &v9fs_dir_operations; | ||
263 | break; | ||
264 | default: | ||
265 | P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", | ||
266 | mode, mode & S_IFMT); | ||
267 | err = -EINVAL; | ||
268 | goto error; | ||
267 | } | 269 | } |
270 | |||
268 | return inode; | 271 | return inode; |
272 | |||
273 | error: | ||
274 | iput(inode); | ||
275 | return ERR_PTR(err); | ||
269 | } | 276 | } |
270 | 277 | ||
271 | /* | 278 | /* |