From 25dd077d1d0aaef23f8608468cbef9a396583b1b Mon Sep 17 00:00:00 2001 From: Denis Plotnikov Date: Thu, 7 May 2020 11:25:19 +0300 Subject: [PATCH] qcow2: rework the cluster compression routine The patch enables processing the image compression type defined for the image and chooses an appropriate method for image clusters (de)compression. Signed-off-by: Denis Plotnikov Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Alberto Garcia Reviewed-by: Max Reitz Message-Id: <20200507082521.29210-3-dplotnikov@virtuozzo.com> Signed-off-by: Max Reitz --- block/qcow2-threads.c | 71 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c index a68126f291..7dbaf53489 100644 --- a/block/qcow2-threads.c +++ b/block/qcow2-threads.c @@ -74,7 +74,9 @@ typedef struct Qcow2CompressData { } Qcow2CompressData; /* - * qcow2_compress() + * qcow2_zlib_compress() + * + * Compress @src_size bytes of data using zlib compression method * * @dest - destination buffer, @dest_size bytes * @src - source buffer, @src_size bytes @@ -83,8 +85,8 @@ typedef struct Qcow2CompressData { * -ENOMEM destination buffer is not enough to store compressed data * -EIO on any other error */ -static ssize_t qcow2_compress(void *dest, size_t dest_size, - const void *src, size_t src_size) +static ssize_t qcow2_zlib_compress(void *dest, size_t dest_size, + const void *src, size_t src_size) { ssize_t ret; z_stream strm; @@ -119,10 +121,10 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size, } /* - * qcow2_decompress() + * qcow2_zlib_decompress() * * Decompress some data (not more than @src_size bytes) to produce exactly - * @dest_size bytes. + * @dest_size bytes using zlib compression method * * @dest - destination buffer, @dest_size bytes * @src - source buffer, @src_size bytes @@ -130,8 +132,8 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size, * Returns: 0 on success * -EIO on fail */ -static ssize_t qcow2_decompress(void *dest, size_t dest_size, - const void *src, size_t src_size) +static ssize_t qcow2_zlib_decompress(void *dest, size_t dest_size, + const void *src, size_t src_size) { int ret; z_stream strm; @@ -191,20 +193,67 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size, return arg.ret; } +/* + * qcow2_co_compress() + * + * Compress @src_size bytes of data using the compression + * method defined by the image compression type + * + * @dest - destination buffer, @dest_size bytes + * @src - source buffer, @src_size bytes + * + * Returns: compressed size on success + * a negative error code on failure + */ ssize_t coroutine_fn qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size, const void *src, size_t src_size) { - return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, - qcow2_compress); + BDRVQcow2State *s = bs->opaque; + Qcow2CompressFunc fn; + + switch (s->compression_type) { + case QCOW2_COMPRESSION_TYPE_ZLIB: + fn = qcow2_zlib_compress; + break; + + default: + abort(); + } + + return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn); } +/* + * qcow2_co_decompress() + * + * Decompress some data (not more than @src_size bytes) to produce exactly + * @dest_size bytes using the compression method defined by the image + * compression type + * + * @dest - destination buffer, @dest_size bytes + * @src - source buffer, @src_size bytes + * + * Returns: 0 on success + * a negative error code on failure + */ ssize_t coroutine_fn qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size, const void *src, size_t src_size) { - return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, - qcow2_decompress); + BDRVQcow2State *s = bs->opaque; + Qcow2CompressFunc fn; + + switch (s->compression_type) { + case QCOW2_COMPRESSION_TYPE_ZLIB: + fn = qcow2_zlib_decompress; + break; + + default: + abort(); + } + + return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn); }