[SCSI] ibmvfc: Fix double completion on abort timeout

If an abort request times out to the virtual fibre channel adapter,
the ibmvfc driver will kick off a reset of the adapter. This
patch ensures we wait for the both the abort request and the
request being aborted to be completed prior to exiting the
eh_abort handler. This fixes a bug where the ibmvfc driver
was erroneously returning success to the eh_abort handler
then later sending back a response to the same command.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Brian King 2012-08-24 16:50:59 -05:00 committed by James Bottomley
parent 7731e6bb31
commit a077c7faf3
1 changed files with 29 additions and 1 deletions

View File

@ -2241,6 +2241,21 @@ static int ibmvfc_match_key(struct ibmvfc_event *evt, void *key)
return 0; return 0;
} }
/**
* ibmvfc_match_evt - Match function for specified event
* @evt: ibmvfc event struct
* @match: event to match
*
* Returns:
* 1 if event matches key / 0 if event does not match key
**/
static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match)
{
if (evt == match)
return 1;
return 0;
}
/** /**
* ibmvfc_abort_task_set - Abort outstanding commands to the device * ibmvfc_abort_task_set - Abort outstanding commands to the device
* @sdev: scsi device to abort commands * @sdev: scsi device to abort commands
@ -2322,7 +2337,20 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
if (rc) { if (rc) {
sdev_printk(KERN_INFO, sdev, "Cancel failed, resetting host\n"); sdev_printk(KERN_INFO, sdev, "Cancel failed, resetting host\n");
ibmvfc_reset_host(vhost); ibmvfc_reset_host(vhost);
rsp_rc = 0; rsp_rc = -EIO;
rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key);
if (rc == SUCCESS)
rsp_rc = 0;
rc = ibmvfc_wait_for_ops(vhost, evt, ibmvfc_match_evt);
if (rc != SUCCESS) {
spin_lock_irqsave(vhost->host->host_lock, flags);
ibmvfc_hard_reset_host(vhost);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
rsp_rc = 0;
}
goto out; goto out;
} }
} }