From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55628) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLH18-0006ZZ-UU for qemu-devel@nongnu.org; Tue, 10 Feb 2015 15:02:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YLH12-0002Yr-60 for qemu-devel@nongnu.org; Tue, 10 Feb 2015 15:02:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39343) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLH11-0002YF-Sg for qemu-devel@nongnu.org; Tue, 10 Feb 2015 15:02:36 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1AK2Z8n026595 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 10 Feb 2015 15:02:35 -0500 From: Max Reitz Date: Tue, 10 Feb 2015 15:02:31 -0500 Message-Id: <1423598552-24301-2-git-send-email-mreitz@redhat.com> In-Reply-To: <1423598552-24301-1-git-send-email-mreitz@redhat.com> References: <1423598552-24301-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH 1/2] qcow2: Respect new_block in alloc_refcount_block() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Fam Zheng , Stefan Hajnoczi , Max Reitz When choosing a new place for the refcount table, alloc_refcount_block() tries to infer the number of clusters used so far from its argument cluster_index (which comes from the idea that if any cluster with an index greater than cluster_index was in use, the refcount table would have to be big enough already to describe cluster_index). However, there is a cluster that may be at or after cluster_index, and which is not covered by the refcount structures, and that is the new refcount block new_block. Therefore, it should be taken into account for the blocks_used calculation. Also, because new_block already describes (or is intended to describe) cluster_index, we may not put the new refcount structures there. Signed-off-by: Max Reitz --- block/qcow2-refcount.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 9b80ca7..b956365 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -326,8 +326,20 @@ static int alloc_refcount_block(BlockDriverState *bs, */ BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW); - /* Calculate the number of refcount blocks needed so far */ - uint64_t blocks_used = DIV_ROUND_UP(cluster_index, s->refcount_block_size); + /* Calculate the number of refcount blocks needed so far; this will be the + * basis for calculating the index of the first cluster used for the + * self-describing refcount structures which we are about to create. + * + * Because we reached this point, there cannot be any refcount entries for + * cluster_index or higher indices yet. However, because new_block has been + * allocated to describe that cluster (and it will assume this role later + * on), we cannot use that index; also, new_block may actually have a higher + * cluster index than cluster_index, so it needs to be taken into account + * here (and 1 needs to be added to its value because that cluster is used). + */ + uint64_t blocks_used = DIV_ROUND_UP(MAX(cluster_index + 1, + (new_block >> s->cluster_bits) + 1), + s->refcount_block_size); if (blocks_used > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) { return -EFBIG; -- 2.1.0