Commit 2cba47a2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix BLKPREP_KILL

From: Jens Axboe <axboe@suse.de>

Samuel Rydh wrote:

If a MODE_SENSE(6) command is sent to an IDE cd using the CDROM_SEND_PACKET
ioctl, then the kernel freezes solidly. To reproduce this, one can take the
SCSI cmd [1a 08 31 00 10 00] and a 16 byte data buffer.

After some bug hunting, I found out that the following is what happens:

- ide-cd recognizes that MODE_SENSE(6) isn't supported and tries
  to abort the request from ide_cdrom_prep_pc by returning BLKPREP_KILL.

- in elv_next_request(), the kill request is handled by
  the following code:

	while (end_that_request_first(rq, 0, rq->nr_sectors))
		;
	end_that_request_last(rq);

The while loop never exits. The end_that_request_first() doesn't do anything
since rq->nr_sectors is 0; it just returns "not-done" after handling those 0
bytes (rq->bio->bi_size is 16).
parent f0fdf5f8
...@@ -210,10 +210,14 @@ struct request *elv_next_request(request_queue_t *q) ...@@ -210,10 +210,14 @@ struct request *elv_next_request(request_queue_t *q)
rq = NULL; rq = NULL;
break; break;
} else if (ret == BLKPREP_KILL) { } else if (ret == BLKPREP_KILL) {
int nr_bytes = rq->hard_nr_sectors << 9;
if (!nr_bytes)
nr_bytes = rq->data_len;
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
rq->flags |= REQ_QUIET; rq->flags |= REQ_QUIET;
while (end_that_request_first(rq, 0, rq->nr_sectors)) end_that_request_chunk(rq, 0, nr_bytes);
;
end_that_request_last(rq); end_that_request_last(rq);
} else { } else {
printk("%s: bad return=%d\n", __FUNCTION__, ret); printk("%s: bad return=%d\n", __FUNCTION__, ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment