qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] qcow2 corruption caused by r5006
@ 2009-03-29  1:30 Nolan
  0 siblings, 0 replies; only message in thread
From: Nolan @ 2009-03-29  1:30 UTC (permalink / raw)
  To: qemu-devel@nongnu.org

While working on a semi-related bug fix (to be sent later) I've been
experimenting with the following hack:

Index: qemu-img.c
===================================================================
--- qemu-img.c  (revision 6929)
+++ qemu-img.c  (working copy)
@@ -596,7 +596,7 @@
                assume that sectors which are unallocated in the input image
                are present in both the output's and input's base images (no
                need to copy them). */
-            if (out_baseimg) {
+            if (1 || out_baseimg) {
                if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
                   sector_num += n1;
                   continue;

My theory being that there is no point making is_allocated_sectors()
memcmp unallocated blocks that we already know will bdrv_read as all
'\0's.  In practice, this results in a nice (2-10x) speed up when doing
a "qemu-img convert" from a sparse format.

The problem is that this breaks "qemu-img convert" when the source is
qcow2 (other formats are fine).  The symptom is that the destination
image has zeroed sectors where the source had actual data!

A binary search narrowed it down to r5006, same as this report:
http://www.mail-archive.com/kvm@vger.kernel.org/msg10416.html

Reverting out that patch fixes it, as does this simpler partial
reversion:
Index: block-qcow2.c
===================================================================
--- block-qcow2.c       (revision 6929)
+++ block-qcow2.c       (working copy)
@@ -1101,11 +1101,19 @@
 static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum)
 {
+    BDRVQcowState *s = bs->opaque;
+    int index_in_cluster, n;
     uint64_t cluster_offset;
 
     *pnum = nb_sectors;
     cluster_offset = get_cluster_offset(bs, sector_num << 9, pnum);
-
+#if 0
+    index_in_cluster = sector_num & (s->cluster_sectors - 1);
+    n = s->cluster_sectors - index_in_cluster;
+    if (n > nb_sectors)
+        n = nb_sectors;
+    *pnum = n;
+#endif
     return (cluster_offset != 0);
 }

Though I doubt this partial reversion will fix the issue reported in the
link above.

On the plus side, this (unlike many of the qcow2 corruption reports) is
a trivially and consistently reproducible case.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-03-29  1:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-29  1:30 [Qemu-devel] qcow2 corruption caused by r5006 Nolan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).