diff options
author | Hua Zhong <hzhong@gmail.com> | 2006-10-03 04:14:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 11:04:07 -0400 |
commit | ce42f19137225d01be9388a73703df40fb7af80f (patch) | |
tree | 16d9b0bc3a5bd30c69b03836d44c1db4338628c4 /drivers/ide/ide-io.c | |
parent | dc844e05913b84d09e86d88c0f861ef0afbee2fd (diff) |
[PATCH] IDE error handling fixes
In 2.6.15.1 I encountered some IDE crashes when unplugging IDE cables to
emulate disk errors. Below is a patch against 2.6.16 which I think still
applies.
1. The first BUG_ON could trigger when a PREFLUSH IO fails (it would
fail the original barrier request which hasn't been marked REQ_STARTED
yet).
2. the rq could have been dequeued already (same as 1).
3. HWGROUP(drive)->rq could be NULL because of the ide_error() several
lines earlier.
Signed-off-by: Hua Zhong <hzhong@gmail.com>
Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 38479a29d3e..8d26619ba16 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -59,8 +59,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
59 | { | 59 | { |
60 | int ret = 1; | 60 | int ret = 1; |
61 | 61 | ||
62 | BUG_ON(!blk_rq_started(rq)); | ||
63 | |||
64 | /* | 62 | /* |
65 | * if failfast is set on a request, override number of sectors and | 63 | * if failfast is set on a request, override number of sectors and |
66 | * complete the whole request right now | 64 | * complete the whole request right now |
@@ -82,7 +80,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
82 | 80 | ||
83 | if (!end_that_request_first(rq, uptodate, nr_sectors)) { | 81 | if (!end_that_request_first(rq, uptodate, nr_sectors)) { |
84 | add_disk_randomness(rq->rq_disk); | 82 | add_disk_randomness(rq->rq_disk); |
85 | blkdev_dequeue_request(rq); | 83 | if (!list_empty(&rq->queuelist)) |
84 | blkdev_dequeue_request(rq); | ||
86 | HWGROUP(drive)->rq = NULL; | 85 | HWGROUP(drive)->rq = NULL; |
87 | end_that_request_last(rq, uptodate); | 86 | end_that_request_last(rq, uptodate); |
88 | ret = 0; | 87 | ret = 0; |
@@ -1346,6 +1345,10 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
1346 | * make sure request is sane | 1345 | * make sure request is sane |
1347 | */ | 1346 | */ |
1348 | rq = HWGROUP(drive)->rq; | 1347 | rq = HWGROUP(drive)->rq; |
1348 | |||
1349 | if (!rq) | ||
1350 | goto out; | ||
1351 | |||
1349 | HWGROUP(drive)->rq = NULL; | 1352 | HWGROUP(drive)->rq = NULL; |
1350 | 1353 | ||
1351 | rq->errors = 0; | 1354 | rq->errors = 0; |