diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2010-07-21 18:57:47 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:05:37 -0400 |
commit | 3cbb7a74a76e45f5e410367259844e8266fba6ec (patch) | |
tree | 0fecd55bd62d80961a0dd7c3fba3523fe8ab5e93 /drivers/scsi/be2iscsi/be_main.c | |
parent | 0aa094331b19e54f928e2ac083285ff68d91c69b (diff) |
[SCSI] be2iscsi: Fix for premature buffer free
This patch fixes a bug where the buffer was being freed as soon as
submission to HW is done.
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_main.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index b70b4ba7207..7436c5ad569 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -71,6 +71,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) | |||
71 | struct beiscsi_hba *phba; | 71 | struct beiscsi_hba *phba; |
72 | struct iscsi_session *session; | 72 | struct iscsi_session *session; |
73 | struct invalidate_command_table *inv_tbl; | 73 | struct invalidate_command_table *inv_tbl; |
74 | struct be_dma_mem nonemb_cmd; | ||
74 | unsigned int cid, tag, num_invalidate; | 75 | unsigned int cid, tag, num_invalidate; |
75 | 76 | ||
76 | cls_session = starget_to_session(scsi_target(sc->device)); | 77 | cls_session = starget_to_session(scsi_target(sc->device)); |
@@ -101,18 +102,34 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) | |||
101 | inv_tbl->cid = cid; | 102 | inv_tbl->cid = cid; |
102 | inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; | 103 | inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; |
103 | num_invalidate = 1; | 104 | num_invalidate = 1; |
104 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); | 105 | nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, |
106 | sizeof(struct invalidate_commands_params_in), | ||
107 | &nonemb_cmd.dma); | ||
108 | if (nonemb_cmd.va == NULL) { | ||
109 | SE_DEBUG(DBG_LVL_1, | ||
110 | "Failed to allocate memory for" | ||
111 | "mgmt_invalidate_icds\n"); | ||
112 | return FAILED; | ||
113 | } | ||
114 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); | ||
115 | |||
116 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, | ||
117 | cid, &nonemb_cmd); | ||
105 | if (!tag) { | 118 | if (!tag) { |
106 | shost_printk(KERN_WARNING, phba->shost, | 119 | shost_printk(KERN_WARNING, phba->shost, |
107 | "mgmt_invalidate_icds could not be" | 120 | "mgmt_invalidate_icds could not be" |
108 | " submitted\n"); | 121 | " submitted\n"); |
122 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | ||
123 | nonemb_cmd.va, nonemb_cmd.dma); | ||
124 | |||
109 | return FAILED; | 125 | return FAILED; |
110 | } else { | 126 | } else { |
111 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | 127 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], |
112 | phba->ctrl.mcc_numtag[tag]); | 128 | phba->ctrl.mcc_numtag[tag]); |
113 | free_mcc_tag(&phba->ctrl, tag); | 129 | free_mcc_tag(&phba->ctrl, tag); |
114 | } | 130 | } |
115 | 131 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | |
132 | nonemb_cmd.va, nonemb_cmd.dma); | ||
116 | return iscsi_eh_abort(sc); | 133 | return iscsi_eh_abort(sc); |
117 | } | 134 | } |
118 | 135 | ||
@@ -126,6 +143,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
126 | struct iscsi_session *session; | 143 | struct iscsi_session *session; |
127 | struct iscsi_cls_session *cls_session; | 144 | struct iscsi_cls_session *cls_session; |
128 | struct invalidate_command_table *inv_tbl; | 145 | struct invalidate_command_table *inv_tbl; |
146 | struct be_dma_mem nonemb_cmd; | ||
129 | unsigned int cid, tag, i, num_invalidate; | 147 | unsigned int cid, tag, i, num_invalidate; |
130 | int rc = FAILED; | 148 | int rc = FAILED; |
131 | 149 | ||
@@ -160,18 +178,33 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
160 | spin_unlock_bh(&session->lock); | 178 | spin_unlock_bh(&session->lock); |
161 | inv_tbl = phba->inv_tbl; | 179 | inv_tbl = phba->inv_tbl; |
162 | 180 | ||
163 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); | 181 | nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, |
182 | sizeof(struct invalidate_commands_params_in), | ||
183 | &nonemb_cmd.dma); | ||
184 | if (nonemb_cmd.va == NULL) { | ||
185 | SE_DEBUG(DBG_LVL_1, | ||
186 | "Failed to allocate memory for" | ||
187 | "mgmt_invalidate_icds\n"); | ||
188 | return FAILED; | ||
189 | } | ||
190 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); | ||
191 | memset(nonemb_cmd.va, 0, nonemb_cmd.size); | ||
192 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, | ||
193 | cid, &nonemb_cmd); | ||
164 | if (!tag) { | 194 | if (!tag) { |
165 | shost_printk(KERN_WARNING, phba->shost, | 195 | shost_printk(KERN_WARNING, phba->shost, |
166 | "mgmt_invalidate_icds could not be" | 196 | "mgmt_invalidate_icds could not be" |
167 | " submitted\n"); | 197 | " submitted\n"); |
198 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | ||
199 | nonemb_cmd.va, nonemb_cmd.dma); | ||
168 | return FAILED; | 200 | return FAILED; |
169 | } else { | 201 | } else { |
170 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | 202 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], |
171 | phba->ctrl.mcc_numtag[tag]); | 203 | phba->ctrl.mcc_numtag[tag]); |
172 | free_mcc_tag(&phba->ctrl, tag); | 204 | free_mcc_tag(&phba->ctrl, tag); |
173 | } | 205 | } |
174 | 206 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | |
207 | nonemb_cmd.va, nonemb_cmd.dma); | ||
175 | return iscsi_eh_device_reset(sc); | 208 | return iscsi_eh_device_reset(sc); |
176 | unlock: | 209 | unlock: |
177 | spin_unlock_bh(&session->lock); | 210 | spin_unlock_bh(&session->lock); |