diff options
author | Mark Rustad <mark.d.rustad@intel.com> | 2012-04-03 13:24:52 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-04-06 21:57:05 -0400 |
commit | 06383f10c49f507220594a455c6491ca6f8c94ab (patch) | |
tree | aeed502673297971463114c1046e82c74ab498f2 /drivers | |
parent | e1c4038282c7586c3544542b37872c434669d3ac (diff) |
tcm_fc: Do not free tpg structure during wq allocation failure
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>
Cc: <stable@vger.kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/tcm_fc/tfc_conf.c | 13 |
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 f357039349ba..2948dc944619 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -300,6 +300,7 @@ static struct se_portal_group *ft_add_tpg( | |||
300 | { | 300 | { |
301 | struct ft_lport_acl *lacl; | 301 | struct ft_lport_acl *lacl; |
302 | struct ft_tpg *tpg; | 302 | struct ft_tpg *tpg; |
303 | struct workqueue_struct *wq; | ||
303 | unsigned long index; | 304 | unsigned long index; |
304 | int ret; | 305 | int ret; |
305 | 306 | ||
@@ -321,18 +322,20 @@ static struct se_portal_group *ft_add_tpg( | |||
321 | tpg->lport_acl = lacl; | 322 | tpg->lport_acl = lacl; |
322 | INIT_LIST_HEAD(&tpg->lun_list); | 323 | INIT_LIST_HEAD(&tpg->lun_list); |
323 | 324 | ||
324 | ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg, | 325 | wq = alloc_workqueue("tcm_fc", 0, 1); |
325 | tpg, TRANSPORT_TPG_TYPE_NORMAL); | 326 | if (!wq) { |
326 | if (ret < 0) { | ||
327 | kfree(tpg); | 327 | kfree(tpg); |
328 | return NULL; | 328 | return NULL; |
329 | } | 329 | } |
330 | 330 | ||
331 | tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1); | 331 | ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg, |
332 | if (!tpg->workqueue) { | 332 | tpg, TRANSPORT_TPG_TYPE_NORMAL); |
333 | if (ret < 0) { | ||
334 | destroy_workqueue(wq); | ||
333 | kfree(tpg); | 335 | kfree(tpg); |
334 | return NULL; | 336 | return NULL; |
335 | } | 337 | } |
338 | tpg->workqueue = wq; | ||
336 | 339 | ||
337 | mutex_lock(&ft_lport_lock); | 340 | mutex_lock(&ft_lport_lock); |
338 | list_add_tail(&tpg->list, &lacl->tpg_list); | 341 | list_add_tail(&tpg->list, &lacl->tpg_list); |