All of lore.kernel.org
 help / color / mirror / Atom feed
From: Denis Plotnikov <dplotnikov@virtuozzo.com>
To: Eric Blake <eblake@redhat.com>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com,
	qemu-block@nongnu.org, mreitz@redhat.com
Subject: Re: [PATCH v1 3/8] qcow2: add zstd cluster compression
Date: Fri, 28 Feb 2020 14:40:07 +0300	[thread overview]
Message-ID: <8345724b-63c7-7d12-3fe7-38fac5e087b2@virtuozzo.com> (raw)
In-Reply-To: <6b9b3f63-5760-c0a1-b330-b92ac894970a@redhat.com>



On 27.02.2020 17:01, Eric Blake wrote:
> On 2/27/20 1:29 AM, Denis Plotnikov wrote:
>> zstd significantly reduces cluster compression time.
>> It provides better compression performance maintaining
>> the same level of the compression ratio in comparison with
>> zlib, which, at the moment, is the only compression
>> method available.
>>
>
>> +static ssize_t qcow2_zstd_compress(void *dest, size_t dest_size,
>> +                                   const void *src, size_t src_size)
>> +{
>> +    size_t ret;
>> +
>> +    /*
>> +     * steal ZSTD_LEN_BUF bytes in the very beginng of the buffer
>
> beginning
>
>> +     * to store compressed chunk size
>> +     */
>> +    char *d_buf = ((char *) dest) + ZSTD_LEN_BUF;
>> +
>> +    /*
>> +     * sanity check that we can store the compressed data length,
>> +     * and there is some space left for the compressor buffer
>> +     */
>> +    if (dest_size <= ZSTD_LEN_BUF) {
>> +        return -ENOMEM;
>> +    }
>> +
>> +    dest_size -= ZSTD_LEN_BUF;
>> +
>> +    ret = ZSTD_compress(d_buf, dest_size, src, src_size, 5);
>> +
>> +    if (ZSTD_isError(ret)) {
>> +        if (ZSTD_getErrorCode(ret) == ZSTD_error_dstSize_tooSmall) {
>> +            return -ENOMEM;
>> +        } else {
>> +            return -EIO;
>> +        }
>> +    }
>> +
>> +    /* paraniod sanity check that we can store the commpressed size */
>
> paranoid, compressed
>
>> +    if (ret > UINT_MAX) {
>> +        return -ENOMEM;
>> +    }
>
> This is pointless.  Better is to ensure that we actually compressed 
> data (the pigeonhole principle states that there are some inputs that 
> MUST result in inflation, in order for most other inputs to result in 
> compression).  But that check was satisfied by checking for 
> ZSTD_error_dstSize_tooSmall, which is what happens for one of those 
> uncompressible inputs.  Namely, zstd will never return a result larger 
> than dest_size, and since dest_size is smaller than UINT_MAX on entry, 
> this check is pointless.  But if you want something, I'd be okay with: 
> assert(ret <= dest_size).
Taking into account that this is "just in case" and I'm trying to 
protect the first 4 bytes of the buffer from the overflow and
I can't imagine the situation when we deal with cluster sizes greater 
than UINT32_MAX but the input size is size_t which can be > UINT32_MAX 
on 64bit archs.
I'd rather stick with
     if (ret > UINT32_MAX) {
         return -ENOMEM;
     }
as Vladimir suggested.

I'm not sure that the assert is good here, since it stops the system 
operating and this isn't potential error but a limitation
Does it work for you?

Denis
>
>> +++ b/docs/interop/qcow2.txt
>> @@ -208,6 +208,7 @@ version 2.
>>                         Available compression type values:
>>                           0: zlib <https://www.zlib.net/>
>> +                        1: zstd <http://github.com/facebook/zstd>
>>       === Header padding ===
>> @@ -575,11 +576,28 @@ Compressed Clusters Descriptor (x = 62 - 
>> (cluster_bits - 8)):
>>                       Another compressed cluster may map to the tail 
>> of the final
>>                       sector used by this compressed cluster.
>>   +                    The layout of the compressed data depends on 
>> the compression
>> +                    type used for the image (see compressed cluster 
>> layout).
>> +
>>   If a cluster is unallocated, read requests shall read the data from 
>> the backing
>>   file (except if bit 0 in the Standard Cluster Descriptor is set). 
>> If there is
>>   no backing file or the backing file is smaller than the image, they 
>> shall read
>>   zeros for all parts that are not covered by the backing file.
>>   +=== Compressed Cluster Layout ===
>> +
>> +The compressed cluster data has a layout depending on the compression
>> +type used for the image, as follows:
>> +
>> +Compressed data layout for the available compression types:
>> +(x = data_space_length - 1)
>> +
>> +    0:  (default)  zlib <http://zlib.net/>:
>> +            Byte  0 -  x:     the compressed data content
>> +                              all the space provided used for 
>> compressed data
>> +    1:  zstd <http://github.com/facebook/zstd>:
>> +            Byte  0 -  3:     the length of compressed data in bytes
>> +                  4 -  x:     the compressed data content
>>     == Snapshots ==
>>   diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index 873fbef3b5..4b6e576c44 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -4401,11 +4401,12 @@
>>   # Compression type used in qcow2 image file
>>   #
>>   # @zlib:  zlib compression, see <http://zlib.net/>
>> +# @zstd:  zstd compression, see <http://github.com/facebook/zstd>
>>   #
>>   # Since: 5.0
>>   ##
>>   { 'enum': 'Qcow2CompressionType',
>> -  'data': [ 'zlib' ] }
>> +  'data': [ 'zlib', { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } 
>> ] }
>
> The spec and UI changes are okay.
>



  reply	other threads:[~2020-02-28 11:41 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-27  7:29 [PATCH v1 0/8] qcow2: Implement zstd cluster compression method Denis Plotnikov
2020-02-27  7:29 ` [PATCH v1 1/8] qcow2: introduce compression type feature Denis Plotnikov
2020-02-27  8:21   ` Vladimir Sementsov-Ogievskiy
2020-02-27 13:24     ` Eric Blake
2020-02-27 13:48   ` Eric Blake
2020-02-27 13:59     ` Vladimir Sementsov-Ogievskiy
2020-02-27 14:13       ` Eric Blake
2020-02-27 14:30         ` Vladimir Sementsov-Ogievskiy
2020-02-27 14:39           ` Eric Blake
2020-02-28  8:34     ` Denis Plotnikov
2020-02-27  7:29 ` [PATCH v1 2/8] qcow2: rework the cluster compression routine Denis Plotnikov
2020-02-27  8:54   ` Vladimir Sementsov-Ogievskiy
2020-02-27  7:29 ` [PATCH v1 3/8] qcow2: add zstd cluster compression Denis Plotnikov
2020-02-27  9:55   ` Vladimir Sementsov-Ogievskiy
2020-02-27 14:11     ` Denis Plotnikov
2020-02-27 14:18       ` Vladimir Sementsov-Ogievskiy
2020-02-28 11:59         ` Denis Plotnikov
2020-02-27 14:01   ` Eric Blake
2020-02-28 11:40     ` Denis Plotnikov [this message]
2020-02-27  7:29 ` [PATCH v1 4/8] iotests: filter out compression_type Denis Plotnikov
2020-02-27  9:57   ` Vladimir Sementsov-Ogievskiy
2020-02-27 14:03   ` Eric Blake
2020-02-28 11:53     ` Denis Plotnikov
2020-02-27  7:29 ` [PATCH v1 5/8] iotests: fix header size, feature table size and backing file offset Denis Plotnikov
2020-02-27  9:59   ` Vladimir Sementsov-Ogievskiy
2020-02-27  7:29 ` [PATCH v1 6/8] iotests: add "compression type" for test output matching Denis Plotnikov
2020-02-27 10:04   ` Vladimir Sementsov-Ogievskiy
2020-02-27 10:09     ` Vladimir Sementsov-Ogievskiy
2020-02-27 14:06       ` Eric Blake
2020-02-28  8:13       ` Denis Plotnikov
2020-02-27  7:29 ` [PATCH v1 7/8] iotests: 080: update header size value because of adding compression type Denis Plotnikov
2020-02-27  7:29 ` [PATCH v1 8/8] iotests: 287: add qcow2 compression type test Denis Plotnikov
2020-02-27 10:29   ` Vladimir Sementsov-Ogievskiy
2020-02-28  8:23     ` Denis Plotnikov
2020-02-28  8:32       ` Vladimir Sementsov-Ogievskiy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8345724b-63c7-7d12-3fe7-38fac5e087b2@virtuozzo.com \
    --to=dplotnikov@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.