summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-05-19 12:40:09 +0200
committerDoug Goldstein <cardoe@gentoo.org>2010-07-20 17:28:40 -0500
commitf2376fa30f49ddc1aa4a7c5fb8be0a358c3e0773 (patch)
tree01e299fef6193cfa50e1fdb28c45a985431f6316
parentblock: fix sector comparism in multiwrite_req_compare (diff)
downloadqemu-kvm-f2376fa30f49ddc1aa4a7c5fb8be0a358c3e0773.tar.gz
qemu-kvm-f2376fa30f49ddc1aa4a7c5fb8be0a358c3e0773.tar.bz2
qemu-kvm-f2376fa30f49ddc1aa4a7c5fb8be0a358c3e0773.zip
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> (cherry picked from commit 618fbb84299780af96e3d4c4b6f2148656fe3708)
-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 2fd9b3fba..0871d2024 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -278,10 +278,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);
@@ -344,7 +354,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) {