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#include "qemu-common.h" 255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block_int.h" 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "module.h" 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <zlib.h> 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "aes.h" 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block/qcow2.h" 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner Differences with QCOW: 335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - Support for multiple incremental snapshots. 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - Memory management by reference counts. 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - Clusters which have a reference count of one have the bit 375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCOW_OFLAG_COPIED to optimize write performance. 385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - Size of compressed clusters is stored in sectors to reduce bit usage 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner in the cluster offsets. 405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - Support for storing additional data (such as the VM state) in the 415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner snapshots. 425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - If a backing store is used, the cluster size is not constrained 435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (could be backported to QCOW). 445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner - L2 tables have always a size of one cluster. 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner*/ 465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct { 495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t magic; 505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t len; 515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QCowExtension; 525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define QCOW_EXT_MAGIC_END 0 535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define QCOW_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA 545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) 565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const QCowHeader *cow_header = (const void *)buf; 585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (buf_size >= sizeof(QCowHeader) && 605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpu(cow_header->magic) == QCOW_MAGIC && 615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpu(cow_header->version) == QCOW_VERSION) 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 100; 635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 68cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * read qcow2 extension and fill bs 705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * start reading from start_offset 715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * finish reading upon magic of value 0 or when end_offset reached 725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * unknown magic is skipped (future extension this version knows nothing about) 735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * return 0 upon success, non-0 otherwise 745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset, 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t end_offset) 775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowExtension ext; 795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t offset; 805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_EXT 825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("qcow_read_extensions: start=%ld end=%ld\n", start_offset, end_offset); 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = start_offset; 855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (offset < end_offset) { 865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_EXT 885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Sanity check */ 895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset > s->cluster_size) 905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("qcow_handle_extension: suspicious offset %lu\n", offset); 915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("attemting to read extended header in offset %lu\n", offset); 935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 95cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, offset, &ext, sizeof(ext)) != sizeof(ext)) { 96cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "qcow_handle_extension: ERROR: " 97cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner "pread fail from offset %" PRIu64 "\n", 98cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset); 995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 1; 1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&ext.magic); 1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&ext.len); 1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset += sizeof(ext); 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_EXT 1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("ext.magic = 0x%x\n", ext.magic); 1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (ext.magic) { 1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case QCOW_EXT_MAGIC_END: 1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case QCOW_EXT_MAGIC_BACKING_FORMAT: 1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ext.len >= sizeof(bs->backing_format)) { 1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "ERROR: ext_backing_format: len=%u too large" 1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " (>=%zu)\n", 1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ext.len, sizeof(bs->backing_format)); 1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 2; 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 118cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, offset , bs->backing_format, 1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ext.len) != ext.len) 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 3; 1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->backing_format[ext.len] = '\0'; 1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_EXT 1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("Qcow2: Got format extension %s\n", bs->backing_format); 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 125cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset = ((offset + ext.len + 7) & ~7); 1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* unknown magic -- just skip it */ 130cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset = ((offset + ext.len + 7) & ~7); 1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 139cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow_open(BlockDriverState *bs, int flags) 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 142cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int len, i; 1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowHeader header; 1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t ext_end; 1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 146cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, 0, &header, sizeof(header)) != sizeof(header)) 1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.magic); 1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.version); 1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&header.backing_file_offset); 1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.backing_file_size); 1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&header.size); 1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.cluster_bits); 1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.crypt_method); 1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&header.l1_table_offset); 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.l1_size); 1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&header.refcount_table_offset); 1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.refcount_table_clusters); 1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be64_to_cpus(&header.snapshots_offset); 1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner be32_to_cpus(&header.nb_snapshots); 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION) 1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 164cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (header.cluster_bits < MIN_CLUSTER_BITS || 1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.cluster_bits > MAX_CLUSTER_BITS) 1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (header.crypt_method > QCOW_CRYPT_AES) 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->crypt_method_header = header.crypt_method; 1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->crypt_method_header) 1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->encrypted = 1; 1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_bits = header.cluster_bits; 1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_size = 1 << s->cluster_bits; 1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_sectors = 1 << (s->cluster_bits - 9); 1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */ 1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l2_size = 1 << s->l2_bits; 1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->total_sectors = header.size / 512; 1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->csize_shift = (62 - (s->cluster_bits - 8)); 1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->csize_mask = (1 << (s->cluster_bits - 8)) - 1; 1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_offset_mask = (1LL << s->csize_shift) - 1; 1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table_offset = header.refcount_table_offset; 1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table_size = 1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.refcount_table_clusters << (s->cluster_bits - 3); 1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->snapshots_offset = header.snapshots_offset; 1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->nb_snapshots = header.nb_snapshots; 1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* read the level 1 table */ 1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l1_size = header.l1_size; 190cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->l1_vm_state_index = size_to_l1(s, header.size); 1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* the L1 table must contain at least enough entries to put 1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.size bytes */ 1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->l1_size < s->l1_vm_state_index) 1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l1_table_offset = header.l1_table_offset; 196cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (s->l1_size > 0) { 197cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->l1_table = qemu_mallocz( 198cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner align_offset(s->l1_size * sizeof(uint64_t), 512)); 199cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) != 200cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->l1_size * sizeof(uint64_t)) 201cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 202cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner for(i = 0;i < s->l1_size; i++) { 203cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner be64_to_cpus(&s->l1_table[i]); 204cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* alloc L2 cache */ 2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); 2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_cache = qemu_malloc(s->cluster_size); 2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* one more sector for decompressed data alignment */ 2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size 2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner + 512); 2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_cache_offset = -1; 2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (qcow2_refcount_init(bs) < 0) 2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2177fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije QLIST_INIT(&s->cluster_allocs); 2187fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije 2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* read qcow2 extensions */ 2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (header.backing_file_offset) 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ext_end = header.backing_file_offset; 2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ext_end = s->cluster_size; 2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (qcow_read_extensions(bs, sizeof(header), ext_end)) 2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* read the backing file name */ 2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (header.backing_file_offset != 0) { 2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner len = header.backing_file_size; 2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (len > 1023) 2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner len = 1023; 232cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pread(bs->file, header.backing_file_offset, bs->backing_file, len) != len) 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->backing_file[len] = '\0'; 2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (qcow2_read_snapshots(bs) < 0) 2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_ALLOC 240cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow2_check_refcounts(bs); 2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fail: 2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_free_snapshots(bs); 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_refcount_close(bs); 2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->l1_table); 2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->l2_cache); 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->cluster_cache); 2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->cluster_data); 2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_set_key(BlockDriverState *bs, const char *key) 2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t keybuf[16]; 2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int len, i; 2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(keybuf, 0, 16); 2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner len = strlen(key); 2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (len > 16) 2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner len = 16; 2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* XXX: we could compress the chars to 7 bits to increase 2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner entropy */ 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0;i < len;i++) { 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner keybuf[i] = key[i]; 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->crypt_method = s->crypt_method_header; 2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0) 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0) 2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* test */ 2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t in[16]; 2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t out[16]; 2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t tmp[16]; 2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i=0;i<16;i++) 2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner in[i] = i; 2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AES_encrypt(in, tmp, &s->aes_encrypt_key); 2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AES_decrypt(tmp, out, &s->aes_decrypt_key); 2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < 16; i++) 2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf(" %02x", tmp[i]); 2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("\n"); 2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < 16; i++) 2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf(" %02x", out[i]); 2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("\n"); 2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num, 2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_sectors, int *pnum) 2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t cluster_offset; 300cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pnum = nb_sectors; 303cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* FIXME We can get errors here, but the bdrv_is_allocated interface can't 304cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * pass them on today */ 305cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset); 306cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 307cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner *pnum = 0; 308cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (cluster_offset != 0); 3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* handle reading after the end of the backing file */ 3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qcow2_backing_read1(BlockDriverState *bs, 3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, uint8_t *buf, int nb_sectors) 3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int n1; 3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((sector_num + nb_sectors) <= bs->total_sectors) 3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return nb_sectors; 3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sector_num >= bs->total_sectors) 3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n1 = 0; 3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n1 = bs->total_sectors - sector_num; 3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1)); 3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return n1; 3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QCowAIOCB { 3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverAIOCB common; 3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num; 3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector *qiov; 3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *buf; 3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner void *orig_buf; 334cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int remaining_sectors; 335cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int cur_nr_sectors; /* number of sectors in current iteration */ 3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t cluster_offset; 3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *cluster_data; 3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverAIOCB *hd_aiocb; 3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct iovec hd_iov; 3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector hd_qiov; 3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUBH *bh; 3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowL2Meta l2meta; 343cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_ENTRY(QCowAIOCB) next_depend; 3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QCowAIOCB; 3455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_aio_cancel(BlockDriverAIOCB *blockacb) 3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 348cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common); 3495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (acb->hd_aiocb) 3505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_aio_cancel(acb->hd_aiocb); 3515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_aio_release(acb); 3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic AIOPool qcow_aio_pool = { 3555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .aiocb_size = sizeof(QCowAIOCB), 3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .cancel = qcow_aio_cancel, 3575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}; 3585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_aio_read_cb(void *opaque, int ret); 3605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_aio_read_bh(void *opaque) 3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb = opaque; 3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_bh_delete(acb->bh); 3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->bh = NULL; 3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow_aio_read_cb(opaque, 0); 3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb) 3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (acb->bh) 3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->bh = qemu_bh_new(cb, acb); 3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb->bh) 3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_bh_schedule(acb->bh); 3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_aio_read_cb(void *opaque, int ret) 3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb = opaque; 3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverState *bs = acb->common.bs; 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int index_in_cluster, n1; 3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_aiocb = NULL; 3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* post process the read buffer */ 3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb->cluster_offset) { 3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* nothing to do */ 3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { 3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* nothing to do */ 3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->crypt_method) { 4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf, 401cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->cur_nr_sectors, 0, 4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner &s->aes_decrypt_key); 4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 406cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->remaining_sectors -= acb->cur_nr_sectors; 407cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->sector_num += acb->cur_nr_sectors; 408cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->buf += acb->cur_nr_sectors * 512; 4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 410cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->remaining_sectors == 0) { 4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* request completed */ 4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = 0; 4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* prepare next AIO request */ 417cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->cur_nr_sectors = acb->remaining_sectors; 418cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, 419cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &acb->cur_nr_sectors, &acb->cluster_offset); 420cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 421cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto done; 422cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 423cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); 4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb->cluster_offset) { 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->backing_hd) { 4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* read from the base image */ 4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n1 = qcow2_backing_read1(bs->backing_hd, acb->sector_num, 430cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->buf, acb->cur_nr_sectors); 4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n1 > 0) { 4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_iov.iov_base = (void *)acb->buf; 433cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->hd_iov.iov_len = acb->cur_nr_sectors * 512; 4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); 435cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); 4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num, 437cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &acb->hd_qiov, acb->cur_nr_sectors, 4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow_aio_read_cb, acb); 4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (acb->hd_aiocb == NULL) 4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = qcow_schedule_bh(qcow_aio_read_bh, acb); 4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Note: in this case, no need to wait */ 448cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memset(acb->buf, 0, 512 * acb->cur_nr_sectors); 4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = qcow_schedule_bh(qcow_aio_read_bh, acb); 4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { 4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* add AIO support for compressed blocks ? */ 455cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (qcow2_decompress_cluster(bs, acb->cluster_offset) < 0) 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 457cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memcpy(acb->buf, s->cluster_cache + index_in_cluster * 512, 458cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 512 * acb->cur_nr_sectors); 4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = qcow_schedule_bh(qcow_aio_read_bh, acb); 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((acb->cluster_offset & 511) != 0) { 4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = -EIO; 4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_iov.iov_base = (void *)acb->buf; 469cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->hd_iov.iov_len = acb->cur_nr_sectors * 512; 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); 471cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); 472cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->hd_aiocb = bdrv_aio_readv(bs->file, 4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (acb->cluster_offset >> 9) + index_in_cluster, 474cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &acb->hd_qiov, acb->cur_nr_sectors, 475cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow_aio_read_cb, acb); 476cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->hd_aiocb == NULL) { 477cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -EIO; 4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 479cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerdone: 4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (acb->qiov->niov > 1) { 4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size); 4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_vfree(acb->orig_buf); 4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->common.cb(acb->common.opaque, ret); 4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_aio_release(acb); 4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, 4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque, int is_write) 4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb; 4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = qemu_aio_get(&qcow_aio_pool, bs, cb, opaque); 4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb) 5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_aiocb = NULL; 5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->sector_num = sector_num; 5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->qiov = qiov; 5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (qiov->niov > 1) { 5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); 5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (is_write) 5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_to_buffer(qiov, acb->buf); 5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->buf = (uint8_t *)qiov->iov->iov_base; 5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 511cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->remaining_sectors = nb_sectors; 512cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->cur_nr_sectors = 0; 5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->cluster_offset = 0; 5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->l2meta.nb_clusters = 0; 515cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_INIT(&acb->l2meta.dependent_requests); 5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return acb; 5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *qcow_aio_readv(BlockDriverState *bs, 5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb; 5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb) 5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow_aio_read_cb(acb, 0); 5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return &acb->common; 5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 533cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic void qcow_aio_write_cb(void *opaque, int ret); 534cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 535cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic void run_dependent_requests(QCowL2Meta *m) 536cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 537cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QCowAIOCB *req; 538cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QCowAIOCB *next; 539cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 540cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Take the request off the list of running requests */ 541cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (m->nb_clusters != 0) { 542cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_REMOVE(m, next_in_flight); 543cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 544cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 545cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Restart all dependent requests */ 546cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_FOREACH_SAFE(req, &m->dependent_requests, next_depend, next) { 547cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow_aio_write_cb(req, 0); 548cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 549cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 550cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Empty the list for the next part of the request */ 551cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_INIT(&m->dependent_requests); 552cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 553cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_aio_write_cb(void *opaque, int ret) 5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb = opaque; 5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverState *bs = acb->common.bs; 5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int index_in_cluster; 5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const uint8_t *src_buf; 5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int n_end; 5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_aiocb = NULL; 5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 565cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret >= 0) { 566cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta); 567cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 569cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner run_dependent_requests(&acb->l2meta); 570cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 571cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 574cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->remaining_sectors -= acb->cur_nr_sectors; 575cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->sector_num += acb->cur_nr_sectors; 576cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->buf += acb->cur_nr_sectors * 512; 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 578cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->remaining_sectors == 0) { 5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* request completed */ 5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = 0; 5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); 585cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner n_end = index_in_cluster + acb->remaining_sectors; 5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->crypt_method && 5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) 5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; 5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 590cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, 591cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner index_in_cluster, n_end, &acb->cur_nr_sectors, &acb->l2meta); 592cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto done; 5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 595cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 596cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->cluster_offset = acb->l2meta.cluster_offset; 597cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 598cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Need to wait for another request? If so, we are done for now. */ 599cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->l2meta.nb_clusters == 0 && acb->l2meta.depends_on != NULL) { 600cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_INSERT_HEAD(&acb->l2meta.depends_on->dependent_requests, 601cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb, next_depend); 602cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return; 603cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 604cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 605cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner assert((acb->cluster_offset & 511) == 0); 606cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->crypt_method) { 6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb->cluster_data) { 6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * 6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_size); 6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf, 613cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->cur_nr_sectors, 1, &s->aes_encrypt_key); 6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner src_buf = acb->cluster_data; 6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner src_buf = acb->buf; 6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->hd_iov.iov_base = (void *)src_buf; 619cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->hd_iov.iov_len = acb->cur_nr_sectors * 512; 6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); 621cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); 622cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner acb->hd_aiocb = bdrv_aio_writev(bs->file, 6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (acb->cluster_offset >> 9) + index_in_cluster, 624cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &acb->hd_qiov, acb->cur_nr_sectors, 6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow_aio_write_cb, acb); 626cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->hd_aiocb == NULL) { 627cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -EIO; 628cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 629cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 633cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail: 634cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (acb->l2meta.nb_clusters != 0) { 635cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_REMOVE(&acb->l2meta, next_in_flight); 636cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerdone: 6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (acb->qiov->niov > 1) 6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_vfree(acb->orig_buf); 6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->common.cb(acb->common.opaque, ret); 6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_aio_release(acb); 6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs, 6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowAIOCB *acb; 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_cache_offset = -1; /* disable compressed cache */ 6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb) 6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow_aio_write_cb(acb, 0); 6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return &acb->common; 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_close(BlockDriverState *bs) 6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->l1_table); 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->l2_cache); 6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->cluster_cache); 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->cluster_data); 6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_refcount_close(bs); 669cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 670cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 671cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner/* 672cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Updates the variable length parts of the qcow2 header, i.e. the backing file 673cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * name and all extensions. qcow2 was not designed to allow such changes, so if 674cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * we run out of space (we can only use the first cluster) this function may 675cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * fail. 676cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * 677cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * Returns 0 on success, -errno in error cases. 678cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 679cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow2_update_ext_header(BlockDriverState *bs, 680cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner const char *backing_file, const char *backing_fmt) 681cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 682cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t backing_file_len = 0; 683cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t backing_fmt_len = 0; 684cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BDRVQcowState *s = bs->opaque; 685cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QCowExtension ext_backing_fmt = {0, 0}; 686cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 687cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 688cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Backing file format doesn't make sense without a backing file */ 689cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_fmt && !backing_file) { 690cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -EINVAL; 691cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 692cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 693cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Prepare the backing file format extension if needed */ 694cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_fmt) { 695cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ext_backing_fmt.len = cpu_to_be32(strlen(backing_fmt)); 696cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT); 697cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner backing_fmt_len = ((sizeof(ext_backing_fmt) 698cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner + strlen(backing_fmt) + 7) & ~7); 699cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 700cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 701cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Check if we can fit the new header into the first cluster */ 702cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_file) { 703cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner backing_file_len = strlen(backing_file); 704cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 705cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 706cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t header_size = sizeof(QCowHeader) + backing_file_len 707cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner + backing_fmt_len; 708cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 709cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (header_size > s->cluster_size) { 710cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -ENOSPC; 711cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 712cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 713cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Rewrite backing file name and qcow2 extensions */ 714cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t ext_size = header_size - sizeof(QCowHeader); 715cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint8_t buf[ext_size]; 716cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t offset = 0; 717cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size_t backing_file_offset = 0; 718cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 719cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_file) { 720cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_fmt) { 721cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int padding = backing_fmt_len - 722cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner (sizeof(ext_backing_fmt) + strlen(backing_fmt)); 723cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 724cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt)); 725cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset += sizeof(ext_backing_fmt); 726cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 727cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memcpy(buf + offset, backing_fmt, strlen(backing_fmt)); 728cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset += strlen(backing_fmt); 729cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 730cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memset(buf + offset, 0, padding); 731cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset += padding; 732cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 733cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 734cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memcpy(buf + offset, backing_file, backing_file_len); 735cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner backing_file_offset = sizeof(QCowHeader) + offset; 736cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 737cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 738cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, sizeof(QCowHeader), buf, ext_size); 739cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 740cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 741cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 742cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 743cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Update header fields */ 744cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset); 745cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint32_t be_backing_file_size = cpu_to_be32(backing_file_len); 746cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 747cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_offset), 748cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &be_backing_file_offset, sizeof(uint64_t)); 749cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 750cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 751cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 752cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 753cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_size), 754cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &be_backing_file_size, sizeof(uint32_t)); 755cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 756cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto fail; 757cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 758cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 759cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = 0; 760cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerfail: 761cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 762cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 763cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 764cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow2_change_backing_file(BlockDriverState *bs, 765cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner const char *backing_file, const char *backing_fmt) 766cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 767cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return qcow2_update_ext_header(bs, backing_file, backing_fmt); 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int get_bits_from_size(size_t size) 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int res = 0; 7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (size == 0) { 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (size != 1) { 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Not a power of two */ 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (size & 1) { 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size >>= 1; 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner res++; 7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return res; 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 791cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 792cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int preallocate(BlockDriverState *bs) 7934e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner{ 794cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t nb_sectors; 795cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t offset; 796cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int num; 797cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 798cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QCowL2Meta meta; 799cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 800cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner nb_sectors = bdrv_getlength(bs) >> 9; 801cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset = 0; 802cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner QLIST_INIT(&meta.dependent_requests); 803cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner meta.cluster_offset = 0; 804cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 805cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner while (nb_sectors) { 806cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner num = MIN(nb_sectors, INT_MAX >> 9); 807cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta); 8084e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner if (ret < 0) { 809cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 8104e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner } 8114e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 812cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_alloc_cluster_link_l2(bs, &meta); 813cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 814cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters); 815cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 816cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 8174e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 818cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* There are no dependent requests, but we need to remove our request 819cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * from the list of in-flight requests */ 820cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner run_dependent_requests(&meta); 821cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 822cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* TODO Preallocate data if requested */ 823cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 824cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner nb_sectors -= num; 825cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset += num << 9; 826cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 827cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 828cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* 829cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * It is expected that the image file is large enough to actually contain 830cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * all of the allocated clusters (otherwise we get failing reads after 831cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner * EOF). Extend the image to the last allocated sector. 832cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner */ 833cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (meta.cluster_offset != 0) { 834cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint8_t buf[512]; 835cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner memset(buf, 0, 512); 836cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_write(bs->file, (meta.cluster_offset >> 9) + num - 1, buf, 1); 837cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 838cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 839cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 840cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 8414e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 8424e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner return 0; 8434e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner} 8444e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_create2(const char *filename, int64_t total_size, 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *backing_file, const char *backing_format, 847cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int flags, size_t cluster_size, int prealloc) 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits; 851cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ref_clusters, reftable_clusters, backing_format_len = 0; 852cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int rounded_ext_bf_len = 0; 8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowHeader header; 8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t tmp, offset; 855cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t old_ref_clusters; 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowCreateState s1, *s = &s1; 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QCowExtension ext_bf = {0, 0}; 858cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(s, 0, sizeof(*s)); 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); 8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (fd < 0) 864cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -errno; 8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(&header, 0, sizeof(header)); 8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.magic = cpu_to_be32(QCOW_MAGIC); 8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.version = cpu_to_be32(QCOW_VERSION); 8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.size = cpu_to_be64(total_size * 512); 8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header_size = sizeof(header); 8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner backing_filename_len = 0; 8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (backing_file) { 8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (backing_format) { 8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT; 8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner backing_format_len = strlen(backing_format); 875cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ext_bf.len = backing_format_len; 876cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner rounded_ext_bf_len = (sizeof(ext_bf) + ext_bf.len + 7) & ~7; 877cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner header_size += rounded_ext_bf_len; 8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.backing_file_offset = cpu_to_be64(header_size); 8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner backing_filename_len = strlen(backing_file); 8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.backing_file_size = cpu_to_be32(backing_filename_len); 8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header_size += backing_filename_len; 8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Cluster size */ 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_bits = get_bits_from_size(cluster_size); 8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s->cluster_bits < MIN_CLUSTER_BITS || 8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_bits > MAX_CLUSTER_BITS) 8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "Cluster size must be a power of two between " 8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "%d and %dk\n", 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1 << MIN_CLUSTER_BITS, 8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1 << (MAX_CLUSTER_BITS - 10)); 8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EINVAL; 8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->cluster_size = 1 << s->cluster_bits; 8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.cluster_bits = cpu_to_be32(s->cluster_bits); 8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header_size = (header_size + 7) & ~7; 9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (flags & BLOCK_FLAG_ENCRYPT) { 9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); 9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); 9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_bits = s->cluster_bits - 3; 9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner shift = s->cluster_bits + l2_bits; 9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift); 9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset = align_offset(header_size, s->cluster_size); 9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->l1_table_offset = offset; 9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.l1_table_offset = cpu_to_be64(s->l1_table_offset); 9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.l1_size = cpu_to_be32(l1_size); 9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size); 9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 914cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* count how many refcount blocks needed */ 915cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 916cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#define NUM_CLUSTERS(bytes) \ 917cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner (((bytes) + (s->cluster_size) - 1) / (s->cluster_size)) 918cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 919cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ref_clusters = NUM_CLUSTERS(NUM_CLUSTERS(offset) * sizeof(uint16_t)); 920cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 921cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner do { 922cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner uint64_t image_clusters; 923cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner old_ref_clusters = ref_clusters; 924cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 925cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Number of clusters used for the refcount table */ 926cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner reftable_clusters = NUM_CLUSTERS(ref_clusters * sizeof(uint64_t)); 927cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 928cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Number of clusters that the whole image will have */ 929cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner image_clusters = NUM_CLUSTERS(offset) + ref_clusters 930cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner + reftable_clusters; 931cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 932cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Number of refcount blocks needed for the image */ 933cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ref_clusters = NUM_CLUSTERS(image_clusters * sizeof(uint16_t)); 934cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 935cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } while (ref_clusters != old_ref_clusters); 936cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 937cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->refcount_table = qemu_mallocz(reftable_clusters * s->cluster_size); 9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table_offset = offset; 9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner header.refcount_table_offset = cpu_to_be64(offset); 941cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner header.refcount_table_clusters = cpu_to_be32(reftable_clusters); 942cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset += (reftable_clusters * s->cluster_size); 9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_block_offset = offset; 9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i=0; i < ref_clusters; i++) { 9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_table[i] = cpu_to_be64(offset); 9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner offset += s->cluster_size; 9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size); 9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* update refcounts */ 9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_create_refcount_update(s, 0, header_size); 9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_create_refcount_update(s, s->l1_table_offset, 9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l1_size * sizeof(uint64_t)); 956cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner qcow2_create_refcount_update(s, s->refcount_table_offset, 957cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner reftable_clusters * s->cluster_size); 9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qcow2_create_refcount_update(s, s->refcount_block_offset, 9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ref_clusters * s->cluster_size); 9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* write all the data */ 962cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, &header, sizeof(header)); 963cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != sizeof(header)) { 964cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 965cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 966cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 9675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (backing_file) { 9685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (backing_format_len) { 9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char zero[16]; 970cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int padding = rounded_ext_bf_len - (ext_bf.len + sizeof(ext_bf)); 9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(zero, 0, sizeof(zero)); 9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_to_be32s(&ext_bf.magic); 9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_to_be32s(&ext_bf.len); 975cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, &ext_bf, sizeof(ext_bf)); 976cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != sizeof(ext_bf)) { 977cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 978cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 9795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 980cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, backing_format, backing_format_len); 981cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != backing_format_len) { 982cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 983cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 984cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 985cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (padding > 0) { 986cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, zero, padding); 987cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != padding) { 988cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 989cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 990cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 991cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 992cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 993cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, backing_file, backing_filename_len); 994cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != backing_filename_len) { 995cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 996cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 999cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner lseek(fd, s->l1_table_offset, SEEK_SET); 10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tmp = 0; 10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0;i < l1_size; i++) { 1002cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, &tmp, sizeof(tmp)); 1003cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != sizeof(tmp)) { 1004cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 1005cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 1006cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1007cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1008cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner lseek(fd, s->refcount_table_offset, SEEK_SET); 1009cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, s->refcount_table, 1010cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner reftable_clusters * s->cluster_size); 1011cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != reftable_clusters * s->cluster_size) { 1012cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 1013cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 10145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1016cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner lseek(fd, s->refcount_block_offset, SEEK_SET); 1017cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qemu_write_full(fd, s->refcount_block, 1018cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ref_clusters * s->cluster_size); 1019cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret != ref_clusters * s->cluster_size) { 1020cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = -errno; 1021cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner goto exit; 1022cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1024cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = 0; 1025cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerexit: 10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->refcount_table); 10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(s->refcount_block); 10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd); 1029cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1030cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* Preallocate metadata */ 1031cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret == 0 && prealloc) { 1032cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BlockDriverState *bs; 1033cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BlockDriver *drv = bdrv_find_format("qcow2"); 1034cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner bs = bdrv_new(""); 1035cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner bdrv_open(bs, filename, BDRV_O_CACHE_WB | BDRV_O_RDWR, drv); 1036cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = preallocate(bs); 1037cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner bdrv_close(bs); 1038cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1039cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1040cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_create(const char *filename, QEMUOptionParameter *options) 10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *backing_file = NULL; 10465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *backing_fmt = NULL; 10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t sectors = 0; 10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int flags = 0; 10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size_t cluster_size = 65536; 1050cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int prealloc = 0; 10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Read out options */ 10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (options && options->name) { 10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!strcmp(options->name, BLOCK_OPT_SIZE)) { 10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sectors = options->value.n / 512; 10565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { 10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner backing_file = options->value.s; 10585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { 10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner backing_fmt = options->value.s; 10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { 10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; 10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { 10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (options->value.n) { 10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_size = options->value.n; 10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1066cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { 1067cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (!options->value.s || !strcmp(options->value.s, "off")) { 1068cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner prealloc = 0; 1069cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else if (!strcmp(options->value.s, "metadata")) { 1070cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner prealloc = 1; 1071cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } else { 1072cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Invalid preallocation mode: '%s'\n", 1073cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner options->value.s); 1074cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -EINVAL; 1075cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner options++; 10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1080cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (backing_file && prealloc) { 1081cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner fprintf(stderr, "Backing file and preallocation cannot be used at " 1082cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner "the same time\n"); 1083cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -EINVAL; 1084cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1085cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return qcow_create2(filename, sectors, backing_file, backing_fmt, flags, 1087cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cluster_size, prealloc); 10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_make_empty(BlockDriverState *bs) 10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* XXX: not correct */ 10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t l1_length = s->l1_size * sizeof(uint64_t); 10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(s->l1_table, 0, l1_length); 1099cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0) 11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 1101cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length); 11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 11045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner l2_cache_reset(bs); 11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1110cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow2_truncate(BlockDriverState *bs, int64_t offset) 11117fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije{ 11127fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije BDRVQcowState *s = bs->opaque; 1113cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret, new_l1_size; 11147fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije 1115cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (offset & 511) { 1116cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -EINVAL; 11177fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije } 1118cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1119cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* cannot proceed if image has snapshots */ 1120cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (s->nb_snapshots) { 1121cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -ENOTSUP; 1122cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1123cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1124cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* shrinking is currently not supported */ 1125cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (offset < bs->total_sectors * 512) { 1126cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return -ENOTSUP; 1127cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1128cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1129cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner new_l1_size = size_to_l1(s, offset); 1130cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = qcow2_grow_l1_table(bs, new_l1_size); 1131cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 1132cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 1133cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1134cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1135cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner /* write updated header.size */ 1136cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner offset = cpu_to_be64(offset); 1137cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), 1138cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner &offset, sizeof(uint64_t)); 1139cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (ret < 0) { 1140cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 1141cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner } 1142cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1143cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner s->l1_vm_state_index = new_l1_size; 11447fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije return 0; 11457fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije} 11467fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije 11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: put compressed sectors first, then all the cluster aligned 11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tables to avoid losing bytes in alignment */ 11495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, 11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const uint8_t *buf, int nb_sectors) 11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner z_stream strm; 11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret, out_len; 11555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *out_buf; 11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t cluster_offset; 11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (nb_sectors == 0) { 11595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* align end of file to a sector boundary to ease reading with 11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sector based I/Os */ 1161cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner cluster_offset = bdrv_getlength(bs->file); 11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset = (cluster_offset + 511) & ~511; 1163cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner bdrv_truncate(bs->file, cluster_offset); 11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (nb_sectors != s->cluster_sectors) 11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EINVAL; 11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); 11715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* best compression, small window, no zlib header */ 11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(&strm, 0, sizeof(strm)); 11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, 11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner Z_DEFLATED, -12, 11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9, Z_DEFAULT_STRATEGY); 11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret != 0) { 11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(out_buf); 11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strm.avail_in = s->cluster_size; 11835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strm.next_in = (uint8_t *)buf; 11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strm.avail_out = s->cluster_size; 11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strm.next_out = out_buf; 11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = deflate(&strm, Z_FINISH); 11885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret != Z_STREAM_END && ret != Z_OK) { 11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(out_buf); 11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner deflateEnd(&strm); 11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner out_len = strm.next_out - out_buf; 11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner deflateEnd(&strm); 11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret != Z_STREAM_END || out_len >= s->cluster_size) { 11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* could not compress: write normal cluster */ 11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_write(bs, sector_num, buf, s->cluster_sectors); 12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset = qcow2_alloc_compressed_cluster_offset(bs, 12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sector_num << 9, out_len); 12035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!cluster_offset) 12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 12055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cluster_offset &= s->cluster_offset_mask; 1206cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED); 1207cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) { 12085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(out_buf); 12095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 12105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free(out_buf); 12145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 12155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qcow_flush(BlockDriverState *bs) 12185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1219cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner bdrv_flush(bs->file); 1220cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner} 1221cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1222cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs, 1223cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 1224cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{ 1225cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return bdrv_aio_flush(bs->file, cb, opaque); 12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12287fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thijestatic int64_t qcow_vm_state_offset(BDRVQcowState *s) 12297fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije{ 1230cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); 12317fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije} 12327fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije 12335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 12355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdi->cluster_size = s->cluster_size; 12377fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije bdi->vm_state_offset = qcow_vm_state_offset(s); 12385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1242cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow_check(BlockDriverState *bs, BdrvCheckResult *result) 12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1244cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return qcow2_check_refcounts(bs, result); 12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dump_refcounts(BlockDriverState *bs) 12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BDRVQcowState *s = bs->opaque; 12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t nb_clusters, k, k1, size; 12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int refcount; 12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1254cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner size = bdrv_getlength(bs->file); 12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_clusters = size_to_clusters(s, size); 12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(k = 0; k < nb_clusters;) { 12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner k1 = k; 12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner refcount = get_refcount(bs, k); 12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner k++; 12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (k < nb_clusters && get_refcount(bs, k) == refcount) 12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner k++; 1262cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner printf("%" PRId64 ": refcount=%d nb=%" PRId64 "\n", k, refcount, 1263cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner k - k1); 12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 12675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1268cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t pos, int size) 12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 12717fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije BDRVQcowState *s = bs->opaque; 12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int growable = bs->growable; 1273cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner int ret; 12745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1275cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE); 12765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->growable = 1; 1277cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner ret = bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size); 12785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->growable = growable; 12795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1280cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner return ret; 12815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1283cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf, 12845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t pos, int size) 12855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 12867fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije BDRVQcowState *s = bs->opaque; 12875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int growable = bs->growable; 12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1290cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD); 12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->growable = 1; 12927fd67eba0b961d94a5d6baa8e3c3de37b729f738Ot ten Thije ret = bdrv_pread(bs, qcow_vm_state_offset(s) + pos, buf, size); 12935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->growable = growable; 12945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUOptionParameter qcow_create_options[] = { 12995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .name = BLOCK_OPT_SIZE, 13015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .type = OPT_SIZE, 13025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .help = "Virtual disk size" 13035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }, 13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .name = BLOCK_OPT_BACKING_FILE, 13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .type = OPT_STRING, 13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .help = "File name of a base image" 13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }, 13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 13105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .name = BLOCK_OPT_BACKING_FMT, 13115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .type = OPT_STRING, 13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .help = "Image format of the base image" 13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }, 13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 13155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .name = BLOCK_OPT_ENCRYPT, 13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .type = OPT_FLAG, 13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .help = "Encrypt the image" 13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }, 13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .name = BLOCK_OPT_CLUSTER_SIZE, 13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .type = OPT_SIZE, 13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .help = "qcow2 cluster size" 13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner }, 1324cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner { 1325cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .name = BLOCK_OPT_PREALLOC, 1326cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .type = OPT_STRING, 1327cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .help = "Preallocation mode (allowed values: off, metadata)" 1328cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner }, 13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { NULL } 13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}; 13315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriver bdrv_qcow2 = { 13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .format_name = "qcow2", 13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .instance_size = sizeof(BDRVQcowState), 13355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_probe = qcow_probe, 13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_open = qcow_open, 13375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_close = qcow_close, 13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_create = qcow_create, 13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_flush = qcow_flush, 13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_is_allocated = qcow_is_allocated, 13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_set_key = qcow_set_key, 13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_make_empty = qcow_make_empty, 13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1344cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_aio_readv = qcow_aio_readv, 1345cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_aio_writev = qcow_aio_writev, 1346cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_aio_flush = qcow_aio_flush, 1347cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1348cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_truncate = qcow2_truncate, 1349cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_write_compressed = qcow_write_compressed, 13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_snapshot_create = qcow2_snapshot_create, 13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_snapshot_goto = qcow2_snapshot_goto, 13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_snapshot_delete = qcow2_snapshot_delete, 13545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_snapshot_list = qcow2_snapshot_list, 13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_get_info = qcow_get_info, 13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1357cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_save_vmstate = qcow_save_vmstate, 1358cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_load_vmstate = qcow_load_vmstate, 1359cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner 1360cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner .bdrv_change_backing_file = qcow2_change_backing_file, 13615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .create_options = qcow_create_options, 13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .bdrv_check = qcow_check, 13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}; 13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bdrv_qcow2_init(void) 13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_register(&bdrv_qcow2); 13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerblock_init(bdrv_qcow2_init); 1372