Commit 46f2cb79 authored by Dave Jones's avatar Dave Jones Committed by Linus Torvalds

[PATCH] make nbd working in 2.5.x

From Petr Vandrovec

   we use nbd for our diskless systems, and it looks to me like that
it has some serious problems in 2.5.x... Can you apply this patch
and forward it to Linus?

There were:
* Missing disk's queue initialization
* Driver should use list_del_init: put_request now verifies
  that req->queuelist is empty, and list_del was incompatible
  with this.
* I converted nbd_end_request back to end_that_request_{first,last}
  as I saw no reason why driver should do it itself... and
  blk_put_request has no place under queue_lock, so apparently when
  semantic changed nobody went through drivers...
parent 5141a806
......@@ -76,22 +76,15 @@ static void nbd_end_request(struct request *req)
{
int uptodate = (req->errors == 0) ? 1 : 0;
request_queue_t *q = req->q;
struct bio *bio;
unsigned nsect;
unsigned long flags;
#ifdef PARANOIA
requests_out++;
#endif
spin_lock_irqsave(q->queue_lock, flags);
while((bio = req->bio) != NULL) {
nsect = bio_sectors(bio);
blk_finished_io(nsect);
req->bio = bio->bi_next;
bio->bi_next = NULL;
bio_endio(bio, nsect << 9, uptodate ? 0 : -EIO);
if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
end_that_request_last(req);
}
blk_put_request(req);
spin_unlock_irqrestore(q->queue_lock, flags);
}
......@@ -243,7 +236,7 @@ static struct request *nbd_find_request(struct nbd_device *lo, char *handle)
req = list_entry(tmp, struct request, queuelist);
if (req != xreq)
continue;
list_del(&req->queuelist);
list_del_init(&req->queuelist);
spin_unlock(&lo->queue_lock);
return req;
}
......@@ -322,7 +315,7 @@ void nbd_clear_que(struct nbd_device *lo)
spin_lock(&lo->queue_lock);
if (!list_empty(&lo->queue_head)) {
req = list_entry(lo->queue_head.next, struct request, queuelist);
list_del(&req->queuelist);
list_del_init(&req->queuelist);
}
spin_unlock(&lo->queue_lock);
if (req) {
......@@ -387,7 +380,7 @@ static void do_nbd_request(request_queue_t * q)
if (req->errors) {
printk(KERN_ERR "nbd: nbd_send_req failed\n");
spin_lock(&lo->queue_lock);
list_del(&req->queuelist);
list_del_init(&req->queuelist);
spin_unlock(&lo->queue_lock);
nbd_end_request(req);
spin_lock_irq(q->queue_lock);
......@@ -590,6 +583,7 @@ static int __init nbd_init(void)
disk->first_minor = i;
disk->fops = &nbd_fops;
disk->private_data = &nbd_dev[i];
disk->queue = &nbd_queue;
sprintf(disk->disk_name, "nbd%d", i);
set_capacity(disk, 0x3ffffe);
add_disk(disk);
......
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