summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index d042915ce895..946039117bf4 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -117,6 +117,12 @@ static int scsi_host_eh_past_deadline(struct Scsi_Host *shost)
/**
* scmd_eh_abort_handler - Handle command aborts
* @work: command to be aborted.
+ *
+ * Note: this function must be called only for a command that has timed out.
+ * Because the block layer marks a request as complete before it calls
+ * scsi_times_out(), a .scsi_done() call from the LLD for a command that has
+ * timed out do not have any effect. Hence it is safe to call
+ * scsi_finish_command() from this function.
*/
void
scmd_eh_abort_handler(struct work_struct *work)
@@ -223,7 +229,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd)
static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
- struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
+ struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
+ struct Scsi_Host *shost = scmd->device->host;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
@@ -259,7 +266,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd)
* Ensure that all tasks observe the host state change before the
* host_failed change.
*/
- call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
+ call_rcu(&scmd->rcu, scsi_eh_inc_host_failed);
}
/**
@@ -1888,7 +1895,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
}
return FAILED;
- maybe_retry:
+maybe_retry:
/* we requeue for retry because the error was retryable, and
* the request was not marked fast fail. Note that above,