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 <zlib.h>
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block_int.h"
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block/qcow2.h"
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int new_l1_size, new_l1_size2, ret, i;
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t *new_l1_table;
36cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int64_t new_l1_table_offset;
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t data[12];
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    new_l1_size = s->l1_size;
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (min_size <= new_l1_size)
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
42cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (new_l1_size == 0) {
43cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        new_l1_size = 1;
44cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (min_size > new_l1_size) {
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        new_l1_size = (new_l1_size * 3 + 1) / 2;
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_ALLOC2
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    new_l1_size2 = sizeof(uint64_t) * new_l1_size;
53cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* write new table (align to cluster) */
57cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);
585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
59cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (new_l1_table_offset < 0) {
60cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        qemu_free(new_l1_table);
61cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return new_l1_table_offset;
62cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < s->l1_size; i++)
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
67cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
68cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0)
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < s->l1_size; i++)
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* set new table */
74cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_to_be32w((uint32_t*)data, new_l1_size);
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
77cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
78cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
80cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(s->l1_table);
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l1_table_offset = new_l1_table_offset;
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l1_table = new_l1_table;
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l1_size = new_l1_size;
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fail:
88cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    qemu_free(new_l1_table);
89cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
90cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return ret;
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_l2_cache_reset(BlockDriverState *bs)
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int l2_cache_new_entry(BlockDriverState *bs)
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t min_count;
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int min_index, i;
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* find a new entry in the least used one */
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    min_index = 0;
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    min_count = 0xffffffff;
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < L2_CACHE_SIZE; i++) {
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (s->l2_cache_counts[i] < min_count) {
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            min_count = s->l2_cache_counts[i];
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            min_index = i;
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return min_index;
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * seek_l2_table
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * seek l2_offset in the l2_cache table
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * if not found, return NULL,
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * if found,
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *   increments the l2 cache hit count of the entry,
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *   if counter overflow, divide by two all counters
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *   return the pointer to the l2 cache entry
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint64_t *seek_l2_table(BDRVQcowState *s, uint64_t l2_offset)
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i, j;
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < L2_CACHE_SIZE; i++) {
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (l2_offset == s->l2_cache_offsets[i]) {
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* increment the hit count */
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (++s->l2_cache_counts[i] == 0xffffffff) {
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(j = 0; j < L2_CACHE_SIZE; j++) {
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    s->l2_cache_counts[j] >>= 1;
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return s->l2_cache + (i << s->l2_bits);
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * l2_load
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Loads a L2 table into memory. If the table is in the cache, the cache
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * is used; otherwise the L2 table is loaded from the image file.
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns a pointer to the L2 table on success, or NULL if the read from
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the image file failed.
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
160cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int l2_load(BlockDriverState *bs, uint64_t l2_offset,
161cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t **l2_table)
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int min_index;
165cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int ret;
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek if the table for the given offset is in the cache */
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
169cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *l2_table = seek_l2_table(s, l2_offset);
170cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (*l2_table != NULL) {
171cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return 0;
172cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* not found: load a new entry in the least used one */
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    min_index = l2_cache_new_entry(bs);
177cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *l2_table = s->l2_cache + (min_index << s->l2_bits);
178cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
179cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
180cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pread(bs->file, l2_offset, *l2_table,
181cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        s->l2_size * sizeof(uint64_t));
182cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
183cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return ret;
184cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
185cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l2_cache_offsets[min_index] = l2_offset;
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l2_cache_counts[min_index] = 1;
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
189cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Writes one sector of the L1 table to the disk (can't update single entries
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and we really don't want bdrv_pread to perform a read-modify-write)
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define L1_ENTRIES_PER_SECTOR (512 / 8)
197cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int write_l1_entry(BlockDriverState *bs, int l1_index)
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
199cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t buf[L1_ENTRIES_PER_SECTOR];
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int l1_start_index;
202cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int i, ret;
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
209cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
210cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
211cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        buf, sizeof(buf));
212cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
213cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return ret;
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * l2_allocate
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Allocate a new l2 entry in the file. If l1_index points to an already
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * used entry in the L2 table (i.e. we are doing a copy on write for the L2
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * table) copy the contents of the old L2 table into the newly allocated one.
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Otherwise the new table is initialized with zeros.
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
229cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int min_index;
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t old_l2_offset;
234cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t *l2_table;
235cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int64_t l2_offset;
236cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int ret;
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    old_l2_offset = s->l1_table[l1_index];
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* allocate a new l2 entry */
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
243cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (l2_offset < 0) {
244cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return l2_offset;
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* allocate a new entry in the l2 cache */
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    min_index = l2_cache_new_entry(bs);
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_table = s->l2_cache + (min_index << s->l2_bits);
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (old_l2_offset == 0) {
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if there was no old l2 table, clear the new table */
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if there was an old l2 table, read it from the disk */
257cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ);
258cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        ret = bdrv_pread(bs->file, old_l2_offset, l2_table,
259cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            s->l2_size * sizeof(uint64_t));
260cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (ret < 0) {
261cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            goto fail;
262cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* write the l2 table to the file */
265cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
266cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
267cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        s->l2_size * sizeof(uint64_t));
268cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
269cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        goto fail;
270cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
271cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
272cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    /* update the L1 entry */
273cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
274cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = write_l1_entry(bs, l1_index);
275cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
276cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        goto fail;
277cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* update the l2 cache entry */
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l2_cache_offsets[min_index] = l2_offset;
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->l2_cache_counts[min_index] = 1;
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
284cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *table = l2_table;
285cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
286cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
287cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail:
288cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    s->l1_table[l1_index] = old_l2_offset;
289cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    qcow2_l2_cache_reset(bs);
290cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return ret;
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t *l2_table, uint64_t start, uint64_t mask)
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t offset = be64_to_cpu(l2_table[0]) & ~mask;
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!offset)
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = start; i < start + nb_clusters; i++)
303cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (offset + (uint64_t) i * cluster_size != (be64_to_cpu(l2_table[i]) & ~mask))
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return (i - start);
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table)
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i = 0;
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while(nb_clusters-- && l2_table[i] == 0)
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i++;
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return i;
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* The crypt function is compatible with the linux cryptoloop
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   algorithm for < 4 GB images. NOTE: out_buf == in_buf is
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   supported */
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                           uint8_t *out_buf, const uint8_t *in_buf,
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                           int nb_sectors, int enc,
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                           const AES_KEY *key)
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    union {
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t ll[2];
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint8_t b[16];
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } ivec;
3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < nb_sectors; i++) {
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ivec.ll[0] = cpu_to_le64(sector_num);
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ivec.ll[1] = 0;
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        AES_cbc_encrypt(in_buf, out_buf, 512, key,
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        ivec.b, enc);
3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sector_num++;
3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        in_buf += 512;
3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        out_buf += 512;
3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
345cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow_read(BlockDriverState *bs, int64_t sector_num,
346cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                     uint8_t *buf, int nb_sectors)
3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
3495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, index_in_cluster, n, n1;
3505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t cluster_offset;
3515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (nb_sectors > 0) {
3535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        n = nb_sectors;
354cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
355cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        ret = qcow2_get_cluster_offset(bs, sector_num << 9, &n,
356cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            &cluster_offset);
357cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (ret < 0) {
358cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            return ret;
359cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
360cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index_in_cluster = sector_num & (s->cluster_sectors - 1);
3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cluster_offset) {
3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (bs->backing_hd) {
3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* read from the base image */
3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                n1 = qcow2_backing_read1(bs->backing_hd, sector_num, buf, n);
3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (n1 > 0) {
367cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING);
3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (ret < 0)
3705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        return -1;
3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                memset(buf, 0, 512 * n);
3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
376cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            if (qcow2_decompress_cluster(bs, cluster_offset) < 0)
3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
380cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            BLKDBG_EVENT(bs->file, BLKDBG_READ);
381cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            ret = bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512);
3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ret != n * 512)
3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (s->crypt_method) {
3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qcow2_encrypt_sectors(s, sector_num, buf, buf, n, 0,
3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                &s->aes_decrypt_key);
3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_sectors -= n;
3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sector_num += n;
3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        buf += n * 512;
3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        uint64_t cluster_offset, int n_start, int n_end)
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int n, ret;
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    n = n_end - n_start;
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n <= 0)
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
405cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
406cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret < 0)
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret;
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->crypt_method) {
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qcow2_encrypt_sectors(s, start_sect + n_start,
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        s->cluster_data,
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        s->cluster_data, n, 1,
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        &s->aes_encrypt_key);
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
415cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
416cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start,
417cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        s->cluster_data, n);
4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret < 0)
4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret;
4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * get_cluster_offset
4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
427cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * For a given offset of the disk image, find the cluster offset in
428cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * qcow2 file. The offset is stored in *cluster_offset.
4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * on entry, *num is the number of contiguous clusters we'd like to
4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * access following offset.
4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * on exit, *num is the number of contiguous clusters we can read.
4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
435cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Return 0, if the offset is found
436cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Return -errno, otherwise.
4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
440cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
441cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int *num, uint64_t *cluster_offset)
4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
444cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    unsigned int l1_index, l2_index;
445cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t l2_offset, *l2_table;
4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int l1_bits, c;
447cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    unsigned int index_in_cluster, nb_clusters;
448cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t nb_available, nb_needed;
449cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int ret;
4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_needed = *num + index_in_cluster;
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l1_bits = s->l2_bits + s->cluster_bits;
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compute how many bytes there are between the offset and
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * the end of the l1 entry
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
460cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1));
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compute the number of available sectors */
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_available = (nb_available >> 9) + index_in_cluster;
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_needed > nb_available) {
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_needed = nb_available;
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
470cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *cluster_offset = 0;
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek the the l2 offset in the l1 table */
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l1_index = offset >> l1_bits;
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (l1_index >= s->l1_size)
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto out;
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_offset = s->l1_table[l1_index];
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek the l2 table of the given l2 offset */
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!l2_offset)
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto out;
4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* load the l2 table in memory */
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_offset &= ~QCOW_OFLAG_COPIED;
488cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = l2_load(bs, l2_offset, &l2_table);
489cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
490cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return ret;
491cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* find the cluster offset for the given disk offset */
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
496cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *cluster_offset = be64_to_cpu(l2_table[l2_index]);
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_clusters = size_to_clusters(s, nb_needed << 9);
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
499cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (!*cluster_offset) {
5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* how many empty clusters ? */
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);
5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* how many allocated clusters ? */
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        c = count_contiguous_clusters(nb_clusters, s->cluster_size,
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                &l2_table[l2_index], 0, QCOW_OFLAG_COPIED);
5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   nb_available = (c * s->cluster_sectors);
5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerout:
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_available > nb_needed)
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_available = nb_needed;
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *num = nb_available - index_in_cluster;
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
515cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    *cluster_offset &=~QCOW_OFLAG_COPIED;
516cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * get_cluster_table
5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * for a given disk offset, load (and allocate if needed)
5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the l2 table.
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the l2 table offset in the qcow2 file and the cluster index
5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * in the l2 table are given to the caller.
5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
528cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Returns 0 on success, -errno in failure case
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int get_cluster_table(BlockDriverState *bs, uint64_t offset,
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             uint64_t **new_l2_table,
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             uint64_t *new_l2_offset,
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             int *new_l2_index)
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
536cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    unsigned int l1_index, l2_index;
537cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t l2_offset;
538cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t *l2_table = NULL;
539cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int ret;
5405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek the the l2 offset in the l1 table */
5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l1_index = offset >> (s->l2_bits + s->cluster_bits);
5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (l1_index >= s->l1_size) {
5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = qcow2_grow_l1_table(bs, l1_index + 1);
546cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (ret < 0) {
547cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            return ret;
548cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_offset = s->l1_table[l1_index];
5515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek the l2 table of the given l2 offset */
5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (l2_offset & QCOW_OFLAG_COPIED) {
5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* load the l2 table in memory */
5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        l2_offset &= ~QCOW_OFLAG_COPIED;
557cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        ret = l2_load(bs, l2_offset, &l2_table);
558cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (ret < 0) {
559cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            return ret;
560cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (l2_offset)
5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
564cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        ret = l2_allocate(bs, l1_index, &l2_table);
565cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (ret < 0) {
566cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            return ret;
567cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* find the cluster offset for the given disk offset */
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *new_l2_table = l2_table;
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *new_l2_offset = l2_offset;
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *new_l2_index = l2_index;
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
579cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * alloc_compressed_cluster_offset
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * For a given offset of the disk image, return cluster offset in
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * qcow2 file.
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If the offset is not found, allocate a new compressed cluster.
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Return the cluster offset if successful,
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Return 0, otherwise.
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                               uint64_t offset,
5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                               int compressed_size)
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int l2_index, ret;
601cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t l2_offset, *l2_table;
602cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int64_t cluster_offset;
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_csectors;
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
606cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
608cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cluster_offset = be64_to_cpu(l2_table[l2_index]);
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cluster_offset & QCOW_OFLAG_COPIED)
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return cluster_offset & ~QCOW_OFLAG_COPIED;
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cluster_offset)
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qcow2_free_any_clusters(bs, cluster_offset, 1);
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
618cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (cluster_offset < 0) {
619cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return 0;
620cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
621cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                  (cluster_offset >> 9);
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cluster_offset |= QCOW_OFLAG_COMPRESSED |
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                      ((uint64_t)nb_csectors << s->csize_shift);
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* update L2 table */
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compressed clusters never have the copied flag */
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
632cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    l2_table[l2_index] = cpu_to_be64(cluster_offset);
634cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (bdrv_pwrite_sync(bs->file,
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    l2_offset + l2_index * sizeof(uint64_t),
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    l2_table + l2_index,
637cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                    sizeof(uint64_t)) < 0)
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return cluster_offset;
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Write L2 table updates to disk, writing whole sectors to avoid a
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * read-modify-write in bdrv_pwrite
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define L2_ENTRIES_PER_SECTOR (512 / 8)
648cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t l2_offset, int l2_index, int num)
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int l2_start_index = l2_index & ~(L1_ENTRIES_PER_SECTOR - 1);
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int start_offset = (8 * l2_index) & ~511;
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int end_offset = (8 * (l2_index + num) + 511) & ~511;
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    size_t len = end_offset - start_offset;
655cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int ret;
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
657cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
658cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = bdrv_pwrite_sync(bs->file, l2_offset + start_offset,
659cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        &l2_table[l2_start_index], len);
660cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
661cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return ret;
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
667cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i, j = 0, l2_index, ret;
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t *old_cluster, start_sect, l2_offset, *l2_table;
672cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t cluster_offset = m->cluster_offset;
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (m->nb_clusters == 0)
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    old_cluster = qemu_malloc(m->nb_clusters * sizeof(uint64_t));
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* copy content of unmodified sectors */
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_sect = (m->offset & ~(s->cluster_size - 1)) >> 9;
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (m->n_start) {
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = copy_sectors(bs, start_sect, cluster_offset, 0, m->n_start);
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0)
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto err;
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (m->nb_available & (s->cluster_sectors - 1)) {
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t end = m->nb_available & ~(uint64_t)(s->cluster_sectors - 1);
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = copy_sectors(bs, start_sect + end, cluster_offset + (end << 9),
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                m->nb_available - end, s->cluster_sectors);
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0)
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto err;
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* update L2 table */
696cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index);
697cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto err;
699cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < m->nb_clusters; i++) {
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if two concurrent writes happen to the same unallocated cluster
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * each write allocates separate cluster and writes data concurrently.
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * The first one to complete updates l2 table with pointer to its
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * cluster the second one has to do RMW (which is done above by
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * copy_sectors()), update l2 table with its cluster pointer and free
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * old cluster. This is what this loop does */
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if(l2_table[l2_index + i] != 0)
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            old_cluster[j++] = l2_table[l2_index + i];
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     }
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
715cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    ret = write_l2_entries(bs, l2_table, l2_offset, l2_index, m->nb_clusters);
716cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
717cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        qcow2_l2_cache_reset(bs);
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto err;
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < j; i++)
7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qcow2_free_any_clusters(bs,
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED, 1);
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = 0;
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnererr:
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(old_cluster);
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * alloc_cluster_offset
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
734cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * For a given offset of the disk image, return cluster offset in qcow2 file.
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If the offset is not found, allocate a new cluster.
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
737cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If the cluster was already allocated, m->nb_clusters is set to 0,
738cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * m->depends_on is set to NULL and the other fields in m are meaningless.
739cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner *
740cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If the cluster is newly allocated, m->nb_clusters is set to the number of
741cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * contiguous clusters that have been allocated. This may be 0 if the request
742cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * conflict with another write request in flight; in this case, m->depends_on
743cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * is set and the remaining fields of m are meaningless.
744cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner *
745cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * If m->nb_clusters is non-zero, the other fields of m are valid and contain
746cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * information about the first allocated cluster.
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
748cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Return 0 on success and -errno in error cases
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
750cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
751cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int n_start, int n_end, int *num, QCowL2Meta *m)
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int l2_index, ret;
755cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    uint64_t l2_offset, *l2_table;
756cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int64_t cluster_offset;
757cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    unsigned int nb_clusters, i = 0;
758cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    QCowL2Meta *old_alloc;
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
761cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (ret < 0) {
762cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return ret;
763cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_clusters = size_to_clusters(s, n_end << 9);
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cluster_offset = be64_to_cpu(l2_table[l2_index]);
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* We keep all QCOW_OFLAG_COPIED clusters */
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cluster_offset & QCOW_OFLAG_COPIED) {
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size,
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                &l2_table[l2_index], 0, 0);
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cluster_offset &= ~QCOW_OFLAG_COPIED;
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        m->nb_clusters = 0;
779cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        m->depends_on = NULL;
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto out;
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* for the moment, multiple compressed clusters are not managed */
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cluster_offset & QCOW_OFLAG_COMPRESSED)
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_clusters = 1;
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* how many available clusters ? */
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (i < nb_clusters) {
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                &l2_table[l2_index], i, 0);
794cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) {
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
796cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i += count_contiguous_free_clusters(nb_clusters - i,
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                &l2_table[l2_index + i]);
800cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (i >= nb_clusters) {
801cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            break;
802cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((cluster_offset & QCOW_OFLAG_COPIED) ||
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                (cluster_offset & QCOW_OFLAG_COMPRESSED))
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
810cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    assert(i <= nb_clusters);
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_clusters = i;
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
813cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    /*
814cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner     * Check if there already is an AIO write request in flight which allocates
815cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner     * the same cluster. In this case we need to wait until the previous
816cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner     * request has completed and updated the L2 table accordingly.
817cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner     */
818cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) {
819cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
820cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        uint64_t end_offset = offset + nb_clusters * s->cluster_size;
821cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        uint64_t old_offset = old_alloc->offset;
822cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        uint64_t old_end_offset = old_alloc->offset +
823cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            old_alloc->nb_clusters * s->cluster_size;
824cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
825cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (end_offset < old_offset || offset > old_end_offset) {
826cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            /* No intersection */
827cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        } else {
828cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            if (offset < old_offset) {
829cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                /* Stop at the start of a running allocation */
830cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                nb_clusters = (old_offset - offset) >> s->cluster_bits;
831cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            } else {
832cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                nb_clusters = 0;
833cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            }
834cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
835cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            if (nb_clusters == 0) {
836cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                /* Set dependency and wait for a callback */
837cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                m->depends_on = old_alloc;
838cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                m->nb_clusters = 0;
839cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                *num = 0;
840cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                return 0;
841cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            }
842cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        }
843cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
844cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
8457fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije    if (!nb_clusters) {
8467fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije        abort();
8477fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije    }
8487fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije
8497fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije    QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight);
8507fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* allocate a new cluster */
8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);
854cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (cluster_offset < 0) {
855cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        QLIST_REMOVE(m, next_in_flight);
856cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        return cluster_offset;
857cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* save info needed for meta data update */
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->offset = offset;
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->n_start = n_start;
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->nb_clusters = nb_clusters;
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerout:
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);
866cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    m->cluster_offset = cluster_offset;
8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *num = m->nb_available - n_start;
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
870cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int decompress_buffer(uint8_t *out_buf, int out_buf_size,
8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             const uint8_t *buf, int buf_size)
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    z_stream strm1, *strm = &strm1;
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, out_len;
8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(strm, 0, sizeof(*strm));
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strm->next_in = (uint8_t *)buf;
8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strm->avail_in = buf_size;
8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strm->next_out = out_buf;
8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strm->avail_out = out_buf_size;
8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = inflateInit2(strm, -12);
8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret != Z_OK)
8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = inflate(strm, Z_FINISH);
8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    out_len = strm->next_out - out_buf;
8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        out_len != out_buf_size) {
8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        inflateEnd(strm);
8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    inflateEnd(strm);
8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
900cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
902cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    BDRVQcowState *s = bs->opaque;
9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, csize, nb_csectors, sector_offset;
9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t coffset;
9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    coffset = cluster_offset & s->cluster_offset_mask;
9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->cluster_cache_offset != coffset) {
9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sector_offset = coffset & 511;
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        csize = nb_csectors * 512 - sector_offset;
911cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
912cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (decompress_buffer(s->cluster_cache, s->cluster_size,
9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                              s->cluster_data + sector_offset, csize) < 0) {
9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->cluster_cache_offset = coffset;
9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
924