Commit 2bb54115 authored by Abhishek Kulkarni's avatar Abhishek Kulkarni Committed by Eric Van Hensbergen

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: default avatarAbhishek Kulkarni <adkulkar@umail.iu.edu>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent 50fb6d2b
...@@ -207,65 +207,72 @@ v9fs_blank_wstat(struct p9_wstat *wstat) ...@@ -207,65 +207,72 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
struct inode *v9fs_get_inode(struct super_block *sb, int mode) struct inode *v9fs_get_inode(struct super_block *sb, int mode)
{ {
int err;
struct inode *inode; struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info; struct v9fs_session_info *v9ses = sb->s_fs_info;
P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
inode = new_inode(sb); inode = new_inode(sb);
if (inode) { if (!inode) {
inode->i_mode = mode; P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
inode->i_uid = current_fsuid(); return -ENOMEM;
inode->i_gid = current_fsgid(); }
inode->i_blocks = 0;
inode->i_rdev = 0; inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_uid = current_fsuid();
inode->i_mapping->a_ops = &v9fs_addr_operations; inode->i_gid = current_fsgid();
inode->i_blocks = 0;
switch (mode & S_IFMT) { inode->i_rdev = 0;
case S_IFIFO: inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
case S_IFBLK: inode->i_mapping->a_ops = &v9fs_addr_operations;
case S_IFCHR:
case S_IFSOCK: switch (mode & S_IFMT) {
if (!v9fs_extended(v9ses)) { case S_IFIFO:
P9_DPRINTK(P9_DEBUG_ERROR, case S_IFBLK:
"special files without extended mode\n"); case S_IFCHR:
return ERR_PTR(-EINVAL); case S_IFSOCK:
} if (!v9fs_extended(v9ses)) {
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
break;
case S_IFREG:
inode->i_op = &v9fs_file_inode_operations;
inode->i_fop = &v9fs_file_operations;
break;
case S_IFLNK:
if (!v9fs_extended(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"extended modes used w/o 9P2000.u\n");
return ERR_PTR(-EINVAL);
}
inode->i_op = &v9fs_symlink_inode_operations;
break;
case S_IFDIR:
inc_nlink(inode);
if (v9fs_extended(v9ses))
inode->i_op = &v9fs_dir_inode_operations_ext;
else
inode->i_op = &v9fs_dir_inode_operations;
inode->i_fop = &v9fs_dir_operations;
break;
default:
P9_DPRINTK(P9_DEBUG_ERROR, P9_DPRINTK(P9_DEBUG_ERROR,
"BAD mode 0x%x S_IFMT 0x%x\n", "special files without extended mode\n");
mode, mode & S_IFMT); err = -EINVAL;
return ERR_PTR(-EINVAL); goto error;
} }
} else { init_special_inode(inode, inode->i_mode, inode->i_rdev);
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); break;
return ERR_PTR(-ENOMEM); case S_IFREG:
inode->i_op = &v9fs_file_inode_operations;
inode->i_fop = &v9fs_file_operations;
break;
case S_IFLNK:
if (!v9fs_extended(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"extended modes used w/o 9P2000.u\n");
err = -EINVAL;
goto error;
}
inode->i_op = &v9fs_symlink_inode_operations;
break;
case S_IFDIR:
inc_nlink(inode);
if (v9fs_extended(v9ses))
inode->i_op = &v9fs_dir_inode_operations_ext;
else
inode->i_op = &v9fs_dir_inode_operations;
inode->i_fop = &v9fs_dir_operations;
break;
default:
P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
mode, mode & S_IFMT);
err = -EINVAL;
goto error;
} }
return inode; return inode;
error:
iput(inode);
return ERR_PTR(err);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment