From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:34902) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R323x-0001Cf-UX for qemu-devel@nongnu.org; Mon, 12 Sep 2011 04:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R323w-0006N9-LR for qemu-devel@nongnu.org; Mon, 12 Sep 2011 04:40:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R323w-0006Mt-CO for qemu-devel@nongnu.org; Mon, 12 Sep 2011 04:40:20 -0400 Message-ID: <4E6DC623.8020707@redhat.com> Date: Mon, 12 Sep 2011 10:43:15 +0200 From: Kevin Wolf MIME-Version: 1.0 References: <1315643036-22322-1-git-send-email-freddy77@gmail.com> In-Reply-To: <1315643036-22322-1-git-send-email-freddy77@gmail.com> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] qcow2: fix range check List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Frediano Ziglio Cc: qemu-devel@nongnu.org Am 10.09.2011 10:23, schrieb Frediano Ziglio: > QCowL2Meta::offset is not cluster aligned but only sector aligned > however nb_clusters count cluster from cluster start. > This fix range check. Note that old code have no corruption issues > related to this check cause it only cause intersection to occur > when shouldn't. Are you sure? See below. (I think it doesn't corrupt the image, but for a different reason) > > Signed-off-by: Frediano Ziglio > --- > block/qcow2-cluster.c | 14 +++++++------- > 1 files changed, 7 insertions(+), 7 deletions(-) > > diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c > index 428b5ad..2f76311 100644 > --- a/block/qcow2-cluster.c > +++ b/block/qcow2-cluster.c > @@ -776,17 +776,17 @@ again: > */ > QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) { > > - uint64_t end_offset = offset + nb_clusters * s->cluster_size; > - uint64_t old_offset = old_alloc->offset; > - uint64_t old_end_offset = old_alloc->offset + > - old_alloc->nb_clusters * s->cluster_size; > + uint64_t start = offset >> s->cluster_bits; > + uint64_t end = start + nb_clusters; > + uint64_t old_start = old_alloc->offset >> s->cluster_bits; > + uint64_t old_end = old_start + old_alloc->nb_clusters; > > - if (end_offset < old_offset || offset > old_end_offset) { > + if (end < old_start || start > old_end) { > /* No intersection */ Consider request A from 0x0 + 0x1000 bytes and request B from 0x2000 + 0x1000 bytes. Both touch the same cluster and therefore should be serialised, but 0x2000 > 0x1000, so we decided here that there is no intersection and we don't have to care. Note that this doesn't corrupt the image, qcow2 can handle parallel requests allocating the same cluster. In qcow2_alloc_cluster_link_l2() we get an additional COW operation, so performance will be hurt, but correctness is maintained. > } else { > - if (offset < old_offset) { > + if (start < old_start) { > /* Stop at the start of a running allocation */ > - nb_clusters = (old_offset - offset) >> s->cluster_bits; > + nb_clusters = old_start - start; > } else { > nb_clusters = 0; > } Anyway, the patch looks good. Applied to the block branch. Kevin