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>
This commit is contained in:
parent
50fb6d2bd7
commit
2bb541157f
@ -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;
|
|
||||||
inode->i_uid = current_fsuid();
|
|
||||||
inode->i_gid = current_fsgid();
|
|
||||||
inode->i_blocks = 0;
|
|
||||||
inode->i_rdev = 0;
|
|
||||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
|
||||||
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
|
||||||
|
|
||||||
switch (mode & S_IFMT) {
|
|
||||||
case S_IFIFO:
|
|
||||||
case S_IFBLK:
|
|
||||||
case S_IFCHR:
|
|
||||||
case S_IFSOCK:
|
|
||||||
if (!v9fs_extended(v9ses)) {
|
|
||||||
P9_DPRINTK(P9_DEBUG_ERROR,
|
|
||||||
"special files without extended mode\n");
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
"BAD mode 0x%x S_IFMT 0x%x\n",
|
|
||||||
mode, mode & S_IFMT);
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
|
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
|
||||||
return ERR_PTR(-ENOMEM);
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inode->i_mode = mode;
|
||||||
|
inode->i_uid = current_fsuid();
|
||||||
|
inode->i_gid = current_fsgid();
|
||||||
|
inode->i_blocks = 0;
|
||||||
|
inode->i_rdev = 0;
|
||||||
|
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||||
|
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
||||||
|
|
||||||
|
switch (mode & S_IFMT) {
|
||||||
|
case S_IFIFO:
|
||||||
|
case S_IFBLK:
|
||||||
|
case S_IFCHR:
|
||||||
|
case S_IFSOCK:
|
||||||
|
if (!v9fs_extended(v9ses)) {
|
||||||
|
P9_DPRINTK(P9_DEBUG_ERROR,
|
||||||
|
"special files without extended mode\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user