diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2012-07-20 03:07:34 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-07-20 14:34:21 -0400 |
commit | 2962846d14769e526b5d266f4af998b5a027b1d7 (patch) | |
tree | 6ccd195cd39b6cbec2ed8f25e38f28ff98fdecf3 /drivers/target | |
parent | d6dfc868bcf329392abd1ecfa7357eb51ebf8c30 (diff) |
target: NULL dereference on error path
During a failure in transport_add_device_to_core_hba() code, we called
destroy_workqueue(dev->tmr_wq) before ->tmr_wq was allocated which leads
to an oops.
This fixes a regression introduced in with:
commit af8772926f019b7bddd7477b8de5f3b0f12bad21
Author: Christoph Hellwig <hch@infradead.org>
Date: Sun Jul 8 15:58:49 2012 -0400
target: replace the processing thread with a TMR work queue
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 7647ecafbcc7..0eaae23d12b5 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1098,7 +1098,7 @@ struct se_device *transport_add_device_to_core_hba( | |||
1098 | * Setup the Asymmetric Logical Unit Assignment for struct se_device | 1098 | * Setup the Asymmetric Logical Unit Assignment for struct se_device |
1099 | */ | 1099 | */ |
1100 | if (core_setup_alua(dev, force_pt) < 0) | 1100 | if (core_setup_alua(dev, force_pt) < 0) |
1101 | goto out; | 1101 | goto err_dev_list; |
1102 | 1102 | ||
1103 | /* | 1103 | /* |
1104 | * Startup the struct se_device processing thread | 1104 | * Startup the struct se_device processing thread |
@@ -1108,7 +1108,7 @@ struct se_device *transport_add_device_to_core_hba( | |||
1108 | if (!dev->tmr_wq) { | 1108 | if (!dev->tmr_wq) { |
1109 | pr_err("Unable to create tmr workqueue for %s\n", | 1109 | pr_err("Unable to create tmr workqueue for %s\n", |
1110 | dev->transport->name); | 1110 | dev->transport->name); |
1111 | goto out; | 1111 | goto err_dev_list; |
1112 | } | 1112 | } |
1113 | /* | 1113 | /* |
1114 | * Setup work_queue for QUEUE_FULL | 1114 | * Setup work_queue for QUEUE_FULL |
@@ -1126,7 +1126,7 @@ struct se_device *transport_add_device_to_core_hba( | |||
1126 | if (!inquiry_prod || !inquiry_rev) { | 1126 | if (!inquiry_prod || !inquiry_rev) { |
1127 | pr_err("All non TCM/pSCSI plugins require" | 1127 | pr_err("All non TCM/pSCSI plugins require" |
1128 | " INQUIRY consts\n"); | 1128 | " INQUIRY consts\n"); |
1129 | goto out; | 1129 | goto err_wq; |
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | strncpy(&dev->se_sub_dev->t10_wwn.vendor[0], "LIO-ORG", 8); | 1132 | strncpy(&dev->se_sub_dev->t10_wwn.vendor[0], "LIO-ORG", 8); |
@@ -1136,9 +1136,10 @@ struct se_device *transport_add_device_to_core_hba( | |||
1136 | scsi_dump_inquiry(dev); | 1136 | scsi_dump_inquiry(dev); |
1137 | 1137 | ||
1138 | return dev; | 1138 | return dev; |
1139 | out: | ||
1140 | destroy_workqueue(dev->tmr_wq); | ||
1141 | 1139 | ||
1140 | err_wq: | ||
1141 | destroy_workqueue(dev->tmr_wq); | ||
1142 | err_dev_list: | ||
1142 | spin_lock(&hba->device_lock); | 1143 | spin_lock(&hba->device_lock); |
1143 | list_del(&dev->dev_list); | 1144 | list_del(&dev->dev_list); |
1144 | hba->dev_count--; | 1145 | hba->dev_count--; |