From 43a0cac4658bbee9c9e84554712a94daa092c1cd Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 16 Nov 2011 15:20:45 +0100 Subject: qcow2: Fix order of refcount updates in qcow2_snapshot_goto The refcount updates must be moved so that in the worst case we can get cluster leaks, but refcounts may never be too low. Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi --- block/qcow2-refcount.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'block/qcow2-refcount.c') diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 9605367777..2db2ede3d1 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -700,6 +700,10 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, l2_table = NULL; l1_table = NULL; l1_size2 = l1_size * sizeof(uint64_t); + + /* WARNING: qcow2_snapshot_goto relies on this function not using the + * l1_table_offset when it is the current s->l1_table_offset! Be careful + * when changing this! */ if (l1_table_offset != s->l1_table_offset) { if (l1_size2 != 0) { l1_table = g_malloc0(align_offset(l1_size2, 512)); @@ -819,7 +823,8 @@ fail: qcow2_cache_set_writethrough(bs, s->refcount_block_cache, old_refcount_writethrough); - if (l1_modified) { + /* Update L1 only if it isn't deleted anyway (addend = -1) */ + if (addend >= 0 && l1_modified) { for(i = 0; i < l1_size; i++) cpu_to_be64s(&l1_table[i]); if (bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table, -- cgit v1.2.3