@@ -930,6 +930,9 @@ static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd)
struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
+ if (!scsi_host_in_recovery(host))
+ return FAILED;
+
SCSI_LOG_ERROR_RECOVERY(3,
shost_printk(KERN_INFO, host, "Snd Host RST\n"));
@@ -960,6 +963,9 @@ static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd)
struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
+ if (!scsi_host_in_recovery(host))
+ return FAILED;
+
SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
"%s: Snd Bus RST\n", __func__));
@@ -1001,6 +1007,10 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
enum scsi_disposition rtn;
struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
+ struct scsi_target *starget = scsi_target(scmd->device);
+
+ if (!(scsi_target_in_recovery(starget) || scsi_host_in_recovery(host)))
+ return FAILED;
if (!hostt->eh_target_reset_handler)
return FAILED;
@@ -1008,7 +1018,7 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
rtn = hostt->eh_target_reset_handler(scmd);
if (rtn == SUCCESS) {
spin_lock_irqsave(host->host_lock, flags);
- __starget_for_each_device(scsi_target(scmd->device), NULL,
+ __starget_for_each_device(starget, NULL,
__scsi_report_device_reset);
spin_unlock_irqrestore(host->host_lock, flags);
}
This is preparation for a genernal LUN/target based error handle strategy, the strategy would reuse some origin error handler APIs, but some steps of these function should not be performed. For example, we should not perform target reset if we just stop IOs on one single LUN. This change add checks in scsi_try_xxx_reset to make sure the reset operations would not be performed only if the condition is not satisfied. Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> --- drivers/scsi/scsi_error.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)