]> git.proxmox.com Git - qemu.git/commitdiff
block: bdrv_has_zero_init
authorKevin Wolf <kwolf@redhat.com>
Wed, 14 Apr 2010 15:30:35 +0000 (17:30 +0200)
committerKevin Wolf <kwolf@redhat.com>
Mon, 3 May 2010 08:07:30 +0000 (10:07 +0200)
This fixes the problem that qemu-img's use of no_zero_init only considered the
no_zero_init flag of the format driver, but not of the underlying protocols.

Between the raw/file split and this fix, converting to host devices is broken.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block.c
block.h
qemu-img.c

diff --git a/block.c b/block.c
index eb1d5621b53b0da1a48593c92412cb775f65472a..56835afc567262fbaf88fc5ce692c886f74e6f41 100644 (file)
--- a/block.c
+++ b/block.c
@@ -1282,6 +1282,19 @@ void bdrv_flush_all(void)
     }
 }
 
+int bdrv_has_zero_init(BlockDriverState *bs)
+{
+    assert(bs->drv);
+
+    if (bs->drv->no_zero_init) {
+        return 0;
+    } else if (bs->file) {
+        return bdrv_has_zero_init(bs->file);
+    }
+
+    return 1;
+}
+
 /*
  * Returns true iff the specified sector is present in the disk image. Drivers
  * not implementing the functionality are assumed to not support backing files,
diff --git a/block.h b/block.h
index f58edf17c38900e377140ebf3be6c0279ea5aa3d..f87d24e5c88340dfc5c158c9406e8aff0f97d7da 100644 (file)
--- a/block.h
+++ b/block.h
@@ -122,6 +122,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
 void bdrv_flush(BlockDriverState *bs);
 void bdrv_flush_all(void);
 
+int bdrv_has_zero_init(BlockDriverState *bs);
 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
        int *pnum);
 
index 7203b8bc72ca554320a2a9dc10d07875e1249d00..74311a5215aa9365425be8da23663f64ab5b25df 100644 (file)
@@ -732,6 +732,8 @@ static int img_convert(int argc, char **argv)
         /* signal EOF to align */
         bdrv_write_compressed(out_bs, 0, NULL, 0);
     } else {
+        int has_zero_init = bdrv_has_zero_init(out_bs);
+
         sector_num = 0; // total number of sectors converted so far
         for(;;) {
             nb_sectors = total_sectors - sector_num;
@@ -755,7 +757,7 @@ static int img_convert(int argc, char **argv)
             if (n > bs_offset + bs_sectors - sector_num)
                 n = bs_offset + bs_sectors - sector_num;
 
-            if (!drv->no_zero_init) {
+            if (has_zero_init) {
                 /* If the output image is being created as a copy on write image,
                    assume that sectors which are unallocated in the input image
                    are present in both the output's and input's base images (no
@@ -788,7 +790,7 @@ static int img_convert(int argc, char **argv)
                    If the output is to a host device, we also write out
                    sectors that are entirely 0, since whatever data was
                    already there is garbage, not 0s. */
-                if (drv->no_zero_init || out_baseimg ||
+                if (!has_zero_init || out_baseimg ||
                     is_allocated_sectors(buf1, n, &n1)) {
                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
                         error("error while writing");