15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Block driver for the QCOW version 2 format 35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 2004-2006 Fabrice Bellard 55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Permission is hereby granted, free of charge, to any person obtaining a copy 75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * of this software and associated documentation files (the "Software"), to deal 85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * in the Software without restriction, including without limitation the rights 95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * copies of the Software, and to permit persons to whom the Software is 115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * furnished to do so, subject to the following conditions: 125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The above copyright notice and this permission notice shall be included in 145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * all copies or substantial portions of the Software. 155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE. 235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block_int.h" 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block/qcow2.h" 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size); 30cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, 315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t offset, int64_t length, 325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int addend); 335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 34cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 35cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int cache_refcount_updates = 0; 36cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 37cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int write_refcount_block(BlockDriverState *bs) 38cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 39cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BDRVQcowState *s = bs->opaque; 40cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t size = s->cluster_size; 41cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 42cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (s->refcount_block_cache_offset == 0) { 43cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 44cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 45cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 46cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE); 47cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pwrite_sync(bs->file, s->refcount_block_cache_offset, 48cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_block_cache, size) < 0) 49cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner { 50cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -EIO; 51cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 52cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 53cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 54cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 55cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*********************************************************/ 575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* refcount handling */ 585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qcow2_refcount_init(BlockDriverState *bs) 605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret, refcount_table_size2, i; 635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_block_cache = qemu_malloc(s->cluster_size); 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t); 665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table = qemu_malloc(refcount_table_size2); 675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->refcount_table_size > 0) { 68cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD); 69cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pread(bs->file, s->refcount_table_offset, 705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table, refcount_table_size2); 715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret != refcount_table_size2) 725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < s->refcount_table_size; i++) 745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&s->refcount_table[i]); 755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fail: 785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOMEM; 795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_refcount_close(BlockDriverState *bs) 825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->refcount_block_cache); 855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->refcount_table); 865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int load_refcount_block(BlockDriverState *bs, 905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t refcount_block_offset) 915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 94cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 95cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (cache_refcount_updates) { 96cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = write_refcount_block(bs); 97cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 98cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 99cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 100cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 101cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 102cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD); 103cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pread(bs->file, refcount_block_offset, s->refcount_block_cache, 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_size); 105cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 106cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 107cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 108cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_block_cache_offset = refcount_block_offset; 1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 113cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 114cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Returns the refcount of the cluster given by its index. Any non-negative 115cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * return value is the refcount of the cluster, negative values are -errno 116cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * and indicate an error. 117cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int get_refcount(BlockDriverState *bs, int64_t cluster_index) 1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int refcount_table_index, block_index; 1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t refcount_block_offset; 123cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); 1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount_table_index >= s->refcount_table_size) 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_block_offset = s->refcount_table[refcount_table_index]; 1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!refcount_block_offset) 1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount_block_offset != s->refcount_block_cache_offset) { 1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* better than nothing: return allocated if read error */ 133cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = load_refcount_block(bs, refcount_block_offset); 134cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 135cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 136cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner block_index = cluster_index & 1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return be16_to_cpu(s->refcount_block_cache[block_index]); 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 143cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 144cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Rounds the refcount table size up to avoid growing the table for each single 145cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * refcount block that is allocated. 146cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 147cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic unsigned int next_refcount_table_size(BDRVQcowState *s, 148cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner unsigned int min_size) 1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 150cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner unsigned int min_clusters = (min_size >> (s->cluster_bits - 3)) + 1; 151cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner unsigned int refcount_table_clusters = 152cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner MAX(1, s->refcount_table_size >> (s->cluster_bits - 3)); 1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 154cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner while (min_clusters > refcount_table_clusters) { 155cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2; 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 158cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return refcount_table_clusters << (s->cluster_bits - 3); 1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 162cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* Checks if two offsets are described by the same refcount block */ 163cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int in_same_refcount_block(BDRVQcowState *s, uint64_t offset_a, 164cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t offset_b) 165cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 166cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t block_a = offset_a >> (2 * s->cluster_bits - REFCOUNT_SHIFT); 167cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t block_b = offset_b >> (2 * s->cluster_bits - REFCOUNT_SHIFT); 168cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 169cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return (block_a == block_b); 170cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 171cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 172cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 173cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Loads a refcount block. If it doesn't exist yet, it is allocated first 174cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * (including growing the refcount table if needed). 175cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 176cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Returns the offset of the refcount block on success or -errno in error case 177cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index) 1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 181cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner unsigned int refcount_table_index; 182cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 184cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC); 185cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 186cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Find the refcount block for the given cluster */ 1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); 188cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 189cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount_table_index < s->refcount_table_size) { 190cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 191cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t refcount_block_offset = 192cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table[refcount_table_index]; 193cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 194cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* If it's already there, we're done */ 195cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount_block_offset) { 196cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount_block_offset != s->refcount_block_cache_offset) { 197cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = load_refcount_block(bs, refcount_block_offset); 198cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 199cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 200cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 201cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 202cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return refcount_block_offset; 203cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 204cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 205cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 206cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* 207cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If we came here, we need to allocate something. Something is at least 208cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * a cluster for the new refcount block. It may also include a new refcount 209cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * table if the old refcount table is too small. 210cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 211cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Note that allocating clusters here needs some special care: 212cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 213cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * - We can't use the normal qcow2_alloc_clusters(), it would try to 214cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * increase the refcount and very likely we would end up with an endless 215cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * recursion. Instead we must place the refcount blocks in a way that 216cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * they can describe them themselves. 217cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 218cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * - We need to consider that at this point we are inside update_refcounts 219cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * and doing the initial refcount increase. This means that some clusters 220cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * have already been allocated by the caller, but their refcount isn't 221cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * accurate yet. free_cluster_index tells us where this allocation ends 222cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * as long as we don't overwrite it by freeing clusters. 223cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 224cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * - alloc_clusters_noref and qcow2_free_clusters may load a different 225cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * refcount block into the cache 226cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 227cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 228cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (cache_refcount_updates) { 229cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = write_refcount_block(bs); 230cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 232cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 235cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Allocate the refcount block itself and mark it as used */ 236cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int64_t new_block = alloc_clusters_noref(bs, s->cluster_size); 237cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (new_block < 0) { 238cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return new_block; 239cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 240cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 241cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef DEBUG_ALLOC2 242cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64 243cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner " at %" PRIx64 "\n", 244cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount_table_index, cluster_index << s->cluster_bits, new_block); 245cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif 246cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 247cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) { 248cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Zero the new refcount block before updating it */ 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(s->refcount_block_cache, 0, s->cluster_size); 250cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_block_cache_offset = new_block; 251cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 252cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* The block describes itself, need to update the cache */ 253cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int block_index = (new_block >> s->cluster_bits) & 254cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); 255cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_block_cache[block_index] = cpu_to_be16(1); 2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 257cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Described somewhere else. This can recurse at most twice before we 258cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * arrive at a block that describes itself. */ 259cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = update_refcount(bs, new_block, s->cluster_size, 1); 260cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 261cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_block; 262cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 263cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 264cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Initialize the new refcount block only after updating its refcount, 265cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * update_refcount uses the refcount cache itself */ 266cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memset(s->refcount_block_cache, 0, s->cluster_size); 267cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_block_cache_offset = new_block; 268cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 269cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 270cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Now the new refcount block needs to be written to disk */ 271cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE); 272cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, new_block, s->refcount_block_cache, 273cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->cluster_size); 274cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 275cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_block; 276cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 277cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 278cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* If the refcount table is big enough, just hook the block up there */ 279cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount_table_index < s->refcount_table_size) { 280cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t data64 = cpu_to_be64(new_block); 281cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP); 282cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, 283cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_offset + refcount_table_index * sizeof(uint64_t), 284cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &data64, sizeof(data64)); 285cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 286cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_block; 2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 288cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 289cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table[refcount_table_index] = new_block; 290cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return new_block; 291cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 292cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 293cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* 294cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If we come here, we need to grow the refcount table. Again, a new 295cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * refcount table needs some space and we can't simply allocate to avoid 296cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * endless recursion. 297cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 298cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Therefore let's grab new refcount blocks at the end of the image, which 299cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * will describe themselves and the new refcount table. This way we can 300cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * reference them only in the new table and do the switch to the new 301cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * refcount table at once without producing an inconsistent state in 302cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * between. 303cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 304cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW); 305cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 306cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Calculate the number of refcount blocks needed so far */ 307cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT); 308cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t blocks_used = (s->free_cluster_index + 309cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount_block_clusters - 1) / refcount_block_clusters; 310cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 311cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* And now we need at least one block more for the new metadata */ 312cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t table_size = next_refcount_table_size(s, blocks_used + 1); 313cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t last_table_size; 314cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t blocks_clusters; 315cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner do { 316cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t table_clusters = size_to_clusters(s, table_size); 317cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner blocks_clusters = 1 + 318cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ((table_clusters + refcount_block_clusters - 1) 319cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner / refcount_block_clusters); 320cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t meta_clusters = table_clusters + blocks_clusters; 321cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 322cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner last_table_size = table_size; 323cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner table_size = next_refcount_table_size(s, blocks_used + 324cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ((meta_clusters + refcount_block_clusters - 1) 325cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner / refcount_block_clusters)); 326cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 327cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } while (last_table_size != table_size); 328cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 329cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef DEBUG_ALLOC2 330cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n", 331cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_size, table_size); 332cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif 333cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 334cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Create the new refcount table and blocks */ 335cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t meta_offset = (blocks_used * refcount_block_clusters) * 336cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->cluster_size; 337cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size; 338cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint16_t *new_blocks = qemu_mallocz(blocks_clusters * s->cluster_size); 339cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t *new_table = qemu_mallocz(table_size * sizeof(uint64_t)); 340cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 341cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner assert(meta_offset >= (s->free_cluster_index * s->cluster_size)); 342cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 343cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Fill the new refcount table */ 344cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memcpy(new_table, s->refcount_table, 345cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_size * sizeof(uint64_t)); 346cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner new_table[refcount_table_index] = new_block; 347cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 348cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int i; 349cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for (i = 0; i < blocks_clusters; i++) { 350cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner new_table[blocks_used + i] = meta_offset + (i * s->cluster_size); 351cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 352cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 353cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Fill the refcount blocks */ 354cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); 355cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int block = 0; 356cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for (i = 0; i < table_clusters + blocks_clusters; i++) { 357cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner new_blocks[block++] = cpu_to_be16(1); 358cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 359cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 360cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Write refcount blocks to disk */ 361cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); 362cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks, 363cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner blocks_clusters * s->cluster_size); 364cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qemu_free(new_blocks); 365cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 366cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_table; 367cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 368cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 369cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Write refcount table to disk */ 370cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for(i = 0; i < table_size; i++) { 371cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cpu_to_be64s(&new_table[i]); 372cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 373cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 374cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE); 375cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, table_offset, new_table, 376cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner table_size * sizeof(uint64_t)); 377cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 378cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_table; 379cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 380cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 381cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for(i = 0; i < table_size; i++) { 382cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cpu_to_be64s(&new_table[i]); 383cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 384cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 385cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Hook up the new refcount table in the qcow2 header */ 386cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint8_t data[12]; 387cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cpu_to_be64w((uint64_t*)data, table_offset); 388cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cpu_to_be32w((uint32_t*)(data + 8), table_clusters); 389cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE); 390cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset), 391cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner data, sizeof(data)); 392cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 393cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_table; 3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 396cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* And switch it in memory */ 397cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t old_table_offset = s->refcount_table_offset; 398cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t old_table_size = s->refcount_table_size; 399cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 400cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qemu_free(s->refcount_table); 401cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table = new_table; 402cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_size = table_size; 403cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_offset = table_offset; 404cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 405cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Free old table. Remember, we must not change free_cluster_index */ 406cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t old_free_cluster_index = s->free_cluster_index; 407cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t)); 408cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->free_cluster_index = old_free_cluster_index; 409cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 410cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = load_refcount_block(bs, new_block); 411cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 412cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail_block; 413cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 414cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 415cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return new_block; 416cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 417cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail_table: 418cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qemu_free(new_table); 419cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail_block: 420cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_block_cache_offset = 0; 421cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define REFCOUNTS_PER_SECTOR (512 >> REFCOUNT_SHIFT) 425cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int write_refcount_block_entries(BlockDriverState *bs, 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t refcount_block_offset, int first_index, int last_index) 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 428cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BDRVQcowState *s = bs->opaque; 4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size_t size; 430cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 431cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 432cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (cache_refcount_updates) { 433cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 434cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 435cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 436cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (first_index < 0) { 437cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 438cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner first_index &= ~(REFCOUNTS_PER_SECTOR - 1); 4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last_index = (last_index + REFCOUNTS_PER_SECTOR) 4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner & ~(REFCOUNTS_PER_SECTOR - 1); 4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size = (last_index - first_index) << REFCOUNT_SHIFT; 445cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 446cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART); 447cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, 4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_block_offset + (first_index << REFCOUNT_SHIFT), 449cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &s->refcount_block_cache[first_index], size); 450cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 451cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: cache several refcount block clusters ? */ 458cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, 459cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int64_t offset, int64_t length, int addend) 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t start, last, cluster_offset; 4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t refcount_block_offset = 0; 4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t table_index = -1, old_table_index; 4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int first_index = -1, last_index = -1; 466cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_ALLOC2 469cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n", 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset, length, addend); 4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 472cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (length < 0) { 4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EINVAL; 474cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (length == 0) { 475cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 476cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 477cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner start = offset & ~(s->cluster_size - 1); 4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last = (offset + length - 1) & ~(s->cluster_size - 1); 4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(cluster_offset = start; cluster_offset <= last; 4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset += s->cluster_size) 4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int block_index, refcount; 4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t cluster_index = cluster_offset >> s->cluster_bits; 485cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int64_t new_block; 4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Only write refcount block to disk when we are done with it */ 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner old_table_index = table_index; 4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); 4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((old_table_index >= 0) && (table_index != old_table_index)) { 4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 492cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = write_refcount_block_entries(bs, refcount_block_offset, 493cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner first_index, last_index); 494cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 495cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner first_index = -1; 4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last_index = -1; 5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Load the refcount block and allocate it if needed */ 503cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner new_block = alloc_refcount_block(bs, cluster_index); 504cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (new_block < 0) { 505cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = new_block; 506cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 508cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount_block_offset = new_block; 5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* we can update the count and save it */ 5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner block_index = cluster_index & 5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); 5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (first_index == -1 || block_index < first_index) { 5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner first_index = block_index; 5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (block_index > last_index) { 5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last_index = block_index; 5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = be16_to_cpu(s->refcount_block_cache[block_index]); 5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount += addend; 522cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0 || refcount > 0xffff) { 523cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -EINVAL; 524cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 525cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount == 0 && cluster_index < s->free_cluster_index) { 5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_cluster_index = cluster_index; 5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_block_cache[block_index] = cpu_to_be16(refcount); 5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 532cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = 0; 533cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail: 534cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Write last changed block to disk */ 5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount_block_offset != 0) { 537cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int wret; 538cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner wret = write_refcount_block_entries(bs, refcount_block_offset, 539cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner first_index, last_index); 540cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (wret < 0) { 541cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret < 0 ? ret : wret; 5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 545cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* 546cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Try do undo any updates if an error is returned (This may succeed in 547cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * some cases like ENOSPC for allocating a new refcount block) 548cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 549cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 550cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int dummy; 551cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner dummy = update_refcount(bs, offset, cluster_offset - offset, -addend); 552cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 553cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 554cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 557cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 558cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Increases or decreases the refcount of a given cluster by one. 559cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * addend must be 1 or -1. 560cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 561cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If the return value is non-negative, it is the new refcount of the cluster. 562cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If it is negative, it is -errno and indicates an error. 563cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int update_cluster_refcount(BlockDriverState *bs, 5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t cluster_index, 5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int addend) 5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend); 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return get_refcount(bs, cluster_index); 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*********************************************************/ 5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* cluster allocation functions */ 5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* return < 0 if error */ 5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size) 5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 590cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int i, nb_clusters, refcount; 5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_clusters = size_to_clusters(s, size); 5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerretry: 5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < nb_clusters; i++) { 595cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int64_t next_cluster_index = s->free_cluster_index++; 596cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount = get_refcount(bs, next_cluster_index); 597cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 598cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0) { 599cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return refcount; 600cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (refcount != 0) { 6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto retry; 602cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_ALLOC2 605cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n", 6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size, 6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (s->free_cluster_index - nb_clusters) << s->cluster_bits); 6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (s->free_cluster_index - nb_clusters) << s->cluster_bits; 6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size) 6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t offset; 615cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 617cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC); 6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = alloc_clusters_noref(bs, size); 619cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (offset < 0) { 620cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return offset; 621cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 622cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 623cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = update_refcount(bs, offset, size, 1); 624cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 625cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 626cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return offset; 6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* only used to allocate compressed sectors. We try to allocate 6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner contiguous sectors. size must be <= cluster_size */ 6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t qcow2_alloc_bytes(BlockDriverState *bs, int size) 6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t offset, cluster_offset; 6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int free_in_cluster; 6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 638cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES); 6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner assert(size > 0 && size <= s->cluster_size); 6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->free_byte_offset == 0) { 6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_byte_offset = qcow2_alloc_clusters(bs, s->cluster_size); 642cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (s->free_byte_offset < 0) { 643cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return s->free_byte_offset; 644cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner redo: 6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner free_in_cluster = s->cluster_size - 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (s->free_byte_offset & (s->cluster_size - 1)); 6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (size <= free_in_cluster) { 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* enough space in current cluster */ 6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = s->free_byte_offset; 6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_byte_offset += size; 6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner free_in_cluster -= size; 6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (free_in_cluster == 0) 6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_byte_offset = 0; 6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((offset & (s->cluster_size - 1)) != 0) 6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner update_cluster_refcount(bs, offset >> s->cluster_bits, 1); 6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = qcow2_alloc_clusters(bs, s->cluster_size); 660cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (offset < 0) { 661cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return offset; 662cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1); 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((cluster_offset + s->cluster_size) == offset) { 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* we are lucky: contiguous data */ 6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = s->free_byte_offset; 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner update_cluster_refcount(bs, offset >> s->cluster_bits, 1); 6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_byte_offset += size; 6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->free_byte_offset = offset; 6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto redo; 6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return offset; 6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_free_clusters(BlockDriverState *bs, 6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t offset, int64_t size) 6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 680cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 681cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 682cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_FREE); 683cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = update_refcount(bs, offset, size, -1); 684cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 685cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret)); 686cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* TODO Remember the clusters to free them later and avoid leaking */ 687cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * free_any_clusters 6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * free clusters according to its type: compressed or not 6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_free_any_clusters(BlockDriverState *bs, 6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t cluster_offset, int nb_clusters) 6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* free the cluster */ 7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (cluster_offset & QCOW_OFLAG_COMPRESSED) { 7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_csectors; 7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_csectors = ((cluster_offset >> s->csize_shift) & 7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->csize_mask) + 1; 7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_free_clusters(bs, 7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (cluster_offset & s->cluster_offset_mask) & ~511, 7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_csectors * 512); 7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_free_clusters(bs, cluster_offset, nb_clusters << s->cluster_bits); 7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*********************************************************/ 7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* snapshots and image creation */ 7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_create_refcount_update(QCowCreateState *s, int64_t offset, 7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t size) 7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int refcount; 7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t start, last, cluster_offset; 7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t *p; 7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner start = offset & ~(s->cluster_size - 1); 7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last = (offset + size - 1) & ~(s->cluster_size - 1); 7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(cluster_offset = start; cluster_offset <= last; 7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset += s->cluster_size) { 7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner p = &s->refcount_block[cluster_offset >> s->cluster_bits]; 7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = be16_to_cpu(*p); 7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount++; 7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *p = cpu_to_be16(refcount); 7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* update the refcounts of snapshots and the copied flag */ 7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qcow2_update_snapshot_refcount(BlockDriverState *bs, 7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t l1_table_offset, int l1_size, int addend) 7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated; 7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t old_offset, old_l2_offset; 7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int l2_size, i, j, l1_modified, l2_modified, nb_csectors, refcount; 7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_l2_cache_reset(bs); 754cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cache_refcount_updates = 1; 7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_table = NULL; 7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_table = NULL; 7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_size2 = l1_size * sizeof(uint64_t); 7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l1_table_offset != s->l1_table_offset) { 760cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (l1_size2 != 0) { 761cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table = qemu_mallocz(align_offset(l1_size2, 512)); 762cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else { 763cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table = NULL; 764cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_allocated = 1; 766cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, l1_table_offset, 7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_table, l1_size2) != l1_size2) 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0;i < l1_size; i++) 7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&l1_table[i]); 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner assert(l1_size == s->l1_size); 7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_table = s->l1_table; 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_allocated = 0; 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_size = s->l2_size * sizeof(uint64_t); 7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_table = qemu_malloc(l2_size); 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_modified = 0; 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < l1_size; i++) { 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_offset = l1_table[i]; 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l2_offset) { 7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner old_l2_offset = l2_offset; 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_offset &= ~QCOW_OFLAG_COPIED; 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_modified = 0; 786cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size) 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(j = 0; j < s->l2_size; j++) { 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = be64_to_cpu(l2_table[j]); 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset != 0) { 7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner old_offset = offset; 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset &= ~QCOW_OFLAG_COPIED; 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset & QCOW_OFLAG_COMPRESSED) { 7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_csectors = ((offset >> s->csize_shift) & 7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->csize_mask) + 1; 796cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (addend != 0) { 797cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 798cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = update_refcount(bs, 799cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner (offset & s->cluster_offset_mask) & ~511, 800cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner nb_csectors * 512, addend); 801cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 802cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 803cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 804cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* compressed clusters are never modified */ 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = 2; 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (addend != 0) { 8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = update_cluster_refcount(bs, offset >> s->cluster_bits, addend); 8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = get_refcount(bs, offset >> s->cluster_bits); 8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 813cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 814cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0) { 815cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 816cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount == 1) { 8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset |= QCOW_OFLAG_COPIED; 8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset != old_offset) { 8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_table[j] = cpu_to_be64(offset); 8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_modified = 1; 8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l2_modified) { 829cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pwrite_sync(bs->file, 830cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l2_offset, l2_table, l2_size) < 0) 8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (addend != 0) { 8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend); 8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = get_refcount(bs, l2_offset >> s->cluster_bits); 8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 839cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0) { 840cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 841cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (refcount == 1) { 8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_offset |= QCOW_OFLAG_COPIED; 8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l2_offset != old_l2_offset) { 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_table[i] = l2_offset; 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_modified = 1; 8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l1_modified) { 8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < l1_size; i++) 8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_to_be64s(&l1_table[i]); 853cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table, 854cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_size2) < 0) 8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < l1_size; i++) 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&l1_table[i]); 8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l1_allocated) 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l1_table); 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l2_table); 862cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cache_refcount_updates = 0; 863cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner write_refcount_block(bs); 8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fail: 8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l1_allocated) 8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l1_table); 8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l2_table); 869cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cache_refcount_updates = 0; 870cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner write_refcount_block(bs); 8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*********************************************************/ 8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* refcount checking functions */ 8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Increases the refcount for a range of clusters in a given refcount table. 8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This is used to construct a temporary refcount table out of L1 and L2 tables 8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * which can be compared the the refcount table saved in the image. 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 887cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Modifies the number of errors in res. 8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 889cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic void inc_refcounts(BlockDriverState *bs, 890cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BdrvCheckResult *res, 8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t *refcount_table, 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int refcount_table_size, 8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t offset, int64_t size) 8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t start, last, cluster_offset; 8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int k; 8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (size <= 0) 900cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return; 9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner start = offset & ~(s->cluster_size - 1); 9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner last = (offset + size - 1) & ~(s->cluster_size - 1); 9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(cluster_offset = start; cluster_offset <= last; 9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset += s->cluster_size) { 9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner k = cluster_offset >> s->cluster_bits; 907cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (k < 0) { 9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR: invalid cluster offset=0x%" PRIx64 "\n", 9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset); 910cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 911cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (k >= refcount_table_size) { 912cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Warning: cluster offset=0x%" PRIx64 " is after " 913cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner "the end of the image file, can't properly check refcounts.\n", 914cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cluster_offset); 915cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->check_errors++; 9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (++refcount_table[k] == 0) { 9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR: overflow cluster offset=0x%" PRIx64 9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "\n", cluster_offset); 920cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Increases the refcount in the given refcount table for the all clusters 9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * referenced in the L2 table. While doing so, performs some checks on L2 9295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * entries. 9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns the number of errors found by the checks or -errno if an internal 9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * error occurred. 9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 934cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, 9355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t *refcount_table, int refcount_table_size, int64_t l2_offset, 9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int check_copied) 9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t *l2_table, offset; 9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i, l2_size, nb_csectors, refcount; 9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Read L2 table from disk */ 9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_size = s->l2_size * sizeof(uint64_t); 9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_table = qemu_malloc(l2_size); 9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 946cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size) 9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Do the actual checks */ 9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < s->l2_size; i++) { 9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = be64_to_cpu(l2_table[i]); 9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset != 0) { 9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset & QCOW_OFLAG_COMPRESSED) { 9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Compressed clusters don't have QCOW_OFLAG_COPIED */ 9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset & QCOW_OFLAG_COPIED) { 9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR: cluster %" PRId64 ": " 9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "copied flag must never be set for compressed " 9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "clusters\n", offset >> s->cluster_bits); 9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset &= ~QCOW_OFLAG_COPIED; 960cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Mark cluster as used */ 9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_csectors = ((offset >> s->csize_shift) & 9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->csize_mask) + 1; 9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset &= s->cluster_offset_mask; 967cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, refcount_table_size, 968cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset & ~511, nb_csectors * 512); 9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 9705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */ 9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (check_copied) { 9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t entry = offset; 9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset &= ~QCOW_OFLAG_COPIED; 9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = get_refcount(bs, offset >> s->cluster_bits); 975cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0) { 976cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Can't get refcount for offset %" 977cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner PRIx64 ": %s\n", entry, strerror(-refcount)); 978cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 979cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((refcount == 1) != ((entry & QCOW_OFLAG_COPIED) != 0)) { 9815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR OFLAG_COPIED: offset=%" 9825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner PRIx64 " refcount=%d\n", entry, refcount); 983cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 9845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Mark cluster as used */ 9885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset &= ~QCOW_OFLAG_COPIED; 989cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table,refcount_table_size, 990cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset, s->cluster_size); 9915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Correct offsets are cluster aligned */ 9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset & (s->cluster_size - 1)) { 9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not " 9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "properly aligned; L2 entry corrupted.\n", offset); 996cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l2_table); 1003cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail: 1006cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n"); 10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l2_table); 10085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 10095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Increases the refcount for the L1 table, its L2 tables and all referenced 10135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * clusters in the given refcount table. While doing so, performs some checks 10145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * on L1 and L2 entries. 10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 10165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns the number of errors found by the checks or -errno if an internal 10175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * error occurred. 10185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 10195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int check_refcounts_l1(BlockDriverState *bs, 1020cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BdrvCheckResult *res, 10215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t *refcount_table, 10225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int refcount_table_size, 10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t l1_table_offset, int l1_size, 10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int check_copied) 10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t *l1_table, l2_offset, l1_size2; 10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i, refcount, ret; 10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_size2 = l1_size * sizeof(uint64_t); 10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Mark L1 table as used */ 1033cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, refcount_table_size, 1034cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table_offset, l1_size2); 10355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Read L1 table entries from disk */ 1037cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (l1_size2 == 0) { 1038cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table = NULL; 1039cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else { 1040cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table = qemu_malloc(l1_size2); 1041cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, l1_table_offset, 1042cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l1_table, l1_size2) != l1_size2) 1043cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 1044cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for(i = 0;i < l1_size; i++) 1045cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner be64_to_cpus(&l1_table[i]); 1046cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Do the actual checks */ 10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < l1_size; i++) { 10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_offset = l1_table[i]; 10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l2_offset) { 10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */ 10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (check_copied) { 10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED) 10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner >> s->cluster_bits); 1056cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount < 0) { 1057cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Can't get refcount for l2_offset %" 1058cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner PRIx64 ": %s\n", l2_offset, strerror(-refcount)); 1059cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 1060cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) { 10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64 10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " refcount=%d\n", l2_offset, refcount); 1064cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Mark L2 table as used */ 10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_offset &= ~QCOW_OFLAG_COPIED; 1070cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, refcount_table_size, 1071cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner l2_offset, s->cluster_size); 10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* L2 tables are cluster aligned */ 10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (l2_offset & (s->cluster_size - 1)) { 10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not " 10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "cluster aligned; L1 entry corrupted\n", l2_offset); 1077cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Process and check L2 entries */ 1081cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = check_refcounts_l2(bs, res, refcount_table, 1082cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount_table_size, l2_offset, check_copied); 10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l1_table); 1089cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail: 10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n"); 1093cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->check_errors++; 10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(l1_table); 10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 10995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Checks an image for refcount consistency. 11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 11015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns 0 if no errors are found, the number of errors in case the image is 11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * detected as corrupted, and -errno when an internal error occured. 11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 1104cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) 11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t size; 11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_clusters, refcount1, refcount2, i; 11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowSnapshot *sn; 11105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t *refcount_table; 1111cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 11125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1113cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size = bdrv_getlength(bs->file); 11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_clusters = size_to_clusters(s, size); 11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t)); 11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* header */ 1118cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, nb_clusters, 1119cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 0, s->cluster_size); 11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* current L1 table */ 1122cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, 11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l1_table_offset, s->l1_size, 1); 11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* snapshots */ 11295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < s->nb_snapshots; i++) { 11305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sn = s->snapshots + i; 1131cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, 1132cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner sn->l1_table_offset, sn->l1_size, 0); 1133cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 1134cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 1135cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 11365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1137cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, nb_clusters, 1138cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->snapshots_offset, s->snapshots_size); 11395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* refcount data */ 1141cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, nb_clusters, 1142cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_offset, 1143cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table_size * sizeof(uint64_t)); 1144cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < s->refcount_table_size; i++) { 1146cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t offset, cluster; 11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = s->refcount_table[i]; 1148cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cluster = offset >> s->cluster_bits; 1149cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1150cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Refcount blocks are cluster aligned */ 1151cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (offset & (s->cluster_size - 1)) { 1152cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "ERROR refcount block %d is not " 1153cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner "cluster aligned; refcount table entry corrupted\n", i); 1154cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 1155cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner continue; 1156cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1157cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1158cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (cluster >= nb_clusters) { 1159cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "ERROR refcount block %d is outside image\n", i); 1160cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 1161cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner continue; 1162cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1163cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset != 0) { 1165cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner inc_refcounts(bs, res, refcount_table, nb_clusters, 1166cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset, s->cluster_size); 1167cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount_table[cluster] != 1) { 1168cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "ERROR refcount block %d refcount=%d\n", 1169cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner i, refcount_table[cluster]); 1170cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 1171cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* compare ref counts */ 11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < nb_clusters; i++) { 11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount1 = get_refcount(bs, i); 1178cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount1 < 0) { 1179cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Can't get refcount for cluster %d: %s\n", 1180cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner i, strerror(-refcount1)); 1181cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->check_errors++; 1182cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner continue; 1183cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1184cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount2 = refcount_table[i]; 11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (refcount1 != refcount2) { 1187cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "%s cluster %d refcount=%d reference=%d\n", 1188cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner refcount1 < refcount2 ? "ERROR" : "Leaked", 11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner i, refcount1, refcount2); 1190cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (refcount1 < refcount2) { 1191cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->corruptions++; 1192cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else { 1193cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner res->leaks++; 1194cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(refcount_table); 11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1200cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return 0; 12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1203