From 94968b7fa9b14e71f004474d7ce77e189e6a2bf3 Mon Sep 17 00:00:00 2001
Message-Id: <94968b7fa9b14e71f004474d7ce77e189e6a2bf3.1349175436.git.minovotn@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 13 Sep 2012 15:05:12 +0200
Subject: [PATCH 01/34] stream: do not copy unallocated sectors from the base

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1347548712-22634-1-git-send-email-pbonzini@redhat.com>
Patchwork-id: 41896
O-Subject: [RHEL 6.4 qemu-kvm PATCH v2] stream: do not copy unallocated sectors from the base
Bugzilla: 832336
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>

Bugzilla: 832336

Unallocated sectors should really never be accessed by the guest,
so there's no need to copy them during the streaming process.
If they are read by the guest during streaming, guest-initiated
copy-on-read will copy them (we're in the base == NULL case, which
enables copy on read).  If they are read after we disconnect the
image from the base, they will read as zeroes anyway.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commits 04120e3bb0323c3c81c252301485ad81dd842718
 and efcc7a23242dd0fa05932383cf35c068d16e6bbf)

Conflicts:
	tests/qemu-iotests/030
---
        v1->v2: note commit 04120e3bb0323c3c81c252301485ad81dd842718
            in the log.

 block/stream.c | 20 +++++---------------
 1 file modificato, 5 inserzioni(+), 15 rimozioni(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 block/stream.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 83e200e..76a21c4 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -141,14 +141,9 @@ static int coroutine_fn is_allocated_base(BlockDriverState *top,
      */
     intermediate = top->backing_hd;
 
-    while (intermediate) {
+    while (intermediate != base) {
         int pnum_inter;
 
-        /* reached base */
-        if (intermediate == base) {
-            *pnum = n;
-            return 1;
-        }
         ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
                                    &pnum_inter);
         if (ret < 0) {
@@ -171,6 +166,7 @@ static int coroutine_fn is_allocated_base(BlockDriverState *top,
         intermediate = intermediate->backing_hd;
     }
 
+    *pnum = n;
     return 1;
 }
 
@@ -181,7 +177,7 @@ static void coroutine_fn stream_run(void *opaque)
     BlockDriverState *base = s->base;
     int64_t sector_num, end;
     int ret = 0;
-    int n;
+    int n = 0;
     void *buf;
 
     s->common.len = bdrv_getlength(bs);
@@ -214,14 +210,8 @@ wait:
             break;
         }
 
-        if (base) {
-            ret = is_allocated_base(bs, base, sector_num,
-                                    STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
-        } else {
-            ret = bdrv_co_is_allocated(bs, sector_num,
-                                       STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE,
-                                       &n);
-        }
+        ret = is_allocated_base(bs, base, sector_num,
+                                STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
         trace_stream_one_iteration(s, sector_num, n, ret);
         if (ret == 0) {
             if (s->common.speed) {
-- 
1.7.11.4

