summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-05-19 12:40:09 +0200
committerKevin Wolf <kwolf@redhat.com>2010-05-21 11:49:19 +0200
commit618fbb84299780af96e3d4c4b6f2148656fe3708 (patch)
treeba3fdaa1fe637ac824767fccb3e1df797d7fc46a /hw
parentde6c8042ec55da18702fa51f09072fcaa315edc3 (diff)
downloadqemu-618fbb84299780af96e3d4c4b6f2148656fe3708.tar.gz
virtio-blk: fix barrier support
Before issuing the barrier to the block driver we need to flush our oustanding queue of write requests, as the flush is supposed to be issued after them. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/virtio-blk.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index d270225020..5d7f1a2200 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -240,10 +240,20 @@ static void do_multiwrite(BlockDriverState *bs, BlockRequest *blkreq,
}
}
-static void virtio_blk_handle_flush(VirtIOBlockReq *req)
+static void virtio_blk_handle_flush(BlockRequest *blkreq, int *num_writes,
+ VirtIOBlockReq *req, BlockDriverState **old_bs)
{
BlockDriverAIOCB *acb;
+ /*
+ * Make sure all outstanding writes are posted to the backing device.
+ */
+ if (*old_bs != NULL) {
+ do_multiwrite(*old_bs, blkreq, *num_writes);
+ }
+ *num_writes = 0;
+ *old_bs = req->dev->bs;
+
acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
if (!acb) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
@@ -316,7 +326,8 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
if (req->out->type & VIRTIO_BLK_T_FLUSH) {
- virtio_blk_handle_flush(req);
+ virtio_blk_handle_flush(mrb->blkreq, &mrb->num_writes,
+ req, &mrb->old_bs);
} else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
virtio_blk_handle_scsi(req);
} else if (req->out->type & VIRTIO_BLK_T_OUT) {