aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAbhishek Kulkarni <adkulkar@umail.iu.edu>2009-07-19 15:41:56 -0400
committerEric Van Hensbergen <ericvh@strongmad.austin.ibm.com>2009-08-17 17:27:57 -0400
commit2bb541157fe2602af7b9952096d0524f6f9c1e73 (patch)
tree79ee0fbdded9918298fbd37b1b56232b9f5f81d0 /fs
parent50fb6d2bd7062708892ae7147f30c3ee905b7a3d (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')
-rw-r--r--fs/9p/vfs_inode.c105
1 files changed, 56 insertions, 49 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 1fa5f15eaddc..0c8af1abf603 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
208struct inode *v9fs_get_inode(struct super_block *sb, int mode) 208struct 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
273error:
274 iput(inode);
275 return ERR_PTR(err);
269} 276}
270 277
271/* 278/*