Commit 67e9b61e authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] update nbd driver to large sizes etc

parent 059fd0e0
......@@ -26,6 +26,8 @@
* reduce number of partial TCP segments sent. <steve@chygwyn.com>
* 01-12-6 Fix deadlock condition by making queue locks independant of
* the transmit lock. <steve@chygwyn.com>
* 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes.
* <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com>
*
* possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
* why not: would need verify_area and friends, would share yet another
......@@ -89,10 +91,12 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
oldfs = get_fs();
set_fs(get_ds());
/* Allow interception of SIGKILL only
* Don't allow other signals to interrupt the transmission */
spin_lock_irqsave(&current->sig->siglock, flags);
oldset = current->blocked;
sigfillset(&current->blocked);
sigdelsetmask(&current->blocked, sigmask(SIGKILL));
recalc_sigpending();
spin_unlock_irqrestore(&current->sig->siglock, flags);
......@@ -115,6 +119,17 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
else
result = sock_recvmsg(sock, &msg, size, 0);
if (signal_pending(current)) {
siginfo_t info;
spin_lock_irqsave(&current->sig->siglock, flags);
printk(KERN_WARNING "NBD (pid %d: %s) got signal %d\n",
current->pid, current->comm,
dequeue_signal(&current->blocked, &info));
spin_unlock_irqrestore(&current->sig->siglock, flags);
result = -EINTR;
break;
}
if (result <= 0) {
#ifdef PARANOIA
printk(KERN_ERR "NBD: %s - sock=%ld at buf=%ld, size=%d returned %d.\n",
......@@ -154,6 +169,10 @@ void nbd_send_req(struct nbd_device *lo, struct request *req)
down(&lo->tx_lock);
if (!sock || !lo->sock) {
FAIL("Attempted sendmsg to closed socket\n");
}
result = nbd_xmit(1, sock, (char *) &request, sizeof(request), nbd_cmd(req) == NBD_CMD_WRITE ? MSG_MORE : 0);
if (result <= 0)
FAIL("Sendmsg failed for control.");
......@@ -324,11 +343,31 @@ static void do_nbd_request(request_queue_t * q)
spin_unlock_irq(q->queue_lock);
spin_lock(&lo->queue_lock);
if (!lo->file) {
spin_unlock(&lo->queue_lock);
printk(KERN_ERR "nbd: failed between accept and semaphore, file lost\n");
req->errors++;
nbd_end_request(req);
spin_lock_irq(q->queue_lock);
continue;
}
list_add(&req->queuelist, &lo->queue_head);
spin_unlock(&lo->queue_lock);
nbd_send_req(lo, req);
if (req->errors) {
printk(KERN_ERR "nbd: nbd_send_req failed\n");
spin_lock(&lo->queue_lock);
list_del(&req->queuelist);
spin_unlock(&lo->queue_lock);
nbd_end_request(req);
spin_lock_irq(q->queue_lock);
continue;
}
spin_lock_irq(q->queue_lock);
continue;
......@@ -371,12 +410,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.\n");
return -EBUSY;
}
spin_unlock(&lo->queue_lock);
file = lo->file;
if (!file)
if (!file) {
spin_unlock(&lo->queue_lock);
return -EINVAL;
}
lo->file = NULL;
lo->sock = NULL;
spin_unlock(&lo->queue_lock);
fput(file);
return 0;
case NBD_SET_SOCK:
......@@ -420,6 +461,26 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
if (!lo->file)
return -EINVAL;
nbd_do_it(lo);
/* on return tidy up in case we have a signal */
/* Forcibly shutdown the socket causing all listeners
* to error
*
* FIXME: This code is duplicated from sys_shutdown, but
* there should be a more generic interface rather than
* calling socket ops directly here */
down(&lo->tx_lock);
printk(KERN_WARNING "nbd: shutting down socket\n");
lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN);
lo->sock = NULL;
up(&lo->tx_lock);
spin_lock(&lo->queue_lock);
file = lo->file;
lo->file = NULL;
spin_unlock(&lo->queue_lock);
nbd_clear_que(lo);
printk(KERN_WARNING "nbd: queue cleared\n");
if (file)
fput(file);
return lo->harderror;
case NBD_CLEAR_QUE:
nbd_clear_que(lo);
......@@ -498,7 +559,7 @@ static int __init nbd_init(void)
init_MUTEX(&nbd_dev[i].tx_lock);
nbd_dev[i].blksize = 1024;
nbd_dev[i].blksize_bits = 10;
nbd_dev[i].bytesize = 0x7ffffc00; /* 2GB */
nbd_dev[i].bytesize = ((u64)0x7ffffc00) << 10; /* 2TB */
disk->major = MAJOR_NR;
disk->first_minor = i;
disk->fops = &nbd_fops;
......
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