Sophie

Sophie

distrib > Mageia > 4 > x86_64 > media > core-updates-src > by-pkgid > 405ecbfd47707aaab6090c273e001faa > files > 64

qemu-1.6.2-1.10.mga4.src.rpm

From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Wed, 26 Mar 2014 13:05:56 +0100
Subject: [PATCH] dmg: drop broken bdrv_pread() loop

It is not necessary to check errno for EINTR and the block layer does
not produce short reads.  Therefore we can drop the loop that attempts
to read a compressed chunk.

The loop is buggy because it incorrectly adds the transferred bytes
twice:

  do {
      ret = bdrv_pread(...);
      i += ret;
  } while (ret >= 0 && ret + i < s->lengths[chunk]);

Luckily we can drop the loop completely and perform a single
bdrv_pread().

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit b404bf854217dbe8a5649449eb3ad33777f7d900)
---
 block/dmg.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/block/dmg.c b/block/dmg.c
index cb4060c..24f08ef 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -297,21 +297,10 @@ static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
         s->current_chunk = s->n_chunks;
         switch (s->types[chunk]) {
         case 0x80000005: { /* zlib compressed */
-            int i;
-
             /* we need to buffer, because only the chunk as whole can be
              * inflated. */
-            i = 0;
-            do {
-                ret = bdrv_pread(bs->file, s->offsets[chunk] + i,
-                                 s->compressed_chunk + i,
-                                 s->lengths[chunk] - i);
-                if (ret < 0 && errno == EINTR) {
-                    ret = 0;
-                }
-                i += ret;
-            } while (ret >= 0 && ret + i < s->lengths[chunk]);
-
+            ret = bdrv_pread(bs->file, s->offsets[chunk],
+                             s->compressed_chunk, s->lengths[chunk]);
             if (ret != s->lengths[chunk]) {
                 return -1;
             }