mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-27 12:02:04 -06:00
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>
This commit is contained in:
parent
73ed27ec28
commit
b404bf8542
1 changed files with 2 additions and 13 deletions
15
block/dmg.c
15
block/dmg.c
|
@ -298,21 +298,10 @@ static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
|
||||||
s->current_chunk = s->n_chunks;
|
s->current_chunk = s->n_chunks;
|
||||||
switch (s->types[chunk]) {
|
switch (s->types[chunk]) {
|
||||||
case 0x80000005: { /* zlib compressed */
|
case 0x80000005: { /* zlib compressed */
|
||||||
int i;
|
|
||||||
|
|
||||||
/* we need to buffer, because only the chunk as whole can be
|
/* we need to buffer, because only the chunk as whole can be
|
||||||
* inflated. */
|
* inflated. */
|
||||||
i = 0;
|
ret = bdrv_pread(bs->file, s->offsets[chunk],
|
||||||
do {
|
s->compressed_chunk, s->lengths[chunk]);
|
||||||
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]);
|
|
||||||
|
|
||||||
if (ret != s->lengths[chunk]) {
|
if (ret != s->lengths[chunk]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue