diff options
author | Javier Martinez Canillas <martinez.javier@gmail.com> | 2011-01-06 07:43:59 +0100 |
---|---|---|
committer | Javier Martinez Canillas <martinez.javier@gmail.com> | 2011-01-08 01:07:34 +0100 |
commit | 26e967f1a1dc04f6e234f617c5ce5e895c431bc2 (patch) | |
tree | 639ab11257f6fc645f5acf6766cb71f51b4e11b1 | |
parent | 383b607f7fff26ec216765b20b1125897a3f360a (diff) | |
download | ldd3-26e967f1a1dc04f6e234f617c5ce5e895c431bc2.tar.gz |
sbull: Use blk_fetch_request instead blk_peek_request to dequeue requests
The block layer request API changes make a requirement for block drivers
to dequeue requests before signal its completition.
Commit 1dfd4ab138fc9f9cad869e6110022c7cfd5544d1 changed sbull to use
the new block layer API. But the patch only renamed the functions while
keeping the old driver semantics. It used blk_peek_request() that does the
same that elv_next_request() did.
Remove the request from the queue before is not only a recomendation
but a true requirement. Attempting to complete a request that remains
in the queue make the kernel oops. So the last commit introduced a Bug.
This patch uses blk_fetch_request() instead of blk_peek_request().
blk_fetch_request() not only returns the request in the head of the
queue but also removes the request from the queue so a latter
signaling of the request completition doesn't hang the system.
-rw-r--r-- | sbull/sbull.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/sbull/sbull.c b/sbull/sbull.c index 8201f7d..0dc474e 100644 --- a/sbull/sbull.c +++ b/sbull/sbull.c @@ -104,11 +104,11 @@ static void sbull_request(struct request_queue *q) { struct request *req; - while ((req = blk_peek_request(q)) != NULL) { + while ((req = blk_fetch_request(q)) != NULL) { struct sbull_dev *dev = req->rq_disk->private_data; if (req->cmd_type != REQ_TYPE_FS) { printk (KERN_NOTICE "Skip non-fs request\n"); - blk_end_request(req, 0, blk_rq_cur_bytes(req)); + __blk_end_request_cur(req, -EIO); continue; } // printk (KERN_NOTICE "Req dev %d dir %ld sec %ld, nr %d f %lx\n", @@ -117,7 +117,7 @@ static void sbull_request(struct request_queue *q) // req->flags); sbull_transfer(dev, blk_rq_pos(req), blk_rq_cur_sectors(req), req->buffer, rq_data_dir(req)); - blk_end_request(req, 1, blk_rq_cur_bytes(req)); + __blk_end_request_cur(req, 0); } } @@ -168,17 +168,14 @@ static void sbull_full_request(struct request_queue *q) int sectors_xferred; struct sbull_dev *dev = q->queuedata; - while ((req = blk_peek_request(q)) != NULL) { + while ((req = blk_fetch_request(q)) != NULL) { if (req->cmd_type != REQ_TYPE_FS) { printk (KERN_NOTICE "Skip non-fs request\n"); - blk_end_request(req, 0, blk_rq_cur_bytes(req)); + __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); continue; } sectors_xferred = sbull_xfer_request(dev, req); - if (! __blk_end_request(req, 1, sectors_xferred)) { - blk_start_request(req); - __blk_end_request(req, 0, blk_rq_cur_bytes(req)); - } + __blk_end_request(req, 0, sectors_xferred); } } |