Commit 54d816d3 authored by Ewan D. Milne's avatar Ewan D. Milne Committed by Martin K. Petersen
Browse files

scsi: core: Simplify control flow in scmd_eh_abort_handler()

Simplify the nested conditionals in the function by using a label for the
error path.  Introduce local "shost" to avoid repeated "sdev->shost" usage.
Also remove scsi_eh_complete_abort() since there is now only one place it
would be called.

Link: https://lore.kernel.org/r/20211029194311.17504-3-emilne@redhat.com


Signed-off-by: default avatarEwan D. Milne <emilne@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent fa55b7dc
Loading
Loading
Loading
Loading
+55 −54
Original line number Diff line number Diff line
@@ -133,23 +133,6 @@ static bool scsi_eh_should_retry_cmd(struct scsi_cmnd *cmd)
	return true;
}

static void scsi_eh_complete_abort(struct scsi_cmnd *scmd, struct Scsi_Host *shost)
{
	unsigned long flags;

	spin_lock_irqsave(shost->host_lock, flags);
	list_del_init(&scmd->eh_entry);
	/*
	 * If the abort succeeds, and there is no further
	 * EH action, clear the ->last_reset time.
	 */
	if (list_empty(&shost->eh_abort_list) &&
	    list_empty(&shost->eh_cmd_q))
		if (shost->eh_deadline != -1)
			shost->last_reset = 0;
	spin_unlock_irqrestore(shost->host_lock, flags);
}

/**
 * scmd_eh_abort_handler - Handle command aborts
 * @work:	command to be aborted.
@@ -166,54 +149,72 @@ scmd_eh_abort_handler(struct work_struct *work)
	struct scsi_cmnd *scmd =
		container_of(work, struct scsi_cmnd, abort_work.work);
	struct scsi_device *sdev = scmd->device;
	struct Scsi_Host *shost = sdev->host;
	enum scsi_disposition rtn;
	unsigned long flags;

	if (scsi_host_eh_past_deadline(sdev->host)) {
	if (scsi_host_eh_past_deadline(shost)) {
		SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_INFO, scmd,
				    "eh timeout, not aborting\n"));
	} else {
		goto out;
	}

	SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_INFO, scmd,
				    "aborting command\n"));
		rtn = scsi_try_to_abort_cmd(sdev->host->hostt, scmd);
		if (rtn == SUCCESS) {
	rtn = scsi_try_to_abort_cmd(shost->hostt, scmd);
	if (rtn != SUCCESS) {
		SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_INFO, scmd,
				    "cmd abort %s\n",
				    (rtn == FAST_IO_FAIL) ?
				    "not send" : "failed"));
		goto out;
	}
	set_host_byte(scmd, DID_TIME_OUT);
			if (scsi_host_eh_past_deadline(sdev->host)) {
	if (scsi_host_eh_past_deadline(shost)) {
		SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_INFO, scmd,
				    "eh timeout, not retrying "
				    "aborted command\n"));
			} else if (!scsi_noretry_cmd(scmd) &&
		goto out;
	}

	spin_lock_irqsave(shost->host_lock, flags);
	list_del_init(&scmd->eh_entry);

	/*
	 * If the abort succeeds, and there is no further
	 * EH action, clear the ->last_reset time.
	 */
	if (list_empty(&shost->eh_abort_list) &&
	    list_empty(&shost->eh_cmd_q))
		if (shost->eh_deadline != -1)
			shost->last_reset = 0;

	spin_unlock_irqrestore(shost->host_lock, flags);

	if (!scsi_noretry_cmd(scmd) &&
	    scsi_cmd_retry_allowed(scmd) &&
	    scsi_eh_should_retry_cmd(scmd)) {
		SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_WARNING, scmd,
				    "retry aborted command\n"));
				scsi_eh_complete_abort(scmd, sdev->host);
		scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
				return;
	} else {
		SCSI_LOG_ERROR_RECOVERY(3,
			scmd_printk(KERN_WARNING, scmd,
				    "finish aborted command\n"));
				scsi_eh_complete_abort(scmd, sdev->host);
		scsi_finish_command(scmd);
				return;
			}
		} else {
			SCSI_LOG_ERROR_RECOVERY(3,
				scmd_printk(KERN_INFO, scmd,
					    "cmd abort %s\n",
					    (rtn == FAST_IO_FAIL) ?
					    "not send" : "failed"));
		}
	}
	return;

	spin_lock_irqsave(sdev->host->host_lock, flags);
out:
	spin_lock_irqsave(shost->host_lock, flags);
	list_del_init(&scmd->eh_entry);
	spin_unlock_irqrestore(sdev->host->host_lock, flags);
	spin_unlock_irqrestore(shost->host_lock, flags);

	scsi_eh_scmd_add(scmd);
}