diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2010-02-08 10:12:05 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-16 16:01:17 -0800 |
commit | c947862f9126983537a4cc11e07d26882d60b7e7 (patch) | |
tree | 335ae3483ea540877ff5230c3f43288847300417 | |
parent | 54716e3beb0ab20c49471348dfe399a71bfc8fd3 (diff) |
CAPI: Fix leaks in capifs_new_ncci
When something went wrong during capifs_new_ncci, the looked up dentry
was not properly released. Neither was the allocated inode. Refactor the
function to avoid leaks.
Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/isdn/capi/capifs.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 9f8f67b6c07f..dc68fcb122a0 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -152,22 +152,33 @@ static struct dentry *get_node(int num) void capifs_new_ncci(unsigned int number, dev_t device) { struct dentry *dentry; - struct inode *inode = new_inode(capifs_mnt->mnt_sb); - if (!inode) - return; - inode->i_ino = number+2; + struct inode *inode; dentry = get_node(number); + if (IS_ERR(dentry)) + goto unlock_out; + + if (dentry->d_inode) { + dput(dentry); + goto unlock_out; + } + + inode = new_inode(capifs_mnt->mnt_sb); + if (!inode) { + dput(dentry); + goto unlock_out; + } /* config contents is protected by root's i_mutex */ inode->i_uid = config.setuid ? config.uid : current_fsuid(); inode->i_gid = config.setgid ? config.gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_ino = number + 2; init_special_inode(inode, S_IFCHR|config.mode, device); - //inode->i_op = &capifs_file_inode_operations; - if (!IS_ERR(dentry) && !dentry->d_inode) - d_instantiate(dentry, inode); + d_instantiate(dentry, inode); + +unlock_out: mutex_unlock(&capifs_root->d_inode->i_mutex); } |