qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@gmail.com>
To: Max Reitz <mreitz@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3 07/22] qcow2: Helper function for refcount modification
Date: Fri, 28 Nov 2014 11:26:41 +0000	[thread overview]
Message-ID: <20141128112641.GD13631@stefanha-thinkpad.redhat.com> (raw)
In-Reply-To: <54774424.80200@redhat.com>

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

On Thu, Nov 27, 2014 at 04:32:52PM +0100, Max Reitz wrote:
> On 2014-11-27 at 16:21, Stefan Hajnoczi wrote:
> >On Thu, Nov 20, 2014 at 06:06:23PM +0100, Max Reitz wrote:
> >>@@ -583,7 +608,12 @@ 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 (refcount < 0) {
> >>+            ret = -ERANGE;
> >>+            goto fail;
> >>+        }
> >Here again.
> >
> >>@@ -1206,11 +1236,14 @@ static int inc_refcounts(BlockDriverState *bs,
> >>              }
> >>          }
> >>-        if (++(*refcount_table)[k] == 0) {
> >>+        refcount = s->get_refcount(*refcount_table, k);
> >Here the refcount < 0 check is missing.  That's why it would be simpler
> >to eliminate the refcount < 0 case entirely.
> 
> It's not missing. This is part of the refcount check, as are all the
> following ("in other places"). The refcount check builds a refcount array in
> memory all by itself, so it knows for sure there are no overflows. The line
> which you omitted directly after this clips the refcount values against
> s->refcount_max which is INT64_MAX for 64-bit refcounts.
> 
> Therefore, no overflows possible in the refcount checking functions, because
> the refcount checking functions don't introduce the overflows themselves.
> The other overflow checks are only in place to reject faulty images provided
> from the outside.

I see, that makes sense.

> >>@@ -1726,7 +1761,7 @@ static void compare_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
> >>              continue;
> >>          }
> >>-        refcount2 = refcount_table[i];
> >>+        refcount2 = s->get_refcount(refcount_table, i);
> >Missing here too and in other places.
> >
> >>+typedef uint64_t Qcow2GetRefcountFunc(const void *refcount_array,
> >>+                                      uint64_t index);
> >Should the return type be int64_t?
> 
> No. If it was, we'd have to check for errors every time we call it, but it
> cannot return errors (well, if we let it return uint64_t, it might return
> -ERANGE, but that's exactly what I don't want). Therefore, let it return
> uint64_t so we know this function cannot fail.
> 
> >>+typedef void Qcow2SetRefcountFunc(void *refcount_array,
> >>+                                  uint64_t index, uint64_t value);
> >Should value's type be int64_t?  Just because the type is unsigned
> >doesn't make (uint64_t)-1ULL a valid value.
> 
> Actually, it does. It's just that the implementation provided here does not
> support it.
> 
> Since there is an assertion against that case in the 64-bit implementation
> for this function, I don't have a problem with using int64_t here, though.
> But that would break symmetry with Qcow2GetRefcountFunc(), and I do have a
> reason there not to return a signed value, as explained above.

Okay, so uint64_t is really a different type - it's the qcow2 spec
64-bit refcount.  int64_t is the QEMU implementation's internal
representation.

This seems error-prone to me.  Maybe comments would have helped, but
it's best to eliminate the problem entirely.  Why not bite the bullet
and fix up qcow2?

There are two external function prototypes that need to be changed:

int64_t qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index);

int64_t qcow2_update_cluster_refcount(BlockDriverState *bs,
                                      int64_t cluster_index, int addend,
                                      enum qcow2_discard_type type);

/* Returns 0 on success, -errno on failure */
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
                       uint64_t *refcount);
int qcow2_update_cluster_refcount(BlockDriverState *bs,
                                  int64_t cluster_index, int addend,
                                  enum qcow2_discard_type type,
				  uint64_t *refcount);

Have I missed a fundamental reason why the implementation's internal
refcount type cannot be changed from int64_t to uint64_t?

It would keep the code complexity down and reduce errors.

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

  reply	other threads:[~2014-11-28 11:27 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-20 17:06 [Qemu-devel] [PATCH v3 00/22] qcow2: Support refcount orders != 4 Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 01/22] qcow2: Add two new fields to BDRVQcowState Max Reitz
2014-11-27 13:49   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 02/22] qcow2: Add refcount_width to format-specific info Max Reitz
2014-11-27 13:47   ` Stefan Hajnoczi
2014-11-27 14:19     ` Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 03/22] qcow2: Use 64 bits for refcount values Max Reitz
2014-11-27 13:49   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 04/22] qcow2: Respect error in qcow2_alloc_bytes() Max Reitz
2014-11-27 14:56   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 05/22] qcow2: Refcount overflow and qcow2_alloc_bytes() Max Reitz
2014-11-27 14:59   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 06/22] qcow2: Helper for refcount array reallocation Max Reitz
2014-11-20 21:43   ` Eric Blake
2014-11-21  8:45     ` Max Reitz
2014-11-27 15:09   ` Stefan Hajnoczi
2014-11-27 15:11     ` Max Reitz
2014-11-28 10:46       ` Stefan Hajnoczi
2014-12-02  9:52         ` Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 07/22] qcow2: Helper function for refcount modification Max Reitz
2014-11-20 22:13   ` Eric Blake
2014-11-27 15:21   ` Stefan Hajnoczi
2014-11-27 15:32     ` Max Reitz
2014-11-28 11:26       ` Stefan Hajnoczi [this message]
2014-12-02  9:54         ` Max Reitz
2014-11-28 11:11   ` Stefan Hajnoczi
2014-12-02  9:57     ` Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 08/22] qcow2: More helpers " Max Reitz
2014-11-20 22:20   ` Eric Blake
2014-11-27 15:31   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 09/22] qcow2: Open images with refcount order != 4 Max Reitz
2014-11-27 15:32   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 10/22] qcow2: refcount_order parameter for qcow2_create2 Max Reitz
2014-11-20 22:23   ` Eric Blake
2014-11-27 16:25   ` Stefan Hajnoczi
2014-12-02  9:56     ` Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 11/22] iotests: Prepare for refcount_width option Max Reitz
2014-11-28 13:06   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 12/22] qcow2: Allow creation with refcount order != 4 Max Reitz
2014-11-28 13:15   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 13/22] progress: Allow regressing progress Max Reitz
2014-11-20 22:29   ` Eric Blake
2014-11-28 13:17   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 14/22] block: Add opaque value to the amend CB Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 15/22] qcow2: Use error_report() in qcow2_amend_options() Max Reitz
2014-11-28 13:21   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 16/22] qcow2: Use abort() instead of assert(false) Max Reitz
2014-11-28 13:21   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 17/22] qcow2: Split upgrade/downgrade paths for amend Max Reitz
2014-11-28 13:22   ` Stefan Hajnoczi
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 18/22] qcow2: Use intermediate helper CB " Max Reitz
2014-11-28 14:13   ` Stefan Hajnoczi
2014-12-02  9:59     ` Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 19/22] qcow2: Add function for refcount order amendment Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 20/22] qcow2: Invoke refcount order amendment function Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 21/22] qcow2: Point to amend function in check Max Reitz
2014-11-20 17:06 ` [Qemu-devel] [PATCH v3 22/22] iotests: Add test for different refcount widths Max Reitz
2014-11-20 23:04   ` 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=20141128112641.GD13631@stefanha-thinkpad.redhat.com \
    --to=stefanha@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).