Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 951f746f authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley
Browse files

[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: 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 8627533c
Loading
Loading
Loading
Loading
+8 −13
Original line number Diff line number Diff line
@@ -1116,6 +1116,10 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
		goto out;
	}

	if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
			&unit->status)))
		goto unit_blocked;

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
        sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
        sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
@@ -1131,22 +1135,13 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,

	zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);
	retval = zfcp_fsf_req_send(fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Failed to send abort command request "
			      "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
			      zfcp_get_busid_by_adapter(adapter),
			      unit->port->wwpn, unit->fcp_lun);
	if (!retval)
		goto out;

 unit_blocked:
		zfcp_fsf_req_free(fsf_req);
		fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_DEBUG("Abort FCP Command request initiated "
		       "(adapter%s, port d_id=0x%06x, "
		       "unit x%016Lx, old_req_id=0x%lx)\n",
		       zfcp_get_busid_by_adapter(adapter),
		       unit->port->d_id,
		       unit->fcp_lun, old_req_id);
 out:
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
	return fsf_req;