summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
authorjiang.biao2@zte.com.cn <jiang.biao2@zte.com.cn>2015-07-31 17:52:10 +0800
committerJames Bottomley <JBottomley@Odin.com>2015-08-26 17:29:49 -0700
commit709c75b5a2411c31e5a649a2cd6d4866dd11f456 (patch)
tree07b9fabb51025264dbb8e050c3073b2fbea49030 /drivers/scsi/scsi_error.c
parent1cd129918f14f42f8b1940096dba629ce7e7a243 (diff)
scsi_error: should not get sense for timeout IO in scsi error handler
scsi_error: should not get sense for timeout IO in scsi error handler When an IO timeout occurs, the IO will be aborted in scsi_abort_command() and SCSI_EH_ABORT_SCHEDULED will be set. Because of that, the SCSI_EH_CANCEL_CMD will be clear in scsi_eh_scmd_add(). So when scsi error handler starts, it will get sense for this timeout IO and the scmd of the IO request will be reused. In that case, the scmd may be double released when racing with io_done(), which will result in crash. SO SCSI_EH_ABORT_SCHEDULED should also be checked when getting sense. The bug maybe reproduced when the link between host and disk is unstable. Signed-off-by: Jiang Biao <jiang.biao2@zte.com.cn> Signed-off-by: Long Chun <long.chun@zte.com.cn> Reviewed-by: Tan Hu <tan.hu@zte.com.cn> Reviewed-by: Chen Donghai <chen.donghai@zte.com.cn> Reviewed-by: Cai Qu <cai.qu@zte.com.cn> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index d7d28061b31d..3aacd96d63f3 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1160,8 +1160,13 @@ int scsi_eh_get_sense(struct list_head *work_q,
struct Scsi_Host *shost;
int rtn;
+ /*
+ * If SCSI_EH_ABORT_SCHEDULED has been set, it is timeout IO,
+ * should not get sense.
+ */
list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
if ((scmd->eh_eflags & SCSI_EH_CANCEL_CMD) ||
+ (scmd->eh_eflags & SCSI_EH_ABORT_SCHEDULED) ||
SCSI_SENSE_VALID(scmd))
continue;