All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v5 10/26] qcow2: Helper function for refcount modification
Date: Wed, 04 Feb 2015 12:12:30 -0500	[thread overview]
Message-ID: <54D252FE.9030106@redhat.com> (raw)
In-Reply-To: <20150204160645.GF5641@noname.redhat.com>

On 2015-02-04 at 11:06, Kevin Wolf wrote:
> Am 15.12.2014 um 13:50 hat Max Reitz geschrieben:
>> Since refcounts do not always have to be a uint16_t, all refcount blocks
>> and arrays in memory should not have a specific type (thus they become
>> pointers to void) and for accessing them, two helper functions are used
>> (a getter and a setter). Those functions are called indirectly through
>> function pointers in the BDRVQcowState so they may later be exchanged
>> for different refcount orders.
>>
>> With the check and repair functions using this function, the refcount
>> array they are creating will be in big endian byte order; additionally,
>> using realloc_refcount_array() makes the size of this refcount array
>> always cluster-aligned. Both combined allow rebuild_refcount_structure()
>> to drop the bounce buffer which was used to convert parts of the
>> refcount array to big endian byte order and store them on disk. Instead,
>> those parts can now be written directly.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
>> ---
>>   block/qcow2-refcount.c | 122 ++++++++++++++++++++++++++++---------------------
>>   block/qcow2.h          |   8 ++++
>>   2 files changed, 79 insertions(+), 51 deletions(-)
>> @@ -541,7 +561,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
>>   {
>>       BDRVQcowState *s = bs->opaque;
>>       int64_t start, last, cluster_offset;
>> -    uint16_t *refcount_block = NULL;
>> +    void *refcount_block = NULL;
>>       int64_t old_table_index = -1;
>>       int ret;
>>   
>> @@ -593,7 +613,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
>>           /* we can update the count and save it */
>>           block_index = cluster_index & (s->refcount_block_size - 1);
>>   
>> -        refcount = be16_to_cpu(refcount_block[block_index]);
>> +        refcount = s->get_refcount(refcount_block, block_index);
>>           if (decrease ? (refcount - addend > refcount)
>>                        : (refcount + addend < refcount ||
>>                           refcount + addend > s->refcount_max))
>> @@ -609,7 +629,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
>>           if (refcount == 0 && cluster_index < s->free_cluster_index) {
>>               s->free_cluster_index = cluster_index;
>>           }
>> -        refcount_block[block_index] = cpu_to_be16(refcount);
>> +        s->set_refcount(refcount_block, block_index, refcount);
>>   
>>           if (refcount == 0 && s->discard_passthrough[type]) {
>>               update_refcount_discard(bs, cluster_offset, s->cluster_size);
>> @@ -625,8 +645,7 @@ fail:
>>       /* Write last changed block to disk */
>>       if (refcount_block) {
>>           int wret;
>> -        wret = qcow2_cache_put(bs, s->refcount_block_cache,
>> -            (void**) &refcount_block);
>> +        wret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
>>           if (wret < 0) {
>>               return ret < 0 ? ret : wret;
>>           }
> There is a (void**) cast left in the other qcow2_cache_put() call in
> update_refcount().

Will remove.

>> @@ -1883,7 +1907,7 @@ static int64_t alloc_clusters_imrt(BlockDriverState *bs,
>>    */
>>   static int rebuild_refcount_structure(BlockDriverState *bs,
>>                                         BdrvCheckResult *res,
>> -                                      uint16_t **refcount_table,
>> +                                      void **refcount_table,
>>                                         int64_t *nb_clusters)
>>   {
>>       BDRVQcowState *s = bs->opaque;
>> @@ -1891,8 +1915,8 @@ static int rebuild_refcount_structure(BlockDriverState *bs,
>>       int64_t refblock_offset, refblock_start, refblock_index;
>>       uint32_t reftable_size = 0;
>>       uint64_t *on_disk_reftable = NULL;
>> -    uint16_t *on_disk_refblock;
>> -    int i, ret = 0;
>> +    void *on_disk_refblock;
>> +    int ret = 0;
>>       struct {
>>           uint64_t reftable_offset;
>>           uint32_t reftable_clusters;
>> @@ -1902,7 +1926,7 @@ static int rebuild_refcount_structure(BlockDriverState *bs,
>>   
>>   write_refblocks:
>>       for (; cluster < *nb_clusters; cluster++) {
>> -        if (!(*refcount_table)[cluster]) {
>> +        if (!s->get_refcount(*refcount_table, cluster)) {
>>               continue;
>>           }
>>   
>> @@ -1975,17 +1999,13 @@ write_refblocks:
>>               goto fail;
>>           }
>>   
>> -        on_disk_refblock = qemu_blockalign0(bs->file, s->cluster_size);
>> -        for (i = 0; i < s->refcount_block_size &&
>> -                    refblock_start + i < *nb_clusters; i++)
>> -        {
>> -            on_disk_refblock[i] =
>> -                cpu_to_be16((*refcount_table)[refblock_start + i]);
>> -        }
>> +        /* The size of *refcount_table is always cluster-aligned, therefore the
>> +         * write operation will not overflow */
>> +        on_disk_refblock = (void *)((uintptr_t)*refcount_table +
>> +                                    (refblock_index << s->refcount_block_bits));
> Are you sure about s->refcount_block_bits? You're now calculating in
> bytes and not in entries any more like before with uint16_t*.So I think
> this should be s->cluster_bits now (or refblock_index * s->cluster_size
> if you don't want to confuse people more than necessary :-)).

You're right. Now I'm wondering why it worked, though. Maybe  the tests 
only covered the refblock_index == 0 case...

Good catch, thanks!

Max

>>           ret = bdrv_write(bs->file, refblock_offset / BDRV_SECTOR_SIZE,
>> -                         (void *)on_disk_refblock, s->cluster_sectors);
>> -        qemu_vfree(on_disk_refblock);
>> +                         on_disk_refblock, s->cluster_sectors);
>>           if (ret < 0) {
>>               fprintf(stderr, "ERROR writing refblock: %s\n", strerror(-ret));
>>               goto fail;
> Kevin

  reply	other threads:[~2015-02-04 17:12 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-15 12:50 [Qemu-devel] [PATCH v5 00/26] qcow2: Support refcount orders != 4 Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 01/26] qcow2: Add two new fields to BDRVQcowState Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 02/26] qcow2: Add refcount_bits to format-specific info Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 03/26] qcow2: Do not return new value after refcount update Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 04/26] qcow2: Only return status from qcow2_get_refcount Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 05/26] qcow2: Use unsigned addend for update_refcount() Max Reitz
2015-01-22 15:33   ` Eric Blake
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 06/26] qcow2: Use 64 bits for refcount values Max Reitz
2015-01-22 15:35   ` Eric Blake
2015-02-03 19:26   ` Kevin Wolf
2015-02-03 19:48     ` Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 07/26] qcow2: Respect error in qcow2_alloc_bytes() Max Reitz
2015-02-04 11:40   ` Kevin Wolf
2015-02-04 15:04     ` Max Reitz
2015-02-04 15:12       ` Kevin Wolf
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 08/26] qcow2: Refcount overflow and qcow2_alloc_bytes() Max Reitz
2015-02-04 11:55   ` Kevin Wolf
2015-02-04 15:33     ` Max Reitz
2015-02-04 16:10       ` Kevin Wolf
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 09/26] qcow2: Helper for refcount array reallocation Max Reitz
2015-02-04 13:21   ` Kevin Wolf
2015-02-04 15:57     ` Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 10/26] qcow2: Helper function for refcount modification Max Reitz
2015-02-04 16:06   ` Kevin Wolf
2015-02-04 17:12     ` Max Reitz [this message]
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 11/26] qcow2: More helpers " Max Reitz
2015-02-04 13:53   ` Kevin Wolf
2015-02-04 15:59     ` Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 12/26] qcow2: Open images with refcount order != 4 Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 13/26] qcow2: refcount_order parameter for qcow2_create2 Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 14/26] qcow2: Use symbolic macros in qcow2_amend_options Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 15/26] iotests: Prepare for refcount_bits option Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 16/26] qcow2: Allow creation with refcount order != 4 Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 17/26] progress: Allow regressing progress Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 18/26] block: Add opaque value to the amend CB Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 19/26] qcow2: Use error_report() in qcow2_amend_options() Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 20/26] qcow2: Use abort() instead of assert(false) Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 21/26] qcow2: Split upgrade/downgrade paths for amend Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 22/26] qcow2: Use intermediate helper CB " Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 23/26] qcow2: Add function for refcount order amendment Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 24/26] qcow2: Invoke refcount order amendment function Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 25/26] qcow2: Point to amend function in check Max Reitz
2014-12-15 12:50 ` [Qemu-devel] [PATCH v5 26/26] iotests: Add test for different refcount widths Max Reitz
2015-01-20 22:48 ` [Qemu-devel] [PATCH v5 00/26] qcow2: Support refcount orders != 4 Max Reitz

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=54D252FE.9030106@redhat.com \
    --to=mreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.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.