From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:57311) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCXse-0001Li-Nt for qemu-devel@nongnu.org; Tue, 27 Mar 2012 11:00:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCXsY-0007GH-Gj for qemu-devel@nongnu.org; Tue, 27 Mar 2012 11:00:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:21307) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCXsY-0007FV-8Y for qemu-devel@nongnu.org; Tue, 27 Mar 2012 11:00:10 -0400 From: Kevin Wolf Date: Tue, 27 Mar 2012 17:03:23 +0200 Message-Id: <1332860615-3047-5-git-send-email-kwolf@redhat.com> In-Reply-To: <1332860615-3047-1-git-send-email-kwolf@redhat.com> References: <1332860615-3047-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [RFC PATCH 04/16] qcow2: Fail write_compressed when overwriting data List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, stefanha@gmail.com qcow2_alloc_compressed_cluster_offset() already fails if the copied flag is set, because qcow2_write_compressed() doesn't perform COW as it would have to do to allow this. However, what we really want to check here is whether the cluster is allocated or not. With internal snapshots the copied flag may not be set on allocated clusters. Check the cluster offset instead. Signed-off-by: Kevin Wolf --- block/qcow2-cluster.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 9547fa9..b26028c 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -571,15 +571,14 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, return 0; } + /* Compression can't overwrite anything. Fail if the cluster was already + * allocated. */ cluster_offset = be64_to_cpu(l2_table[l2_index]); - if (cluster_offset & QCOW_OFLAG_COPIED) { + if (cluster_offset & L2E_OFFSET_MASK) { qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); return 0; } - if (cluster_offset) - qcow2_free_any_clusters(bs, cluster_offset, 1); - cluster_offset = qcow2_alloc_bytes(bs, compressed_size); if (cluster_offset < 0) { qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -- 1.7.6.5