On 10/24/2011 11:53 AM, Kevin Wolf wrote:
>> >  
>> >  I'm talking about the internal driver API only.  The external API is
>> >  fine as is.
> Ok, so external callers don't force us to do it.
> 
> Yes, we could split bdrv_flush internally into two functions for "flush
> one level to the OS" and "flush all the way down to the disk", but I'm
> not sure if this really buys us anything or just adds complexity.

I would say that:

1) the "safe" NBD and iSCSI drivers are not in-tree, but you would have to
convert those too.  iSCSI uses aio, so it would be non-trivial.

2) long-term you wanted to convert raw-posix to coroutines, but in the
meanwhile your patch introduces yet another partial transition;

3) your two patches are more complex compared to something like this:

diff --git a/block.c b/block.c
index 11c7f91..1e06a8a 100644
--- a/block.c
+++ b/block.c
@@ -2908,9 +2908,19 @@ static void coroutine_fn bdrv_flush_co_entry(void 
*opaque)
 
 int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 {
-    if (bs->open_flags & BDRV_O_NO_FLUSH) {
+    if (!bs->drv) {
         return 0;
-    } else if (!bs->drv) {
+    }
+
+    /* First send everything to the OS.  */
+    if (bs->drv->bdrv_co_flush_metadata) {
+        int ret = bs->drv->bdrv_co_flush_metadata(bs);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    /* Now flush the host cache to disk if we need to.  */
+    if (bs->open_flags & BDRV_O_NO_FLUSH) {
         return 0;
     } else if (bs->drv->bdrv_co_flush) {
         return bs->drv->bdrv_co_flush(bs);
diff --git a/block/qcow2.c b/block/qcow2.c
index a181932..cd13452 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1105,7 +1105,7 @@ fail:
     return ret;
 }
 
-static int qcow2_co_flush(BlockDriverState *bs)
+static int qcow2_co_flush_metadata(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     int ret;
@@ -1121,7 +1121,11 @@ static int qcow2_co_flush(BlockDriverState *bs)
         return ret;
     }
     qemu_co_mutex_unlock(&s->lock);
+    return 0;
+}
 
+static int qcow2_co_flush(BlockDriverState *bs)
+{
     return bdrv_co_flush(bs->file);
 }
 
@@ -1244,6 +1248,7 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_co_readv      = qcow2_co_readv,
     .bdrv_co_writev     = qcow2_co_writev,
     .bdrv_co_flush      = qcow2_co_flush,
+    .bdrv_co_flush_metadata = qcow2_co_flush_metadata,
 
     .bdrv_co_discard        = qcow2_co_discard,
     .bdrv_truncate          = qcow2_truncate,
diff --git a/block_int.h b/block_int.h
index dac00f5..ab4ceea 100644
--- a/block_int.h
+++ b/block_int.h
@@ -84,6 +84,7 @@ struct BlockDriver {
     int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
+    int coroutine_fn (*bdrv_co_flush_metadata)(BlockDriverState *bs);
     int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors);
 
Paolo

Reply via email to