diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-05-30 00:43:49 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-30 00:43:49 -0400 |
commit | c143dc903d7c0b15f5052e00b2c7de33a8b4299c (patch) | |
tree | 6c7d82a398d92e48ee01563a0fc6f9a13ec442e4 /block | |
parent | 5d85d3247cc3555215d7d11c78576a396c98e4d9 (diff) |
block: fix an oops on BLKPREP_KILL
Doing a bit of torture testing, I ran across a BUG in the block
subsystem (at blk-core.c:2048): the test for if the request is queued.
It turns out the trigger was a BLKPREP_KILL coming out of the SCSI prep
function. Currently for BLKPREP_KILL requests, we send them straight
into __blk_end_request_all() with an error, but they've never been
dequeued, so they trip the bug. Fix this by starting requests before
killing them.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 8b3b74e69184..7ae83a1e2acf 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1789,6 +1789,11 @@ struct request *blk_peek_request(struct request_queue *q) | |||
1789 | break; | 1789 | break; |
1790 | } else if (ret == BLKPREP_KILL) { | 1790 | } else if (ret == BLKPREP_KILL) { |
1791 | rq->cmd_flags |= REQ_QUIET; | 1791 | rq->cmd_flags |= REQ_QUIET; |
1792 | /* | ||
1793 | * Mark this request as started so we don't trigger | ||
1794 | * any debug logic in the end I/O path. | ||
1795 | */ | ||
1796 | blk_start_request(rq); | ||
1792 | __blk_end_request_all(rq, -EIO); | 1797 | __blk_end_request_all(rq, -EIO); |
1793 | } else { | 1798 | } else { |
1794 | printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); | 1799 | printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); |