diff options
author | Michael Reed <mdr@sgi.com> | 2005-12-08 03:46:27 (GMT) |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-08 14:13:29 (GMT) |
commit | 85631672e6a8032267058b4ccbe53f1924a5d0be (patch) | |
tree | e1d415d226e3ef0ee44c4282ee96ef006f3a08a9 /drivers/scsi/scsi_error.c | |
parent | f0353301e6752399ceb874ede7f44e3571c5e4f3 (diff) | |
download | linux-85631672e6a8032267058b4ccbe53f1924a5d0be.tar.xz |
[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/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 18c5d25..c0ae9e9 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); } /** |