diff options
author | Anil Gurumurthy <anil.gurumurthy@qlogic.com> | 2015-11-26 03:54:00 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2015-12-02 17:06:45 -0500 |
commit | 3c3da12d3174891f61f0f2c672da095562f19b92 (patch) | |
tree | d42fecd5fcd2b39f32ba22b0fc0d84ebd9d7de5f | |
parent | 889d0d42667c998a099028f845c0be074acb4b90 (diff) |
bfa: Fix for crash when bfa_itnim is NULL
Fix a very corner case when the port gets disconnected and the BFA and
FCS layers clean up references to the IT nexus. During this window if a
task management command is issued by the SCSI-ML and ends up referencing
a NULL itnim, it could lead to a crash.
Signed-off-by: Sudarsana Kalluru <sudarsana.kalluru@qlogic.com>
Signed-off-by: Anil Gurumurthy <anil.gurumurthy@qlogic.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/bfa/bfad_im.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index efcb2470f40a..2c0cf8a46a47 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -272,6 +272,19 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, | |||
272 | cmnd->host_scribble = NULL; | 272 | cmnd->host_scribble = NULL; |
273 | cmnd->SCp.Status = 0; | 273 | cmnd->SCp.Status = 0; |
274 | bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); | 274 | bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); |
275 | /* | ||
276 | * bfa_itnim can be NULL if the port gets disconnected and the bfa | ||
277 | * and fcs layers have cleaned up their nexus with the targets and | ||
278 | * the same has not been cleaned up by the shim | ||
279 | */ | ||
280 | if (bfa_itnim == NULL) { | ||
281 | bfa_tskim_free(tskim); | ||
282 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, | ||
283 | "target reset, bfa_itnim is NULL\n"); | ||
284 | rc = BFA_STATUS_FAILED; | ||
285 | goto out; | ||
286 | } | ||
287 | |||
275 | memset(&scsilun, 0, sizeof(scsilun)); | 288 | memset(&scsilun, 0, sizeof(scsilun)); |
276 | bfa_tskim_start(tskim, bfa_itnim, scsilun, | 289 | bfa_tskim_start(tskim, bfa_itnim, scsilun, |
277 | FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO); | 290 | FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO); |
@@ -327,6 +340,19 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
327 | cmnd->SCp.ptr = (char *)&wq; | 340 | cmnd->SCp.ptr = (char *)&wq; |
328 | cmnd->SCp.Status = 0; | 341 | cmnd->SCp.Status = 0; |
329 | bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); | 342 | bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); |
343 | /* | ||
344 | * bfa_itnim can be NULL if the port gets disconnected and the bfa | ||
345 | * and fcs layers have cleaned up their nexus with the targets and | ||
346 | * the same has not been cleaned up by the shim | ||
347 | */ | ||
348 | if (bfa_itnim == NULL) { | ||
349 | bfa_tskim_free(tskim); | ||
350 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, | ||
351 | "lun reset, bfa_itnim is NULL\n"); | ||
352 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
353 | rc = FAILED; | ||
354 | goto out; | ||
355 | } | ||
330 | int_to_scsilun(cmnd->device->lun, &scsilun); | 356 | int_to_scsilun(cmnd->device->lun, &scsilun); |
331 | bfa_tskim_start(tskim, bfa_itnim, scsilun, | 357 | bfa_tskim_start(tskim, bfa_itnim, scsilun, |
332 | FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); | 358 | FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); |