qcow2: Fix error handling in the compression code

This patch fixes a few things in the way error codes are handled in
the qcow2 compression code:

a) qcow2_co_pwritev_compressed() expects qcow2_co_compress() to only
   return -1 or -2 on failure, but this is not correct. Since the
   change from qcow2_compress() to qcow2_co_compress() in commit
   ceb029cd6f the new code can also return -EINVAL (although
   there does not seem to exist any code path that would cause that
   error in the current implementation).

b) -1 and -2 are ad-hoc error codes defined in qcow2_compress().
   This patch replaces them with standard constants from errno.h.

c) Both qcow2_compress() and qcow2_co_do_compress() return a negative
   value on failure, but qcow2_co_pwritev_compressed() stores the
   value in an unsigned data type.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Alberto Garcia 2019-04-30 13:08:02 +03:00 committed by Kevin Wolf
parent db04524f82
commit e1f4a37a49

View file

@ -3929,8 +3929,8 @@ fail:
* @src - source buffer, @src_size bytes * @src - source buffer, @src_size bytes
* *
* Returns: compressed size on success * Returns: compressed size on success
* -1 destination buffer is not enough to store compressed data * -ENOMEM destination buffer is not enough to store compressed data
* -2 on any other error * -EIO on any other error
*/ */
static ssize_t qcow2_compress(void *dest, size_t dest_size, static ssize_t qcow2_compress(void *dest, size_t dest_size,
const void *src, size_t src_size) const void *src, size_t src_size)
@ -3943,7 +3943,7 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
-12, 9, Z_DEFAULT_STRATEGY); -12, 9, Z_DEFAULT_STRATEGY);
if (ret != Z_OK) { if (ret != Z_OK) {
return -2; return -EIO;
} }
/* strm.next_in is not const in old zlib versions, such as those used on /* strm.next_in is not const in old zlib versions, such as those used on
@ -3957,7 +3957,7 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
if (ret == Z_STREAM_END) { if (ret == Z_STREAM_END) {
ret = dest_size - strm.avail_out; ret = dest_size - strm.avail_out;
} else { } else {
ret = (ret == Z_OK ? -1 : -2); ret = (ret == Z_OK ? -ENOMEM : -EIO);
} }
deflateEnd(&strm); deflateEnd(&strm);
@ -4096,7 +4096,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
QEMUIOVector hd_qiov; QEMUIOVector hd_qiov;
int ret; int ret;
size_t out_len; ssize_t out_len;
uint8_t *buf, *out_buf; uint8_t *buf, *out_buf;
uint64_t cluster_offset; uint64_t cluster_offset;
@ -4135,16 +4135,16 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
out_len = qcow2_co_compress(bs, out_buf, s->cluster_size - 1, out_len = qcow2_co_compress(bs, out_buf, s->cluster_size - 1,
buf, s->cluster_size); buf, s->cluster_size);
if (out_len == -2) { if (out_len == -ENOMEM) {
ret = -EINVAL;
goto fail;
} else if (out_len == -1) {
/* could not compress: write normal cluster */ /* could not compress: write normal cluster */
ret = qcow2_co_pwritev(bs, offset, bytes, qiov, 0); ret = qcow2_co_pwritev(bs, offset, bytes, qiov, 0);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
} }
goto success; goto success;
} else if (out_len < 0) {
ret = -EINVAL;
goto fail;
} }
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);