]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/mirror-fix-zero-init.patch
Two more fixes
[pve-qemu-kvm.git] / debian / patches / mirror-fix-zero-init.patch
CommitLineData
f1ec9ffb
AD
1From patchwork Thu Oct 1 19:05:28 2015
2Content-Type: text/plain; charset="utf-8"
3MIME-Version: 1.0
4Content-Transfer-Encoding: 7bit
5Subject: [PULL,
6 1/1] block: mirror - fix full sync mode when target does not support
7 zero init
8From: Jeff Cody <jcody@redhat.com>
9X-Patchwork-Id: 525278
10Message-Id: <1443726328-29484-2-git-send-email-jcody@redhat.com>
11To: qemu-block@nongnu.org
12Cc: peter.maydell@linaro.org, jcody@redhat.com, qemu-devel@nongnu.org
13Date: Thu, 1 Oct 2015 15:05:28 -0400
14
15During mirror, if the target device does not support zero init, a
16mirror may result in a corrupted image for sync="full" mode.
17
18This is due to how the initial dirty bitmap is set up prior to copying
19data - we did not mark sectors as dirty that are unallocated. This
20means those unallocated sectors are skipped over on the target, and for
21a device without zero init, invalid data may reside in those holes.
22
23If both of the following conditions are true, then we will explicitly
24mark all sectors as dirty:
25
26 1.) sync = "full"
27 2.) bdrv_has_zero_init(target) == false
28
29If the target does support zero init, but a target image is passed in
30with data already present (i.e. an "existing" image), it is assumed the
31data present in the existing image is valid data for those sectors.
32
33Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
34Message-id: 91ed4bc5bda7e2b09eb508b07c83f4071fe0b3c9.1443705220.git.jcody@redhat.com
35Signed-off-by: Jeff Cody <jcody@redhat.com>
36---
37 block/mirror.c | 4 +++-
38 1 file changed, 3 insertions(+), 1 deletion(-)
39
40diff --git a/block/mirror.c b/block/mirror.c
41index a258926..87928ab 100644
42--- a/block/mirror.c
43+++ b/block/mirror.c
44@@ -455,6 +455,8 @@ static void coroutine_fn mirror_run(void *opaque)
45 if (!s->is_none_mode) {
46 /* First part, loop on the sectors and initialize the dirty bitmap. */
47 BlockDriverState *base = s->base;
48+ bool mark_all_dirty = s->base == NULL && !bdrv_has_zero_init(s->target);
49+
50 for (sector_num = 0; sector_num < end; ) {
51 /* Just to make sure we are not exceeding int limit. */
52 int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
53@@ -477,7 +479,7 @@ static void coroutine_fn mirror_run(void *opaque)
54 }
55
56 assert(n > 0);
57- if (ret == 1) {
58+ if (ret == 1 || mark_all_dirty) {
59 bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
60 }
61 sector_num += n;