Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 598

kvm-83-164.el5_5.9.src.rpm

From 739907c241daa3bdbf38e1e912e71537e5dc6d3b Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <chellwig@redhat.com>
Date: Tue, 24 Nov 2009 19:43:07 -0200
Subject: [PATCH 04/11] virtio-blk: add volatile writecache feature

RH-Author: Christoph Hellwig <chellwig@redhat.com>
Message-id: <1256889879.9905.6.camel@brick.lst.de>
Patchwork-id: 3653
O-Subject: [PATCH 5/5] virtio-blk: add volatile writecache feature
Bugzilla: 537646
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>

commit aa659be3dc2aa86614bcf6960f9d4af2a4362156
Author: Christoph Hellwig <hch@lst.de>
Date:   Fri Sep 4 19:02:23 2009 +0200

    virtio-blk: add volatile writecache feature

    Add a new VIRTIO_BLK_F_WCACHE feature to virtio-blk to indicate that we have
    a volatile write cache that needs controlled flushing.  Implement a
    VIRTIO_BLK_T_FLUSH operation to flush it.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/hw/virtio-blk.c |   29 +++++++++++++++++++++++++++--
 qemu/hw/virtio-blk.h |    4 ++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/qemu/hw/virtio-blk.c b/qemu/hw/virtio-blk.c
index 3addd73..fa20972 100644
--- a/qemu/hw/virtio-blk.c
+++ b/qemu/hw/virtio-blk.c
@@ -107,6 +107,13 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
 }
 
+static void virtio_blk_flush_complete(void *opaque, int ret)
+{
+    VirtIOBlockReq *req = opaque;
+
+    virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK);
+}
+
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
 {
     VirtIOBlockReq *req = qemu_mallocz(sizeof(*req));
@@ -129,6 +136,16 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
     return req;
 }
 
+static void virtio_blk_handle_flush(VirtIOBlockReq *req)
+{
+    BlockDriverAIOCB *acb;
+
+    acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
+    if (!acb) {
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+    }
+}
+
 static int virtio_blk_handle_write(VirtIOBlockReq *req)
 {
     if (!req->buffer) {
@@ -186,7 +203,9 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
         req->out = (void *)req->elem.out_sg[0].iov_base;
         req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
 
-        if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
+        if (req->out->type & VIRTIO_BLK_T_FLUSH) {
+            virtio_blk_handle_flush(req);
+        } else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
             unsigned int len = sizeof(*req->in);
 
             req->in->status = VIRTIO_BLK_S_UNSUPP;
@@ -277,7 +296,13 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
-    return (1 << VIRTIO_BLK_F_SEG_MAX | 1 << VIRTIO_BLK_F_GEOMETRY);
+    VirtIOBlock *s = to_virtio_blk(vdev);
+    uint32_t features;
+
+    features = (1 << VIRTIO_BLK_F_SEG_MAX | 1 << VIRTIO_BLK_F_GEOMETRY);
+    if (bdrv_enable_write_cache(s->bs))
+       features |= (1 << VIRTIO_BLK_F_WCACHE);
+    return features;
 }
 
 static void virtio_blk_save(QEMUFile *f, void *opaque)
diff --git a/qemu/hw/virtio-blk.h b/qemu/hw/virtio-blk.h
index 8c91e1e..315e842 100644
--- a/qemu/hw/virtio-blk.h
+++ b/qemu/hw/virtio-blk.h
@@ -28,6 +28,7 @@
 #define VIRTIO_BLK_F_SIZE_MAX   1       /* Indicates maximum segment size */
 #define VIRTIO_BLK_F_SEG_MAX    2       /* Indicates maximum # of segments */
 #define VIRTIO_BLK_F_GEOMETRY   4       /* Indicates support of legacy geometry */
+#define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */
 
 struct virtio_blk_config
 {
@@ -46,6 +47,9 @@ struct virtio_blk_config
 /* This bit says it's a scsi command, not an actual read or write. */
 #define VIRTIO_BLK_T_SCSI_CMD   2
 
+/* Flush the volatile write cache */
+#define VIRTIO_BLK_T_FLUSH      4
+
 /* Barrier before this op. */
 #define VIRTIO_BLK_T_BARRIER    0x80000000
 
-- 
1.6.3.rc4.29.g8146