[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 10/10] blktap: Add BLKTAP_OP_FLUSH command option.



Wants to be enabled by userspace with a device flag. Semantics equal a
cache flush, i.e. durability for completed I/O but no particular
ordering constraints of in-flight requests.

Signed-off-by: Daniel Stodden <daniel.stodden@xxxxxxxxxx>
---
 drivers/block/blktap/blktap.h |    1 +
 drivers/block/blktap/device.c |   30 ++++++++++++++++++++++++++----
 drivers/block/blktap/ring.c   |    7 +++++++
 include/linux/blktap.h        |    2 ++
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/block/blktap/blktap.h b/drivers/block/blktap/blktap.h
index e0f7d99..1b63d0e 100644
--- a/drivers/block/blktap/blktap.h
+++ b/drivers/block/blktap/blktap.h
@@ -62,6 +62,7 @@ struct blktap_statistics {
        int                            st_rd_req;
        int                            st_wr_req;
        int                            st_oo_req;
+       int                            st_fl_req;
        int                            st_rd_sect;
        int                            st_wr_sect;
        s64                            st_rd_cnt;
diff --git a/drivers/block/blktap/device.c b/drivers/block/blktap/device.c
index 2379643..74c3daf 100644
--- a/drivers/block/blktap/device.c
+++ b/drivers/block/blktap/device.c
@@ -161,6 +161,15 @@ blktap_device_end_request(struct blktap *tap,
        blktap_end_rq(rq, error);
 }
 
+static void
+blktap_device_prepare_flush(struct request_queue *q, struct request *rq)
+{
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
+       rq->timeout  = q->rq_timeout;
+       rq->cmd[0]   = BLKTAP_OP_FLUSH;
+       rq->cmd_len  = 1;
+}
+
 int
 blktap_device_make_request(struct blktap *tap, struct request *rq)
 {
@@ -180,6 +189,12 @@ blktap_device_make_request(struct blktap *tap, struct 
request *rq)
                goto fail;
        }
 
+       if (blk_pc_request(rq)) {
+               request->operation = rq->cmd[0];
+               request->nr_pages  = 0;
+               goto submit;
+       }
+
        if (!blk_fs_request(rq)) {
                err = -EOPNOTSUPP;
                goto fail;
@@ -200,6 +215,7 @@ blktap_device_make_request(struct blktap *tap, struct 
request *rq)
        if (err)
                goto fail;
 
+submit:
        request->rq = rq;
        blktap_ring_submit_request(tap, request);
 
@@ -303,8 +319,12 @@ blktap_device_configure(struct blktap *tap,
        /* Make sure buffer addresses are sector-aligned. */
        blk_queue_dma_alignment(rq, 511);
 
-       /* We are reordering, but cacheless. */
-       blk_queue_ordered(rq, QUEUE_ORDERED_DRAIN, NULL);
+       /* Enable cache control */
+       if (info->flags & BLKTAP_DEVICE_FLAG_FLUSH)
+               blk_queue_ordered(rq, QUEUE_ORDERED_DRAIN_FLUSH,
+                                 blktap_device_prepare_flush);
+       else
+               blk_queue_ordered(rq, QUEUE_ORDERED_DRAIN, NULL);
 }
 
 static int
@@ -502,11 +522,13 @@ blktap_device_create(struct blktap *tap, struct 
blktap_device_info *info)
        set_bit(BLKTAP_DEVICE, &tap->dev_inuse);
 
        dev_info(disk_to_dev(gd),
-                "sector-size: %u/%u phys-offset: %d capacity: %llu\n",
+                "sector-size: %u/%u phys-offset: %d capacity: %llu"
+                " ordered: %#x\n",
                 queue_logical_block_size(rq),
                 queue_physical_block_size(rq),
                 queue_alignment_offset(rq),
-                (unsigned long long)get_capacity(gd));
+                (unsigned long long)get_capacity(gd),
+                rq->ordered);
 
        return 0;
 
diff --git a/drivers/block/blktap/ring.c b/drivers/block/blktap/ring.c
index 25bd311..9a7696e 100644
--- a/drivers/block/blktap/ring.c
+++ b/drivers/block/blktap/ring.c
@@ -299,6 +299,12 @@ blktap_ring_submit_request(struct blktap *tap,
                tap->stats.st_wr_sect += nsecs;
                tap->stats.st_wr_req++;
                break;
+
+       case BLKTAP_OP_FLUSH:
+               breq->sector_number = 0;
+               tap->stats.st_fl_req++;
+               break;
+
        default:
                BUG();
        }
@@ -447,6 +453,7 @@ blktap_ring_ioctl(struct inode *inode, struct file *filp,
 
                mask  = BLKTAP_DEVICE_FLAG_RO;
                mask |= BLKTAP_DEVICE_FLAG_PSZ;
+               mask |= BLKTAP_DEVICE_FLAG_FLUSH;
 
                memset(&info, 0, sizeof(info));
                sz = base_sz = BLKTAP_INFO_SIZE_AT(flags);
diff --git a/include/linux/blktap.h b/include/linux/blktap.h
index 9a280d9..4739320 100644
--- a/include/linux/blktap.h
+++ b/include/linux/blktap.h
@@ -18,6 +18,7 @@
 
 #define BLKTAP_DEVICE_FLAG_RO       0x00000001UL /* disk is R/O */
 #define BLKTAP_DEVICE_FLAG_PSZ      0x00000002UL /* physical sector size */
+#define BLKTAP_DEVICE_FLAG_FLUSH    0x00000004UL /* supports FLUSH */
 
 struct blktap_info {
        unsigned int            ring_major;
@@ -54,6 +55,7 @@ struct blktap_segment {
 
 #define BLKTAP_OP_READ          0
 #define BLKTAP_OP_WRITE         1
+#define BLKTAP_OP_FLUSH         2
 
 #define BLKTAP_SEGMENT_MAX      11
 
-- 
1.7.0.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.