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"
26e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner#include "block/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
64aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    s->refcount_block_cache = g_malloc(s->cluster_size);
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
66aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    s->refcount_table = g_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;
84aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(s->refcount_block_cache);
85aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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;
338aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size);
339aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    uint64_t *new_table = g_malloc0(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);
364aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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
400aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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:
418aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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) {
550a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner        int __attribute__((unused)) 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) {
761aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner            l1_table = g_malloc0(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);
778aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    l2_table = g_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)
860aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        g_free(l1_table);
861aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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)
867aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        g_free(l1_table);
868aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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);
944aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    l2_table = g_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
1002aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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");
1007aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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 {
1040aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        l1_table = g_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    }
1088aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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++;
1094aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_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);
1115aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    refcount_table = g_malloc0(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
1198aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(refcount_table);
11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1200cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1203