Commit ba172420 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[SCSI] zfcp: Hold queue lock when checking port/unit handle for FCP command

We need to hold the queue-lock when checking whether we still have a valid
unit/port handle for the FCP command, i.e whether we can issue this request for
this unit/port. If the error recovery is about to close this unit/port, then it
competes for the queue-lock. If the close request issued by the error recovery
wins, then it is guaranteed that this unit/port has been blocked for other
requests.
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarMartin Peschke <mp3@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 3f0ca62a
...@@ -3593,6 +3593,12 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, ...@@ -3593,6 +3593,12 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
goto failed_req_create; goto failed_req_create;
} }
if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
&unit->status))) {
retval = -EBUSY;
goto unit_blocked;
}
zfcp_unit_get(unit); zfcp_unit_get(unit);
fsf_req->unit = unit; fsf_req->unit = unit;
...@@ -3733,6 +3739,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, ...@@ -3733,6 +3739,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
send_failed: send_failed:
no_fit: no_fit:
failed_scsi_cmnd: failed_scsi_cmnd:
unit_blocked:
zfcp_unit_put(unit); zfcp_unit_put(unit);
zfcp_fsf_req_free(fsf_req); zfcp_fsf_req_free(fsf_req);
fsf_req = NULL; fsf_req = NULL;
......
...@@ -258,8 +258,9 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, ...@@ -258,8 +258,9 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
goto out; goto out;
} }
if (unlikely( tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, use_timer,
!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))) { ZFCP_REQ_AUTO_CLEANUP);
if (unlikely(tmp == -EBUSY)) {
ZFCP_LOG_DEBUG("adapter %s not ready or unit 0x%016Lx " ZFCP_LOG_DEBUG("adapter %s not ready or unit 0x%016Lx "
"on port 0x%016Lx in recovery\n", "on port 0x%016Lx in recovery\n",
zfcp_get_busid_by_unit(unit), zfcp_get_busid_by_unit(unit),
...@@ -268,9 +269,6 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, ...@@ -268,9 +269,6 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
goto out; goto out;
} }
tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, use_timer,
ZFCP_REQ_AUTO_CLEANUP);
if (unlikely(tmp < 0)) { if (unlikely(tmp < 0)) {
ZFCP_LOG_DEBUG("error: initiation of Send FCP Cmnd failed\n"); ZFCP_LOG_DEBUG("error: initiation of Send FCP Cmnd failed\n");
retval = SCSI_MLQUEUE_HOST_BUSY; retval = SCSI_MLQUEUE_HOST_BUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment