| summaryrefslogtreecommitdiff |
| author | Hannes Reinecke <hare@suse.de> | 2010-09-02 07:11:50 (GMT) |
|---|---|---|
| committer | Hannes Reinecke <hare@suse.de> | 2010-09-02 07:11:50 (GMT) |
| commit | ab50bb10700cf1c5951a6359dc665c6c10644d3d (patch) (side-by-side diff) | |
| tree | 4c0c1a143592138b7d793e598a9e2c002b164c9b | |
| parent | dd103d473a325deb04eaca759006e3e0dac82fa7 (diff) | |
- patches.fixes/scsi-update-fc_block_scsi_eh: Device offlinedrpm-2.6.32.19-0.2
while array is momentarily unavailable (bnc#613330).
| -rw-r--r-- | kernel-source.changes | 6 | ||||
| -rw-r--r-- | patches.fixes/scsi-update-fc_block_scsi_eh | 256 | ||||
| -rw-r--r-- | series.conf | 1 |
3 files changed, 263 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes index eb2cf8d..dbfb8c1 100644 --- a/kernel-source.changes +++ b/kernel-source.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Thu Sep 2 09:11:42 CEST 2010 - hare@suse.de + +- patches.fixes/scsi-update-fc_block_scsi_eh: Device offlined + while array is momentarily unavailable (bnc#613330). + +------------------------------------------------------------------- Thu Sep 2 08:44:05 CEST 2010 - hare@suse.de - patches.fixes/scsi-return-needs-retry-for-busy-eh-cmds: Return diff --git a/patches.fixes/scsi-update-fc_block_scsi_eh b/patches.fixes/scsi-update-fc_block_scsi_eh new file mode 100644 index 0000000..1bac027 --- a/dev/null +++ b/patches.fixes/scsi-update-fc_block_scsi_eh @@ -0,0 +1,256 @@ +From: Hannes Reinecke <hare@suse.de> +Subject: Device offlined while array is momentarily unavailable +References: bnc#613330 +Patch-Mainline: Submitted to linux-scsi + +During I/O error injection tests devices are offlined unexpectedly. +Problem is that fc_block_scsi_eh() will return when I/O is terminated +due to fast_io_fail timeout. In which case we shouldn't be running the +error recovery routines of the driver, as the original condition +hasn't cleared. +So we need to check the return state from fc_block_scsi_eh() and +return if the state is not SUCCESS. +But for this we need to modify fc_block_scsi_eh() to not return '0' +but rather the standard 'SUCCESS' variable here. + +Signed-off-by: Hannes Reinecke <hare@suse.de> +Acked-by: James Smart <james.smart@emulex.com> +Acked-by: Andrew Vasquez <andrew.vasquez@qlogic.com> + +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index 05b679b..d84e9eb 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -215,7 +215,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) + + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); +- if (ret) ++ if (ret != SUCCESS) + return ret; + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_RUNNING)) { +@@ -257,7 +257,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) + + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); +- if (ret) ++ if (ret != SUCCESS) + return ret; + + if (!(atomic_read(&adapter->status) & +@@ -302,11 +302,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) + + zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt); + zfcp_erp_wait(adapter); +- ret = fc_block_scsi_eh(scpnt); +- if (ret) +- return ret; +- +- return SUCCESS; ++ return fc_block_scsi_eh(scpnt); + } + + int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) +diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c +index 37150e8..ffc6988 100644 +--- a/drivers/scsi/fnic/fnic_scsi.c ++++ b/drivers/scsi/fnic/fnic_scsi.c +@@ -1243,7 +1243,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) + DECLARE_COMPLETION_ONSTACK(tm_done); + + /* Wait for rport to unblock */ +- fc_block_scsi_eh(sc); ++ ret = fc_block_scsi_eh(sc); ++ if (ret != SUCCESS) ++ return ret; + + /* Get local-port, check ready and link up */ + lp = shost_priv(sc->device->host); +@@ -1519,13 +1521,15 @@ int fnic_device_reset(struct scsi_cmnd *sc) + struct fnic_io_req *io_req; + struct fc_rport *rport; + int status; +- int ret = FAILED; ++ int ret; + spinlock_t *io_lock; + unsigned long flags; + DECLARE_COMPLETION_ONSTACK(tm_done); + + /* Wait for rport to unblock */ +- fc_block_scsi_eh(sc); ++ ret = fc_block_scsi_eh(sc); ++ if (ret != SUCCESS) ++ return ret; + + /* Get local-port, check ready and link up */ + lp = shost_priv(sc->device->host); +@@ -1537,7 +1541,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) + (starget_to_rport(scsi_target(sc->device)))->port_id, + sc->device->lun); + +- ++ ret = FAILED; + if (lp->state != LPORT_ST_READY || !(lp->link_up)) + goto fnic_device_reset_end; + +diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c +index a4881f2..df48f52 100644 +--- a/drivers/scsi/lpfc/lpfc_scsi.c ++++ b/drivers/scsi/lpfc/lpfc_scsi.c +@@ -2989,7 +2989,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) + int ret = SUCCESS; + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); + +- fc_block_scsi_eh(cmnd); ++ ret = fc_block_scsi_eh(cmnd); ++ if (ret != SUCCESS) ++ return ret; ++ + lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; + BUG_ON(!lpfc_cmd); + +@@ -3305,7 +3308,9 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) + return FAILED; + } + pnode = rdata->pnode; +- fc_block_scsi_eh(cmnd); ++ status = fc_block_scsi_eh(cmnd); ++ if (status != SUCCESS) ++ return status; + + status = lpfc_chk_tgt_mapped(vport, cmnd); + if (status == FAILED) { +@@ -3370,7 +3375,9 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) + return FAILED; + } + pnode = rdata->pnode; +- fc_block_scsi_eh(cmnd); ++ status = fc_block_scsi_eh(cmnd); ++ if (status != SUCCESS) ++ return status; + + status = lpfc_chk_tgt_mapped(vport, cmnd); + if (status == FAILED) { +@@ -3427,6 +3434,10 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) + int match; + int ret = SUCCESS, status, i; + ++ ret = fc_block_scsi_eh(cmnd); ++ if (ret != SUCCESS) ++ return ret; ++ + scsi_event.event_type = FC_REG_SCSI_EVENT; + scsi_event.subcategory = LPFC_EVENT_BUSRESET; + scsi_event.lun = 0; +@@ -3436,8 +3447,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) + fc_host_post_vendor_event(shost, fc_get_event_number(), + sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); + +- fc_block_scsi_eh(cmnd); +- + /* + * Since the driver manages a single bus device, reset all + * targets known to the driver. Should any target reset +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index c16a861..a673e5b 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -777,12 +777,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) + srb_t *spt; + int got_ref = 0; + +- fc_block_scsi_eh(cmd); +- + if (!CMD_SP(cmd)) + return SUCCESS; + +- ret = SUCCESS; ++ ret = fc_block_scsi_eh(cmd); ++ if (ret != SUCCESS) ++ return ret; + + id = cmd->device->id; + lun = cmd->device->lun; +@@ -915,7 +915,9 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, + fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + int err; + +- fc_block_scsi_eh(cmd); ++ err = fc_block_scsi_eh(cmd); ++ if (err != SUCCESS) ++ return err; + + if (!fcport) + return FAILED; +@@ -990,17 +992,21 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) + { + scsi_qla_host_t *vha = shost_priv(cmd->device->host); + fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; +- int ret = FAILED; ++ int ret; + unsigned int id, lun; + unsigned long serial; + srb_t *sp = (srb_t *) CMD_SP(cmd); + +- fc_block_scsi_eh(cmd); ++ ret = fc_block_scsi_eh(cmd); ++ if (ret != SUCCESS) ++ return ret; + + id = cmd->device->id; + lun = cmd->device->lun; + serial = cmd->serial_number; + ++ ret = FAILED; ++ + if (!fcport) + return ret; + +@@ -1052,18 +1058,22 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) + scsi_qla_host_t *vha = shost_priv(cmd->device->host); + fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + struct qla_hw_data *ha = vha->hw; +- int ret = FAILED; ++ int ret; + unsigned int id, lun; + unsigned long serial; + srb_t *sp = (srb_t *) CMD_SP(cmd); + scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); + +- fc_block_scsi_eh(cmd); ++ ret = fc_block_scsi_eh(cmd); ++ if (ret != SUCCESS) ++ return ret; + + id = cmd->device->id; + lun = cmd->device->lun; + serial = cmd->serial_number; + ++ ret = FAILED; ++ + if (!fcport) + return ret; + +diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c +index 3310e9e..1113c6f 100644 +--- a/drivers/scsi/scsi_transport_fc.c ++++ b/drivers/scsi/scsi_transport_fc.c +@@ -3200,7 +3200,7 @@ fc_scsi_scan_rport(struct work_struct *work) + * necessary to avoid the scsi_eh failing recovery actions for blocked + * rports which would lead to offlined SCSI devices. + * +- * Returns: 0 if the fc_rport left the state FC_PORTSTATE_BLOCKED. ++ * Returns: SUCCESS if the fc_rport left the state FC_PORTSTATE_BLOCKED. + * FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be + * passed back to scsi_eh. + */ +@@ -3222,7 +3222,7 @@ int fc_block_scsi_eh(struct scsi_cmnd *cmnd) + if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) + return FAST_IO_FAIL; + +- return 0; ++ return SUCCESS; + } + EXPORT_SYMBOL(fc_block_scsi_eh); + diff --git a/series.conf b/series.conf index ceba74d..951f254 100644 --- a/series.conf +++ b/series.conf @@ -1255,6 +1255,7 @@ patches.drivers/mpt-fusion-fix-races-with-deleted.patch patches.fixes/scsi-dh-alua-crash-on-stpg-failback patches.fixes/scsi-return-needs-retry-for-busy-eh-cmds + patches.fixes/scsi-update-fc_block_scsi_eh # Remaining SCSI patches (garloff) patches.suse/scsi-error-test-unit-ready-timeout |