Skip to content

Commit

Permalink
[PATCH] qla2xxx: Close window on race between rport removal and fcpor…
Browse files Browse the repository at this point in the history
…t 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>
  • Loading branch information
andrew.vasquez@qlogic.com authored and Unknown committed Feb 7, 2006
1 parent 62288f1 commit 387f96b
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
goto qc_fail_command;
}

/* Close window on fcport/rport state-transitioning. */
if (!*(fc_port_t **)rport->dd_data) {
cmd->result = DID_IMM_RETRY << 16;
goto qc_fail_command;
}

if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
atomic_read(&ha->loop_state) == LOOP_DEAD) {
Expand Down Expand Up @@ -421,6 +427,12 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
goto qc24_fail_command;
}

/* Close window on fcport/rport state-transitioning. */
if (!*(fc_port_t **)rport->dd_data) {
cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}

if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
atomic_read(&ha->loop_state) == LOOP_DEAD) {
Expand Down Expand Up @@ -1675,11 +1687,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->drport = rport;
fcport->rport = NULL;
*(fc_port_t **)rport->dd_data = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
} else {
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->rport = NULL;
*(fc_port_t **)rport->dd_data = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
fc_remote_port_delete(rport);
}
Expand Down

0 comments on commit 387f96b

Please sign in to comment.