add the zeroinit block driver filter
[pve-qemu-kvm.git] / debian / patches / old / mirror-fix-zero-init.patch
blobcd76df5cb906f9f76e6f038d26b6cc34112ff67d
1 From patchwork Thu Oct 1 19:05:28 2015
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 Subject: [PULL,
6 1/1] block: mirror - fix full sync mode when target does not support
7 zero init
8 From: Jeff Cody <jcody@redhat.com>
9 X-Patchwork-Id: 525278
10 Message-Id: <1443726328-29484-2-git-send-email-jcody@redhat.com>
11 To: qemu-block@nongnu.org
12 Cc: peter.maydell@linaro.org, jcody@redhat.com, qemu-devel@nongnu.org
13 Date: Thu, 1 Oct 2015 15:05:28 -0400
15 During mirror, if the target device does not support zero init, a
16 mirror may result in a corrupted image for sync="full" mode.
18 This is due to how the initial dirty bitmap is set up prior to copying
19 data - we did not mark sectors as dirty that are unallocated. This
20 means those unallocated sectors are skipped over on the target, and for
21 a device without zero init, invalid data may reside in those holes.
23 If both of the following conditions are true, then we will explicitly
24 mark all sectors as dirty:
26 1.) sync = "full"
27 2.) bdrv_has_zero_init(target) == false
29 If the target does support zero init, but a target image is passed in
30 with data already present (i.e. an "existing" image), it is assumed the
31 data present in the existing image is valid data for those sectors.
33 Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
34 Message-id: 91ed4bc5bda7e2b09eb508b07c83f4071fe0b3c9.1443705220.git.jcody@redhat.com
35 Signed-off-by: Jeff Cody <jcody@redhat.com>
36 ---
37 block/mirror.c | 4 +++-
38 1 file changed, 3 insertions(+), 1 deletion(-)
40 diff --git a/block/mirror.c b/block/mirror.c
41 index 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);
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)
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);
61 sector_num += n;