Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2010-09-02 09:11:50 +0200
committerHannes Reinecke <hare@suse.de>2010-09-02 09:11:50 +0200
commitab50bb10700cf1c5951a6359dc665c6c10644d3d (patch)
tree4c0c1a143592138b7d793e598a9e2c002b164c9b
parentdd103d473a325deb04eaca759006e3e0dac82fa7 (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.changes6
-rw-r--r--patches.fixes/scsi-update-fc_block_scsi_eh256
-rw-r--r--series.conf1
3 files changed, 263 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index eb2cf8dafb..dbfb8c13dd 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 0000000000..1bac027fd0
--- /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 ceba74de93..951f254752 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