[PATCH] qla2xxx: Close window on race between rport removal and fcport transition.

Fcport visibility is recognized during interrupt time, but,
rport removal can only occur during a process
(sleeping)-context. Return a DID_IMM_RETRY status for
commands submitted within this window to insure I/Os do not
prematurely run-out of retries.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by andrew.vasquez@qlogic.com and committed by 387f96b4 62288f10

+14
+14
drivers/scsi/qla2xxx/qla_os.c
··· 366 366 goto qc_fail_command; 367 367 } 368 368 369 + /* Close window on fcport/rport state-transitioning. */ 370 + if (!*(fc_port_t **)rport->dd_data) { 371 + cmd->result = DID_IMM_RETRY << 16; 372 + goto qc_fail_command; 373 + } 374 + 369 375 if (atomic_read(&fcport->state) != FCS_ONLINE) { 370 376 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || 371 377 atomic_read(&ha->loop_state) == LOOP_DEAD) { ··· 424 418 rval = fc_remote_port_chkready(rport); 425 419 if (rval) { 426 420 cmd->result = rval; 421 + goto qc24_fail_command; 422 + } 423 + 424 + /* Close window on fcport/rport state-transitioning. */ 425 + if (!*(fc_port_t **)rport->dd_data) { 426 + cmd->result = DID_IMM_RETRY << 16; 427 427 goto qc24_fail_command; 428 428 } 429 429 ··· 1687 1675 spin_lock_irqsave(&fcport->rport_lock, flags); 1688 1676 fcport->drport = rport; 1689 1677 fcport->rport = NULL; 1678 + *(fc_port_t **)rport->dd_data = NULL; 1690 1679 spin_unlock_irqrestore(&fcport->rport_lock, flags); 1691 1680 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); 1692 1681 } else { 1693 1682 spin_lock_irqsave(&fcport->rport_lock, flags); 1694 1683 fcport->rport = NULL; 1684 + *(fc_port_t **)rport->dd_data = NULL; 1695 1685 spin_unlock_irqrestore(&fcport->rport_lock, flags); 1696 1686 fc_remote_port_delete(rport); 1697 1687 }