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-08 01:07:34 +0100
commit26e967f1a1dc04f6e234f617c5ce5e895c431bc2 (patch)
tree639ab11257f6fc645f5acf6766cb71f51b4e11b1
parent383b607f7fff26ec216765b20b1125897a3f360a (diff)
downloadldd3-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.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);
}
}