X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fblock%2Fnbd.c;h=2f5cc3e251c605f34d72d95824caece8294c8037;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=3554188ebe4f0f64fe558e80708647ae878ed3e5;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 3554188eb..2f5cc3e25 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -92,7 +92,7 @@ static struct nbd_device nbd_dev[MAX_NBD]; * a single lock. * Thanks go to Jens Axboe and Al Viro for their LKML emails explaining this! */ -static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(nbd_lock); #ifndef NDEBUG static const char *ioctl_cmd_to_ascii(int cmd) @@ -128,23 +128,11 @@ static void nbd_end_request(struct request *req) { int uptodate = (req->errors == 0) ? 1 : 0; request_queue_t *q = req->q; - struct nbd_device *lo = req->rq_disk->private_data; unsigned long flags; dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, req, uptodate? "done": "failed"); - spin_lock(&lo->queue_lock); - while (req->ref_count > 1) { /* still in send */ - spin_unlock(&lo->queue_lock); - printk(KERN_DEBUG "%s: request %p still in use (%d), waiting\n", - lo->disk->disk_name, req, req->ref_count); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); /* wait a second */ - spin_lock(&lo->queue_lock); - } - spin_unlock(&lo->queue_lock); - spin_lock_irqsave(q->queue_lock, flags); if (!end_that_request_first(req, uptodate, req->nr_sectors)) { end_that_request_last(req); @@ -158,15 +146,12 @@ static void nbd_end_request(struct request *req) static int sock_xmit(struct socket *sock, int send, void *buf, int size, int msg_flags) { - mm_segment_t oldfs; int result; struct msghdr msg; - struct iovec iov; + struct kvec iov; unsigned long flags; sigset_t oldset; - oldfs = get_fs(); - set_fs(get_ds()); /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */ spin_lock_irqsave(¤t->sighand->siglock, flags); @@ -182,17 +167,15 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, iov.iov_len = size; msg.msg_name = NULL; msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) - result = sock_sendmsg(sock, &msg, size); + result = kernel_sendmsg(sock, &msg, &iov, 1, size); else - result = sock_recvmsg(sock, &msg, size, 0); + result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0); if (signal_pending(current)) { siginfo_t info; @@ -219,7 +202,6 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, recalc_sigpending(); spin_unlock_irqrestore(¤t->sighand->siglock, flags); - set_fs(oldfs); return result; } @@ -234,7 +216,7 @@ static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec, return result; } -void nbd_send_req(struct nbd_device *lo, struct request *req) +static int nbd_send_req(struct nbd_device *lo, struct request *req) { int result, i, flags; struct nbd_request request; @@ -294,11 +276,11 @@ void nbd_send_req(struct nbd_device *lo, struct request *req) } } up(&lo->tx_lock); - return; + return 0; error_out: up(&lo->tx_lock); - req->errors++; + return 1; } static struct request *nbd_find_request(struct nbd_device *lo, char *handle) @@ -483,26 +465,19 @@ static void do_nbd_request(request_queue_t * q) } list_add(&req->queuelist, &lo->queue_head); - req->ref_count++; /* make sure req does not get freed */ spin_unlock(&lo->queue_lock); - nbd_send_req(lo, req); - - if (req->errors) { + if (nbd_send_req(lo, req) != 0) { printk(KERN_ERR "%s: Request send failed\n", lo->disk->disk_name); - spin_lock(&lo->queue_lock); - list_del_init(&req->queuelist); - req->ref_count--; - spin_unlock(&lo->queue_lock); - nbd_end_request(req); - spin_lock_irq(q->queue_lock); - continue; + if (nbd_find_request(lo, (char *)&req) != NULL) { + /* we still own req */ + req->errors++; + nbd_end_request(req); + } else /* we're racing with nbd_clear_que */ + printk(KERN_DEBUG "nbd: can't find req\n"); } - spin_lock(&lo->queue_lock); - req->ref_count--; - spin_unlock(&lo->queue_lock); spin_lock_irq(q->queue_lock); continue; @@ -751,6 +726,6 @@ MODULE_DESCRIPTION("Network Block Device"); MODULE_LICENSE("GPL"); #ifndef NDEBUG -MODULE_PARM(debugflags, "i"); +module_param(debugflags, int, 0644); MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); #endif