aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2011-10-26 11:21:50 +0200
committerKevin Wolf <kwolf@redhat.com>2011-10-28 19:25:49 +0200
commit64ebe71aa0e498d24e8c02b133192142fce3a0d0 (patch)
tree86965ca66a532d500d909f13bf66ae176595f82f
parent2b5728164fcf5211bbae8d3c2fc6df62dd6b2295 (diff)
qcow: Fix bdrv_write_compressed error handling
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--block/qcow.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/block/qcow.c b/block/qcow.c
index ab36b2995c..35e21eb6b3 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -736,8 +736,6 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
return -EINVAL;
out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -1;
/* best compression, small window, no zlib header */
memset(&strm, 0, sizeof(strm));
@@ -745,8 +743,8 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
Z_DEFLATED, -12,
9, Z_DEFAULT_STRATEGY);
if (ret != 0) {
- g_free(out_buf);
- return -1;
+ ret = -EINVAL;
+ goto fail;
}
strm.avail_in = s->cluster_size;
@@ -756,9 +754,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
ret = deflate(&strm, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK) {
- g_free(out_buf);
deflateEnd(&strm);
- return -1;
+ ret = -EINVAL;
+ goto fail;
}
out_len = strm.next_out - out_buf;
@@ -766,19 +764,29 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
/* could not compress: write normal cluster */
- bdrv_write(bs, sector_num, buf, s->cluster_sectors);
+ ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
+ if (ret < 0) {
+ goto fail;
+ }
} else {
cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
out_len, 0, 0);
+ if (cluster_offset == 0) {
+ ret = -EIO;
+ goto fail;
+ }
+
cluster_offset &= s->cluster_offset_mask;
- if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) {
- g_free(out_buf);
- return -1;
+ ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
+ if (ret < 0) {
+ goto fail;
}
}
+ ret = 0;
+fail:
g_free(out_buf);
- return 0;
+ return ret;
}
static coroutine_fn int qcow_co_flush(BlockDriverState *bs)