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 | |
| 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>
| -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); |
