Commit 951f746fece2e24a26853b3872d16e9013b6fe0b

Authored by Christof Schmitt
Committed by James Bottomley
1 parent 8627533c11

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

We need to hold the queue-lock when checking whether we still have a valid
unit/port handle for the abort 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: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: Martin Peschke <mp3@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

Showing 1 changed file with 8 additions and 13 deletions Side-by-side Diff

drivers/s390/scsi/zfcp_fsf.c
... ... @@ -1116,6 +1116,10 @@
1116 1116 goto out;
1117 1117 }
1118 1118  
  1119 + if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
  1120 + &unit->status)))
  1121 + goto unit_blocked;
  1122 +
1119 1123 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
1120 1124 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
1121 1125 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
1122 1126  
1123 1127  
... ... @@ -1131,22 +1135,13 @@
1131 1135  
1132 1136 zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);
1133 1137 retval = zfcp_fsf_req_send(fsf_req);
1134   - if (retval) {
1135   - ZFCP_LOG_INFO("error: Failed to send abort command request "
1136   - "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
1137   - zfcp_get_busid_by_adapter(adapter),
1138   - unit->port->wwpn, unit->fcp_lun);
  1138 + if (!retval)
  1139 + goto out;
  1140 +
  1141 + unit_blocked:
1139 1142 zfcp_fsf_req_free(fsf_req);
1140 1143 fsf_req = NULL;
1141   - goto out;
1142   - }
1143 1144  
1144   - ZFCP_LOG_DEBUG("Abort FCP Command request initiated "
1145   - "(adapter%s, port d_id=0x%06x, "
1146   - "unit x%016Lx, old_req_id=0x%lx)\n",
1147   - zfcp_get_busid_by_adapter(adapter),
1148   - unit->port->d_id,
1149   - unit->fcp_lun, old_req_id);
1150 1145 out:
1151 1146 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
1152 1147 return fsf_req;