0a122b
From 35538bdb46122fdf90ca869df29869b8aeaefa09 Mon Sep 17 00:00:00 2001
0a122b
From: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
Date: Tue, 25 Mar 2014 14:23:42 +0100
0a122b
Subject: [PATCH 35/49] dmg: drop broken bdrv_pread() loop
0a122b
0a122b
RH-Author: Kevin Wolf <kwolf@redhat.com>
0a122b
Message-id: <1395753835-7591-36-git-send-email-kwolf@redhat.com>
0a122b
Patchwork-id: n/a
0a122b
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 35/48] dmg: drop broken bdrv_pread() loop
0a122b
Bugzilla: 1066691
0a122b
RH-Acked-by: Jeff Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
0a122b
From: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
0a122b
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1066691
0a122b
Upstream status: Series embargoed
0a122b
0a122b
It is not necessary to check errno for EINTR and the block layer does
0a122b
not produce short reads. Therefore we can drop the loop that attempts
0a122b
to read a compressed chunk.
0a122b
0a122b
The loop is buggy because it incorrectly adds the transferred bytes
0a122b
twice:
0a122b
0a122b
do {
0a122b
ret = bdrv_pread(...);
0a122b
i += ret;
0a122b
} while (ret >= 0 && ret + i < s->lengths[chunk]);
0a122b
0a122b
Luckily we can drop the loop completely and perform a single
0a122b
bdrv_pread().
0a122b
0a122b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
---
0a122b
 block/dmg.c |   15 ++-------------
0a122b
 1 files changed, 2 insertions(+), 13 deletions(-)
0a122b
0a122b
diff --git a/block/dmg.c b/block/dmg.c
0a122b
index f4f3e8e..1cc5426 100644
0a122b
--- a/block/dmg.c
0a122b
+++ b/block/dmg.c
0a122b
@@ -298,21 +298,10 @@ static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
0a122b
         s->current_chunk = s->n_chunks;
0a122b
         switch (s->types[chunk]) {
0a122b
         case 0x80000005: { /* zlib compressed */
0a122b
-            int i;
0a122b
-
0a122b
             /* we need to buffer, because only the chunk as whole can be
0a122b
              * inflated. */
0a122b
-            i = 0;
0a122b
-            do {
0a122b
-                ret = bdrv_pread(bs->file, s->offsets[chunk] + i,
0a122b
-                                 s->compressed_chunk + i,
0a122b
-                                 s->lengths[chunk] - i);
0a122b
-                if (ret < 0 && errno == EINTR) {
0a122b
-                    ret = 0;
0a122b
-                }
0a122b
-                i += ret;
0a122b
-            } while (ret >= 0 && ret + i < s->lengths[chunk]);
0a122b
-
0a122b
+            ret = bdrv_pread(bs->file, s->offsets[chunk],
0a122b
+                             s->compressed_chunk, s->lengths[chunk]);
0a122b
             if (ret != s->lengths[chunk]) {
0a122b
                 return -1;
0a122b
             }
0a122b
-- 
0a122b
1.7.1
0a122b