summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Reed <mdr@sgi.com>2005-12-08 04:46:27 +0100
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-08 15:13:29 +0100
commit85631672e6a8032267058b4ccbe53f1924a5d0be (patch)
treee1d415d226e3ef0ee44c4282ee96ef006f3a08a9 /drivers
parent[SCSI] Fix incorrect pointer in megaraid.c MODE_SENSE emulation (diff)
downloadlinux-85631672e6a8032267058b4ccbe53f1924a5d0be.tar.xz
linux-85631672e6a8032267058b4ccbe53f1924a5d0be.zip
[SCSI] fix OOPS due to clearing eh_action prior to aborting eh command
The eh_action semaphore in scsi_eh_send_command is cleared after a command timeout. The command is subsequently aborted and the abort will try to call scsi_done() on it. Unfortunately, the scsi_eh_done() routine unconditinally completes the semaphore (which is now null). Fix this race by makiong the scsi_eh_done() routine check that the semaphore is non null before completing it (mirroring the ordinary command done/timeout logic). Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_error.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 18c5d2523014..c0ae9e965f6f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -422,10 +422,15 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
**/
static void scsi_eh_done(struct scsi_cmnd *scmd)
{
+ struct completion *eh_action;
+
SCSI_LOG_ERROR_RECOVERY(3,
printk("%s scmd: %p result: %x\n",
__FUNCTION__, scmd, scmd->result));
- complete(scmd->device->host->eh_action);
+
+ eh_action = scmd->device->host->eh_action;
+ if (eh_action)
+ complete(eh_action);
}
/**