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 <h...@lst.de> Index: qemu/hw/virtio-blk.c =================================================================== --- qemu.orig/hw/virtio-blk.c 2010-05-19 11:05:23.259005741 +0200 +++ qemu/hw/virtio-blk.c 2010-05-19 11:08:09.797255846 +0200 @@ -238,10 +238,20 @@ static void do_multiwrite(BlockDriverSta } } -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); @@ -314,7 +324,8 @@ static void virtio_blk_handle_request(Vi 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) {