All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>, qemu-block@nongnu.org
Cc: jsnow@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com
Subject: Re: [Qemu-devel] [PATCH 2/5] qcow2: Implement .bdrv_co_preadv()
Date: Fri, 3 Jun 2016 13:18:23 -0600	[thread overview]
Message-ID: <5751D7FF.8030504@redhat.com> (raw)
In-Reply-To: <1464974478-23598-3-git-send-email-kwolf@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 5051 bytes --]

On 06/03/2016 11:21 AM, Kevin Wolf wrote:
> Reading from qcow2 images is now byte granularity.
> 
> Most of the affected code in qcow2 actually gets simpler with this
> change. The only exception is encryption, which is fixed on 512 bytes
> blocks; in order to keep this working, bs->request_alignment is set for
> encrypted images.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/qcow2-cluster.c |  18 ++++-----
>  block/qcow2.c         | 108 +++++++++++++++++++++++++++-----------------------
>  block/qcow2.h         |   2 +-
>  3 files changed, 67 insertions(+), 61 deletions(-)
> 

> @@ -467,16 +468,16 @@ out:
>   * For a given offset of the disk image, find the cluster offset in
>   * qcow2 file. The offset is stored in *cluster_offset.
>   *
> - * on entry, *num is the number of contiguous sectors we'd like to
> + * on entry, *bytes is the number of contiguous bytes we'd like to

maybe s/number/maximum number/

>   * access following offset.
>   *
> - * on exit, *num is the number of contiguous sectors we can read.
> + * on exit, *bytes is the number of contiguous bytes we can read.

maybe s/we can read/with the same cluster type/

>   *
>   * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error
>   * cases.
>   */
>  int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
> -    int *num, uint64_t *cluster_offset)
> +                             unsigned int *bytes, uint64_t *cluster_offset)
>  {
>      BDRVQcow2State *s = bs->opaque;
>      unsigned int l2_index;
> @@ -485,12 +486,9 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
>      unsigned int offset_in_cluster, nb_clusters;
>      uint64_t bytes_available, bytes_needed;
>      int ret;
> -    unsigned int bytes;
> -
> -    bytes = *num * BDRV_SECTOR_SIZE;

One potential overflow gone...

>  
>      offset_in_cluster = offset_into_cluster(s, offset);
> -    bytes_needed = bytes + offset_in_cluster;
> +    bytes_needed = *bytes + offset_in_cluster;

...but not the other.  Looks like your callers limit their input 'bytes'
to at most INT_MAX, and therefore it happens to not overflow unsigned
int in practice, but you may want an assertion?

> +++ b/block/qcow2.c
> @@ -975,6 +975,9 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
>          }
>  
>          bs->encrypted = 1;
> +
> +        /* Encryption works on a sector granularity */
> +        bs->request_alignment = BDRV_SECTOR_SIZE;

Trivial conflict with my patch 5/5 that moves request_alignment into
BlockLimits (if we even want that, since I still have to find why my
patch makes qemu-iotests 77 hang)

>  
> -static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
> -                          int remaining_sectors, QEMUIOVector *qiov)
> +static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
> +                                        uint64_t bytes, QEMUIOVector *qiov,
> +                                        int flags)

Wait a minute.  .bdrv_co_preadv() takes uint64_t bytes, while
bdrv_co_preadv() takes only unsigned int bytes?  Eww.  We've got some
more scrubbing work to do.  At least it is going to get easier to
universally turn on full 64-bit byte interfaces everywhere, especially
once my patches for auto-fragmenting at max_transfer_length land (which
in turn won't be posted before your conversion of bdrv_aligned_preadv()
to a byte interface).  So no impact to this patch.

>  {
>      BDRVQcow2State *s = bs->opaque;
> -    int index_in_cluster, n1;
> +    int offset_in_cluster, n1;
>      int ret;
> -    int cur_nr_sectors; /* number of sectors in current iteration */
> +    unsigned int cur_bytes; /* number of sectors in current iteration */

comment is stale now

>      uint64_t cluster_offset = 0;
>      uint64_t bytes_done = 0;
>      QEMUIOVector hd_qiov;
> @@ -1389,26 +1402,24 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
>  
>      qemu_co_mutex_lock(&s->lock);
>  
> -    while (remaining_sectors != 0) {
> +    while (bytes != 0) {
>  
>          /* prepare next request */
> -        cur_nr_sectors = remaining_sectors;
> +        cur_bytes = MIN(bytes, INT_MAX);
>          if (s->cipher) {
> -            cur_nr_sectors = MIN(cur_nr_sectors,
> -                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
> +            cur_bytes = MIN(cur_bytes,
> +                            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);

Again, my work on auto-fragmenting at the block layer should make it so
that we can eventually further simplify this part to just assert that
bytes doesn't exceed max_transfer_length, rather than having to fragment
it at INT_MAX ourselves.

Couple of tweaks to fix as pointed out above, but mostly looks sane.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

  reply	other threads:[~2016-06-03 19:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-03 17:21 [Qemu-devel] [PATCH 0/5] qcow2: Implement .bdrv_co_preadv/pwritev Kevin Wolf
2016-06-03 17:21 ` [Qemu-devel] [PATCH 1/5] qcow2: Work with bytes in qcow2_get_cluster_offset() Kevin Wolf
2016-06-03 17:44   ` Eric Blake
2016-06-03 17:21 ` [Qemu-devel] [PATCH 2/5] qcow2: Implement .bdrv_co_preadv() Kevin Wolf
2016-06-03 19:18   ` Eric Blake [this message]
2016-06-03 17:21 ` [Qemu-devel] [PATCH 3/5] qcow2: Make copy_sectors() byte based Kevin Wolf
2016-06-03 19:34   ` Eric Blake
2016-06-03 17:21 ` [Qemu-devel] [PATCH 4/5] qcow2: Use bytes instead of sectors for QCowL2Meta Kevin Wolf
2016-06-03 19:44   ` Eric Blake
2016-06-03 17:21 ` [Qemu-devel] [PATCH 5/5] qcow2: Implement .bdrv_co_pwritev Kevin Wolf
2016-06-03 20:13   ` Eric Blake
2016-06-06 14:50     ` Kevin Wolf
2016-06-03 22:59   ` Eric Blake

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=5751D7FF.8030504@redhat.com \
    --to=eblake@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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.