[Nbd] [CFT][PATCH 2/4] nbd: support FLUSH/FUA
- To: nbd-general@...72...
- Cc: Paul Clements <Paul.Clements@...124...>
- Subject: [Nbd] [CFT][PATCH 2/4] nbd: support FLUSH/FUA
- From: Paolo Bonzini <pbonzini@...696...>
- Date: Tue, 13 Sep 2011 13:09:51 +0200
- Message-id: <1315912193-25959-3-git-send-email-pbonzini@...696...>
- In-reply-to: <1315912193-25959-1-git-send-email-pbonzini@...696...>
- References: <1315912193-25959-1-git-send-email-pbonzini@...696...>
From: Alex Bligh <alex@...872...>
Cc: Paul Clements <Paul.Clements@...124...>
Cc: <nbd-general@...72...>
Signed-off-by: Alex Bligh <alex@...872...>
Signed-off-by: Paolo Bonzini <pbonzini@...696...>
---
After splitting the ROTATIONAL part into a separate patch, this
is all that is left in http://git.alex.org.uk/nbd-module.git.
drivers/block/nbd.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
include/linux/nbd.h | 8 +++++++-
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 616c982..bece3cc 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -100,9 +100,10 @@ static const char *ioctl_cmd_to_ascii(int cmd)
static const char *nbdcmd_to_ascii(int cmd)
{
switch (cmd) {
- case NBD_CMD_READ: return "read";
+ case NBD_CMD_READ: return "read";
case NBD_CMD_WRITE: return "write";
- case NBD_CMD_DISC: return "disconnect";
+ case NBD_CMD_DISC: return "disconnect";
+ case NBD_CMD_FLUSH: return "flush";
}
return "invalid";
}
@@ -242,9 +243,18 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
unsigned long size = blk_rq_bytes(req);
request.magic = htonl(NBD_REQUEST_MAGIC);
- request.type = htonl(nbd_cmd(req));
- request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
- request.len = htonl(size);
+ /* If FUA is set in the request, and we are told to send FUA, then OR in NBD_CMD_FLAG_FUA */
+ request.type = htonl(nbd_cmd(req) |
+ (( (req->cmd_flags & REQ_FUA) && (lo->flags & NBD_FLAG_SEND_FUA)) ?
+ NBD_CMD_FLAG_FUA : 0));
+ /* Send from & len as zero on FLUSH - other values reserved per protocol */
+ if (nbd_cmd(req) == NBD_CMD_FLUSH) {
+ request.from = 0;
+ request.len = 0;
+ } else {
+ request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
+ request.len = htonl(size);
+ }
memcpy(request.handle, &req, sizeof(req));
dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%uB)\n",
@@ -468,6 +478,27 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req)
}
}
+ if (req->cmd_flags & REQ_FLUSH) {
+ if (unlikely(blk_rq_sectors(req))) {
+ /* Elevator is meant to guarantee that a request with REQ_FLUSH
+ * set is broken into an empty request with REQ_FLUSH set then
+ * the rest of the content (if any). If this doesn't happen,
+ * whinge, then proceed to do the content without a flush.
+ */
+ printk(KERN_ERR "%s: nbd passed non-empty flush request\n",
+ lo->disk->disk_name);
+
+ } else {
+ if (lo->flags & NBD_FLAG_SEND_FLUSH)
+ nbd_cmd(req) = NBD_CMD_FLUSH;
+ else {
+ /* Ignore flush that we don't need */
+ nbd_end_request(req);
+ return;
+ }
+ }
+ }
+
req->errors = 0;
mutex_lock(&lo->tx_lock);
@@ -784,6 +815,11 @@ static int __init nbd_init(void)
put_disk(disk);
goto out;
}
+ /* In order not to confuse the elevator, say we always
+ * want FLUSH and FUA. We won't send them to the server
+ * unless the relevant flag bit is set
+ */
+ blk_queue_flush(disk->queue, REQ_FLUSH | REQ_FUA);
/*
* Tell the block layer that we are not a rotational device
*/
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index 3e5a05e..d8cd251 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -32,12 +32,18 @@
enum {
NBD_CMD_READ = 0,
NBD_CMD_WRITE = 1,
- NBD_CMD_DISC = 2
+ NBD_CMD_DISC = 2,
+ NBD_CMD_FLUSH = 3
};
+#define NBD_CMD_MASK_COMMAND 0x0000ffff
+#define NBD_CMD_FLAG_FUA (1<<16)
+
/* values for flags field */
#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_cmd(req) ((req)->cmd[0])
--
1.7.6
Reply to: