Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

181 lines (163 sloc) 5.13 kb
--- linux-2.6.32/drivers/block/nbd.c 2012-09-16 12:52:38.123641274 +0200
+++ linux-2.6.32-humbuq/drivers/block/nbd.c 2012-09-16 05:05:16.318784654 +0200
@@ -194,10 +194,12 @@
if (signal_pending(current)) {
siginfo_t info;
+ int gotsig = dequeue_signal_lock(current, &current->blocked, &info);
printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n",
task_pid_nr(current), current->comm,
- dequeue_signal_lock(current, &current->blocked, &info));
+ gotsig);
result = -EINTR;
+ if (gotsig) lo->flags &= ~NBD_FLAG_RESUME;
sock_shutdown(lo, !send);
break;
}
@@ -445,7 +447,7 @@
}
-static void nbd_handle_req(struct nbd_device *lo, struct request *req)
+static int nbd_handle_req(struct nbd_device *lo, struct request *req)
{
if (req->cmd_type != REQ_TYPE_FS)
goto error_out;
@@ -453,7 +455,7 @@
nbd_cmd(req) = NBD_CMD_READ;
if (rq_data_dir(req) == WRITE) {
nbd_cmd(req) = NBD_CMD_WRITE;
- if (lo->flags & NBD_READ_ONLY) {
+ if (lo->flags & NBD_FLAG_READ_ONLY) {
printk(KERN_ERR "%s: Write on read-only\n",
lo->disk->disk_name);
goto error_out;
@@ -463,7 +465,7 @@
req->errors = 0;
mutex_lock(&lo->tx_lock);
- if (unlikely(!lo->sock)) {
+ if (unlikely((!lo->sock) && ((lo->flags & NBD_FLAG_RESUME) == 0))) {
mutex_unlock(&lo->tx_lock);
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
@@ -475,8 +477,16 @@
if (nbd_send_req(lo, req) != 0) {
printk(KERN_ERR "%s: Request send failed\n",
lo->disk->disk_name);
- req->errors++;
- nbd_end_request(req);
+ if (lo->flags & NBD_FLAG_RESUME) {
+ spin_lock_irq(&lo->queue_lock);
+ list_add(&req->queuelist, &lo->waiting_queue);
+ spin_unlock_irq(&lo->queue_lock);
+ mutex_unlock(&lo->tx_lock);
+ return 1;
+ } else {
+ req->errors++;
+ nbd_end_request(req);
+ }
} else {
spin_lock(&lo->queue_lock);
list_add(&req->queuelist, &lo->queue_head);
@@ -487,11 +497,11 @@
mutex_unlock(&lo->tx_lock);
wake_up_all(&lo->active_wq);
- return;
-
+ return 0;
error_out:
req->errors++;
nbd_end_request(req);
+ return 1;
}
static int nbd_thread(void *data)
@@ -517,7 +527,8 @@
spin_unlock_irq(&lo->queue_lock);
/* handle request */
- nbd_handle_req(lo, req);
+ if (nbd_handle_req(lo, req))
+ return 0;
}
return 0;
}
@@ -545,7 +556,7 @@
BUG_ON(lo->magic != LO_MAGIC);
- if (unlikely(!lo->sock)) {
+ if (unlikely((!lo->sock) && ((lo->flags & NBD_FLAG_RESUME) == 0))) {
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
req->errors++;
@@ -558,7 +569,8 @@
list_add_tail(&req->queuelist, &lo->waiting_queue);
spin_unlock_irq(&lo->queue_lock);
- wake_up(&lo->waiting_wq);
+ if (lo->sock)
+ wake_up(&lo->waiting_wq);
spin_lock_irq(q->queue_lock);
}
@@ -638,6 +650,10 @@
lo->xmit_timeout = arg * HZ;
return 0;
+ case NBD_SET_FLAGS:
+ lo->flags = arg;
+ return 0;
+
case NBD_SET_SIZE_BLOCKS:
lo->bytesize = ((u64) arg) * lo->blksize;
bdev->bd_inode->i_size = lo->bytesize;
@@ -672,15 +688,28 @@
sock_shutdown(lo, 0);
file = lo->file;
lo->file = NULL;
- nbd_clear_que(lo);
- printk(KERN_WARNING "%s: queue cleared\n", lo->disk->disk_name);
+ if ((lo->flags & NBD_FLAG_RESUME) == 0) {
+ nbd_clear_que(lo);
+ printk(KERN_WARNING "%s: queue cleared and device reset.\n", lo->disk->disk_name);
+ lo->bytesize = 0;
+ bdev->bd_inode->i_size = 0;
+ set_capacity(lo->disk, 0);
+ if (max_part > 0)
+ ioctl_by_bdev(bdev, BLKRRPART, 0);
+ } else {
+ struct request *req, *tmp;
+ int moved = 0;
+ spin_lock(&lo->queue_lock);
+ list_for_each_entry_safe(req, tmp, &lo->queue_head, queuelist) {
+ list_del_init(&req->queuelist);
+ list_add(&req->queuelist, &lo->waiting_queue);
+ moved++;
+ }
+ spin_unlock(&lo->queue_lock);
+ printk(KERN_WARNING "%s: retrying %d requests\n", lo->disk->disk_name, moved);
+ }
if (file)
fput(file);
- lo->bytesize = 0;
- bdev->bd_inode->i_size = 0;
- set_capacity(lo->disk, 0);
- if (max_part > 0)
- ioctl_by_bdev(bdev, BLKRRPART, 0);
return lo->harderror;
}
--- linux-2.6.32/include/linux/nbd.h 2009-12-03 04:51:21.000000000 +0100
+++ linux-2.6.32-humbuq/include/linux/nbd.h 2012-09-16 12:53:03.576536821 +0200
@@ -27,6 +27,7 @@
#define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 )
#define NBD_DISCONNECT _IO( 0xab, 8 )
#define NBD_SET_TIMEOUT _IO( 0xab, 9 )
+#define NBD_SET_FLAGS _IO( 0xab, 10 )
enum {
NBD_CMD_READ = 0,
@@ -43,8 +44,15 @@
#include <linux/mutex.h>
/* values for flags field */
-#define NBD_READ_ONLY 0x0001
-#define NBD_WRITE_NOCHK 0x0002
+#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */
+#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */
+#define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */
+#define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Access) */
+#define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm - rotational media */
+#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
+#define NBD_FLAG_RESUME (1 << 6) /* Resume connection */
+
+
struct request;
Jump to Line
Something went wrong with that request. Please try again.