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