Patchwork virtio-blk: fix barrier support

login
register
mail settings
Submitter Christoph Hellwig
Date May 19, 2010, 10:40 a.m.
Message ID <20100519104009.GA8813@lst.de>
Download mbox | patch
Permalink /patch/52972/
State New
Headers show

Comments

Christoph Hellwig - May 19, 2010, 10:40 a.m.
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>
Kevin Wolf - May 19, 2010, 11:27 a.m.
Am 19.05.2010 12:40, schrieb Christoph Hellwig:
> 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>

Thanks, applied to the block branch.

I'm going to send a pull request today to get this in ASAP. It would be
helpful to know by then why Avi's patch helps and if it should be
pushed, too. It looks merely like a workaround, so I'd love to see it
replaced by a real fix.

Kevin

Patch

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) {