summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Martinez Canillas <martinez.javier@gmail.com>2011-01-06 07:43:59 +0100
committerJavier Martinez Canillas <martinez.javier@gmail.com>2011-01-06 07:43:59 +0100
commit092ebcedddd4e13243db4caa28106aaa2168239e (patch)
treea352e100418418638e1b615a1bd0032be8c16f2d
parent25ea535145e56d63183c9a2b6f4d0ec7c6f9e7a9 (diff)
downloadldd3-092ebcedddd4e13243db4caa28106aaa2168239e.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.c15
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);
}
}