summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2012-04-03 10:24:52 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-13 08:33:49 -0700
commitaba6427f057d78fc9a5051d1b57f5c4798811b7c (patch)
tree9630716d35a862bac3d05265405fd475b63dd847
parent3e9e7cc0e5cf8d8234bce7b85692f2c6082e1e85 (diff)
tcm_fc: Do not free tpg structure during wq allocation failure
commit 06383f10c49f507220594a455c6491ca6f8c94ab upstream. Avoid freeing a registered tpg structure if an alloc_workqueue call fails. This fixes a bug where the failure was leaking memory associated with se_portal_group setup during the original core_tpg_register() call. Signed-off-by: Mark Rustad <mark.d.rustad@intel.com> Acked-by: Kiran Patil <Kiran.patil@intel.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/target/tcm_fc/tfc_conf.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 9402b7387cac..7962325afc32 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -304,6 +304,7 @@ static struct se_portal_group *ft_add_tpg(
{
struct ft_lport_acl *lacl;
struct ft_tpg *tpg;
+ struct workqueue_struct *wq;
unsigned long index;
int ret;
@@ -325,18 +326,20 @@ static struct se_portal_group *ft_add_tpg(
tpg->lport_acl = lacl;
INIT_LIST_HEAD(&tpg->lun_list);
- ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
- tpg, TRANSPORT_TPG_TYPE_NORMAL);
- if (ret < 0) {
+ wq = alloc_workqueue("tcm_fc", 0, 1);
+ if (!wq) {
kfree(tpg);
return NULL;
}
- tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1);
- if (!tpg->workqueue) {
+ ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
+ tpg, TRANSPORT_TPG_TYPE_NORMAL);
+ if (ret < 0) {
+ destroy_workqueue(wq);
kfree(tpg);
return NULL;
}
+ tpg->workqueue = wq;
mutex_lock(&ft_lport_lock);
list_add_tail(&tpg->list, &lacl->tpg_list);