1019d6b8fSAnthony Liguori /* 2019d6b8fSAnthony Liguori * Block driver for the QCOW format 3019d6b8fSAnthony Liguori * 4019d6b8fSAnthony Liguori * Copyright (c) 2004-2006 Fabrice Bellard 5019d6b8fSAnthony Liguori * 6019d6b8fSAnthony Liguori * Permission is hereby granted, free of charge, to any person obtaining a copy 7019d6b8fSAnthony Liguori * of this software and associated documentation files (the "Software"), to deal 8019d6b8fSAnthony Liguori * in the Software without restriction, including without limitation the rights 9019d6b8fSAnthony Liguori * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10019d6b8fSAnthony Liguori * copies of the Software, and to permit persons to whom the Software is 11019d6b8fSAnthony Liguori * furnished to do so, subject to the following conditions: 12019d6b8fSAnthony Liguori * 13019d6b8fSAnthony Liguori * The above copyright notice and this permission notice shall be included in 14019d6b8fSAnthony Liguori * all copies or substantial portions of the Software. 15019d6b8fSAnthony Liguori * 16019d6b8fSAnthony Liguori * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17019d6b8fSAnthony Liguori * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18019d6b8fSAnthony Liguori * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19019d6b8fSAnthony Liguori * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20019d6b8fSAnthony Liguori * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21019d6b8fSAnthony Liguori * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22019d6b8fSAnthony Liguori * THE SOFTWARE. 23019d6b8fSAnthony Liguori */ 24452fcdbcSMarkus Armbruster 2580c71a24SPeter Maydell #include "qemu/osdep.h" 26da34e65cSMarkus Armbruster #include "qapi/error.h" 27e6ff69bfSDaniel P. Berrange #include "qemu/error-report.h" 28737e150eSPaolo Bonzini #include "block/block_int.h" 296af40160SKevin Wolf #include "sysemu/block-backend.h" 301de7afc9SPaolo Bonzini #include "qemu/module.h" 31922a01a0SMarkus Armbruster #include "qemu/option.h" 3258369e22SPaolo Bonzini #include "qemu/bswap.h" 33019d6b8fSAnthony Liguori #include <zlib.h> 34452fcdbcSMarkus Armbruster #include "qapi/qmp/qdict.h" 35d85f4222SDaniel P. Berrange #include "qapi/qmp/qstring.h" 36d85f4222SDaniel P. Berrange #include "crypto/block.h" 37795c40b8SJuan Quintela #include "migration/blocker.h" 38d85f4222SDaniel P. Berrange #include "block/crypto.h" 39019d6b8fSAnthony Liguori 40019d6b8fSAnthony Liguori /**************************************************************/ 41019d6b8fSAnthony Liguori /* QEMU COW block driver with compression and encryption support */ 42019d6b8fSAnthony Liguori 43019d6b8fSAnthony Liguori #define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb) 44019d6b8fSAnthony Liguori #define QCOW_VERSION 1 45019d6b8fSAnthony Liguori 46019d6b8fSAnthony Liguori #define QCOW_CRYPT_NONE 0 47019d6b8fSAnthony Liguori #define QCOW_CRYPT_AES 1 48019d6b8fSAnthony Liguori 49019d6b8fSAnthony Liguori #define QCOW_OFLAG_COMPRESSED (1LL << 63) 50019d6b8fSAnthony Liguori 51019d6b8fSAnthony Liguori typedef struct QCowHeader { 52019d6b8fSAnthony Liguori uint32_t magic; 53019d6b8fSAnthony Liguori uint32_t version; 54019d6b8fSAnthony Liguori uint64_t backing_file_offset; 55019d6b8fSAnthony Liguori uint32_t backing_file_size; 56019d6b8fSAnthony Liguori uint32_t mtime; 57019d6b8fSAnthony Liguori uint64_t size; /* in bytes */ 58019d6b8fSAnthony Liguori uint8_t cluster_bits; 59019d6b8fSAnthony Liguori uint8_t l2_bits; 60ea54feffSKevin Wolf uint16_t padding; 61019d6b8fSAnthony Liguori uint32_t crypt_method; 62019d6b8fSAnthony Liguori uint64_t l1_table_offset; 63ea54feffSKevin Wolf } QEMU_PACKED QCowHeader; 64019d6b8fSAnthony Liguori 65019d6b8fSAnthony Liguori #define L2_CACHE_SIZE 16 66019d6b8fSAnthony Liguori 67019d6b8fSAnthony Liguori typedef struct BDRVQcowState { 68019d6b8fSAnthony Liguori int cluster_bits; 69019d6b8fSAnthony Liguori int cluster_size; 70019d6b8fSAnthony Liguori int cluster_sectors; 71019d6b8fSAnthony Liguori int l2_bits; 72019d6b8fSAnthony Liguori int l2_size; 7346485de0SKevin Wolf unsigned int l1_size; 74019d6b8fSAnthony Liguori uint64_t cluster_offset_mask; 75019d6b8fSAnthony Liguori uint64_t l1_table_offset; 76019d6b8fSAnthony Liguori uint64_t *l1_table; 77019d6b8fSAnthony Liguori uint64_t *l2_cache; 78019d6b8fSAnthony Liguori uint64_t l2_cache_offsets[L2_CACHE_SIZE]; 79019d6b8fSAnthony Liguori uint32_t l2_cache_counts[L2_CACHE_SIZE]; 80019d6b8fSAnthony Liguori uint8_t *cluster_cache; 81019d6b8fSAnthony Liguori uint8_t *cluster_data; 82019d6b8fSAnthony Liguori uint64_t cluster_cache_offset; 83d85f4222SDaniel P. Berrange QCryptoBlock *crypto; /* Disk encryption format driver */ 84019d6b8fSAnthony Liguori uint32_t crypt_method_header; 8552b8eb60SKevin Wolf CoMutex lock; 86fd9f102cSKevin Wolf Error *migration_blocker; 87019d6b8fSAnthony Liguori } BDRVQcowState; 88019d6b8fSAnthony Liguori 8966f82ceeSKevin Wolf static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); 90019d6b8fSAnthony Liguori 91019d6b8fSAnthony Liguori static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) 92019d6b8fSAnthony Liguori { 93019d6b8fSAnthony Liguori const QCowHeader *cow_header = (const void *)buf; 94019d6b8fSAnthony Liguori 95019d6b8fSAnthony Liguori if (buf_size >= sizeof(QCowHeader) && 96019d6b8fSAnthony Liguori be32_to_cpu(cow_header->magic) == QCOW_MAGIC && 97019d6b8fSAnthony Liguori be32_to_cpu(cow_header->version) == QCOW_VERSION) 98019d6b8fSAnthony Liguori return 100; 99019d6b8fSAnthony Liguori else 100019d6b8fSAnthony Liguori return 0; 101019d6b8fSAnthony Liguori } 102019d6b8fSAnthony Liguori 103d85f4222SDaniel P. Berrange static QemuOptsList qcow_runtime_opts = { 104d85f4222SDaniel P. Berrange .name = "qcow", 105d85f4222SDaniel P. Berrange .head = QTAILQ_HEAD_INITIALIZER(qcow_runtime_opts.head), 106d85f4222SDaniel P. Berrange .desc = { 107d85f4222SDaniel P. Berrange BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), 108d85f4222SDaniel P. Berrange { /* end of list */ } 109d85f4222SDaniel P. Berrange }, 110d85f4222SDaniel P. Berrange }; 111d85f4222SDaniel P. Berrange 112015a1036SMax Reitz static int qcow_open(BlockDriverState *bs, QDict *options, int flags, 113015a1036SMax Reitz Error **errp) 114019d6b8fSAnthony Liguori { 115019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 116d66e5ceeSKevin Wolf unsigned int len, i, shift; 117d66e5ceeSKevin Wolf int ret; 118019d6b8fSAnthony Liguori QCowHeader header; 119fe44dc91SAshijeet Acharya Error *local_err = NULL; 120d85f4222SDaniel P. Berrange QCryptoBlockOpenOptions *crypto_opts = NULL; 121d85f4222SDaniel P. Berrange unsigned int cflags = 0; 122d85f4222SDaniel P. Berrange QDict *encryptopts = NULL; 123d85f4222SDaniel P. Berrange const char *encryptfmt; 124d85f4222SDaniel P. Berrange 125d85f4222SDaniel P. Berrange qdict_extract_subqdict(options, &encryptopts, "encrypt."); 126d85f4222SDaniel P. Berrange encryptfmt = qdict_get_try_str(encryptopts, "format"); 127019d6b8fSAnthony Liguori 1284e4bf5c4SKevin Wolf bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 1294e4bf5c4SKevin Wolf false, errp); 1304e4bf5c4SKevin Wolf if (!bs->file) { 131d85f4222SDaniel P. Berrange ret = -EINVAL; 132d85f4222SDaniel P. Berrange goto fail; 1334e4bf5c4SKevin Wolf } 1344e4bf5c4SKevin Wolf 135cf2ab8fcSKevin Wolf ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); 13684b0ec02SLi Zhi Hui if (ret < 0) { 137019d6b8fSAnthony Liguori goto fail; 13884b0ec02SLi Zhi Hui } 139019d6b8fSAnthony Liguori be32_to_cpus(&header.magic); 140019d6b8fSAnthony Liguori be32_to_cpus(&header.version); 141019d6b8fSAnthony Liguori be64_to_cpus(&header.backing_file_offset); 142019d6b8fSAnthony Liguori be32_to_cpus(&header.backing_file_size); 143019d6b8fSAnthony Liguori be32_to_cpus(&header.mtime); 144019d6b8fSAnthony Liguori be64_to_cpus(&header.size); 145019d6b8fSAnthony Liguori be32_to_cpus(&header.crypt_method); 146019d6b8fSAnthony Liguori be64_to_cpus(&header.l1_table_offset); 147019d6b8fSAnthony Liguori 14884b0ec02SLi Zhi Hui if (header.magic != QCOW_MAGIC) { 14976abe407SPaolo Bonzini error_setg(errp, "Image not in qcow format"); 15076abe407SPaolo Bonzini ret = -EINVAL; 151019d6b8fSAnthony Liguori goto fail; 15284b0ec02SLi Zhi Hui } 15384b0ec02SLi Zhi Hui if (header.version != QCOW_VERSION) { 154a55448b3SMax Reitz error_setg(errp, "Unsupported qcow version %" PRIu32, header.version); 15584b0ec02SLi Zhi Hui ret = -ENOTSUP; 156019d6b8fSAnthony Liguori goto fail; 15784b0ec02SLi Zhi Hui } 15884b0ec02SLi Zhi Hui 1597159a45bSKevin Wolf if (header.size <= 1) { 1607159a45bSKevin Wolf error_setg(errp, "Image size is too small (must be at least 2 bytes)"); 16184b0ec02SLi Zhi Hui ret = -EINVAL; 162019d6b8fSAnthony Liguori goto fail; 16384b0ec02SLi Zhi Hui } 1647159a45bSKevin Wolf if (header.cluster_bits < 9 || header.cluster_bits > 16) { 1657159a45bSKevin Wolf error_setg(errp, "Cluster size must be between 512 and 64k"); 1667159a45bSKevin Wolf ret = -EINVAL; 1677159a45bSKevin Wolf goto fail; 1687159a45bSKevin Wolf } 1697159a45bSKevin Wolf 17042eb5817SKevin Wolf /* l2_bits specifies number of entries; storing a uint64_t in each entry, 17142eb5817SKevin Wolf * so bytes = num_entries << 3. */ 17242eb5817SKevin Wolf if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) { 17342eb5817SKevin Wolf error_setg(errp, "L2 table size must be between 512 and 64k"); 17442eb5817SKevin Wolf ret = -EINVAL; 17542eb5817SKevin Wolf goto fail; 17642eb5817SKevin Wolf } 17742eb5817SKevin Wolf 178019d6b8fSAnthony Liguori s->crypt_method_header = header.crypt_method; 17984b0ec02SLi Zhi Hui if (s->crypt_method_header) { 180e6ff69bfSDaniel P. Berrange if (bdrv_uses_whitelist() && 181e6ff69bfSDaniel P. Berrange s->crypt_method_header == QCOW_CRYPT_AES) { 1828c0dcbc4SDaniel P. Berrange error_setg(errp, 1838c0dcbc4SDaniel P. Berrange "Use of AES-CBC encrypted qcow images is no longer " 1848c0dcbc4SDaniel P. Berrange "supported in system emulators"); 1858c0dcbc4SDaniel P. Berrange error_append_hint(errp, 1868c0dcbc4SDaniel P. Berrange "You can use 'qemu-img convert' to convert your " 1878c0dcbc4SDaniel P. Berrange "image to an alternative supported format, such " 1888c0dcbc4SDaniel P. Berrange "as unencrypted qcow, or raw with the LUKS " 1898c0dcbc4SDaniel P. Berrange "format instead.\n"); 1908c0dcbc4SDaniel P. Berrange ret = -ENOSYS; 1918c0dcbc4SDaniel P. Berrange goto fail; 192e6ff69bfSDaniel P. Berrange } 193d85f4222SDaniel P. Berrange if (s->crypt_method_header == QCOW_CRYPT_AES) { 194d85f4222SDaniel P. Berrange if (encryptfmt && !g_str_equal(encryptfmt, "aes")) { 195d85f4222SDaniel P. Berrange error_setg(errp, 196d85f4222SDaniel P. Berrange "Header reported 'aes' encryption format but " 197d85f4222SDaniel P. Berrange "options specify '%s'", encryptfmt); 198d85f4222SDaniel P. Berrange ret = -EINVAL; 199d85f4222SDaniel P. Berrange goto fail; 200d85f4222SDaniel P. Berrange } 201d85f4222SDaniel P. Berrange qdict_del(encryptopts, "format"); 202d85f4222SDaniel P. Berrange crypto_opts = block_crypto_open_opts_init( 203d85f4222SDaniel P. Berrange Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); 204d85f4222SDaniel P. Berrange if (!crypto_opts) { 205d85f4222SDaniel P. Berrange ret = -EINVAL; 206d85f4222SDaniel P. Berrange goto fail; 207d85f4222SDaniel P. Berrange } 208e6ff69bfSDaniel P. Berrange 209d85f4222SDaniel P. Berrange if (flags & BDRV_O_NO_IO) { 210d85f4222SDaniel P. Berrange cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; 211d85f4222SDaniel P. Berrange } 2121cd9a787SDaniel P. Berrange s->crypto = qcrypto_block_open(crypto_opts, "encrypt.", 2131cd9a787SDaniel P. Berrange NULL, NULL, cflags, errp); 214d85f4222SDaniel P. Berrange if (!s->crypto) { 215d85f4222SDaniel P. Berrange ret = -EINVAL; 216d85f4222SDaniel P. Berrange goto fail; 217d85f4222SDaniel P. Berrange } 218d85f4222SDaniel P. Berrange } else { 219d85f4222SDaniel P. Berrange error_setg(errp, "invalid encryption method in qcow header"); 220d85f4222SDaniel P. Berrange ret = -EINVAL; 221d85f4222SDaniel P. Berrange goto fail; 222d85f4222SDaniel P. Berrange } 22354115412SEric Blake bs->encrypted = true; 224c01c214bSDaniel P. Berrange } else { 225c01c214bSDaniel P. Berrange if (encryptfmt) { 226c01c214bSDaniel P. Berrange error_setg(errp, "No encryption in image header, but options " 227c01c214bSDaniel P. Berrange "specified format '%s'", encryptfmt); 228c01c214bSDaniel P. Berrange ret = -EINVAL; 229c01c214bSDaniel P. Berrange goto fail; 230c01c214bSDaniel P. Berrange } 23184b0ec02SLi Zhi Hui } 232019d6b8fSAnthony Liguori s->cluster_bits = header.cluster_bits; 233019d6b8fSAnthony Liguori s->cluster_size = 1 << s->cluster_bits; 234019d6b8fSAnthony Liguori s->cluster_sectors = 1 << (s->cluster_bits - 9); 235019d6b8fSAnthony Liguori s->l2_bits = header.l2_bits; 236019d6b8fSAnthony Liguori s->l2_size = 1 << s->l2_bits; 237019d6b8fSAnthony Liguori bs->total_sectors = header.size / 512; 238019d6b8fSAnthony Liguori s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1; 239019d6b8fSAnthony Liguori 240019d6b8fSAnthony Liguori /* read the level 1 table */ 241019d6b8fSAnthony Liguori shift = s->cluster_bits + s->l2_bits; 24246485de0SKevin Wolf if (header.size > UINT64_MAX - (1LL << shift)) { 24346485de0SKevin Wolf error_setg(errp, "Image too large"); 24446485de0SKevin Wolf ret = -EINVAL; 24546485de0SKevin Wolf goto fail; 24646485de0SKevin Wolf } else { 24746485de0SKevin Wolf uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift; 24846485de0SKevin Wolf if (l1_size > INT_MAX / sizeof(uint64_t)) { 24946485de0SKevin Wolf error_setg(errp, "Image too large"); 25046485de0SKevin Wolf ret = -EINVAL; 25146485de0SKevin Wolf goto fail; 25246485de0SKevin Wolf } 25346485de0SKevin Wolf s->l1_size = l1_size; 25446485de0SKevin Wolf } 255019d6b8fSAnthony Liguori 256019d6b8fSAnthony Liguori s->l1_table_offset = header.l1_table_offset; 2575839e53bSMarkus Armbruster s->l1_table = g_try_new(uint64_t, s->l1_size); 2580df93305SKevin Wolf if (s->l1_table == NULL) { 2590df93305SKevin Wolf error_setg(errp, "Could not allocate memory for L1 table"); 2600df93305SKevin Wolf ret = -ENOMEM; 2610df93305SKevin Wolf goto fail; 2620df93305SKevin Wolf } 26384b0ec02SLi Zhi Hui 264cf2ab8fcSKevin Wolf ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, 26584b0ec02SLi Zhi Hui s->l1_size * sizeof(uint64_t)); 26684b0ec02SLi Zhi Hui if (ret < 0) { 267019d6b8fSAnthony Liguori goto fail; 26884b0ec02SLi Zhi Hui } 26984b0ec02SLi Zhi Hui 270019d6b8fSAnthony Liguori for(i = 0;i < s->l1_size; i++) { 271019d6b8fSAnthony Liguori be64_to_cpus(&s->l1_table[i]); 272019d6b8fSAnthony Liguori } 2730df93305SKevin Wolf 2740df93305SKevin Wolf /* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */ 2750df93305SKevin Wolf s->l2_cache = 2769a4f4c31SKevin Wolf qemu_try_blockalign(bs->file->bs, 2770df93305SKevin Wolf s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); 2780df93305SKevin Wolf if (s->l2_cache == NULL) { 2790df93305SKevin Wolf error_setg(errp, "Could not allocate L2 table cache"); 2800df93305SKevin Wolf ret = -ENOMEM; 2810df93305SKevin Wolf goto fail; 2820df93305SKevin Wolf } 2837267c094SAnthony Liguori s->cluster_cache = g_malloc(s->cluster_size); 2847267c094SAnthony Liguori s->cluster_data = g_malloc(s->cluster_size); 285019d6b8fSAnthony Liguori s->cluster_cache_offset = -1; 286019d6b8fSAnthony Liguori 287019d6b8fSAnthony Liguori /* read the backing file name */ 288019d6b8fSAnthony Liguori if (header.backing_file_offset != 0) { 289019d6b8fSAnthony Liguori len = header.backing_file_size; 290e729fa6aSJeff Cody if (len > 1023 || len >= sizeof(bs->backing_file)) { 291d66e5ceeSKevin Wolf error_setg(errp, "Backing file name too long"); 292d66e5ceeSKevin Wolf ret = -EINVAL; 293d66e5ceeSKevin Wolf goto fail; 29484b0ec02SLi Zhi Hui } 295cf2ab8fcSKevin Wolf ret = bdrv_pread(bs->file, header.backing_file_offset, 29684b0ec02SLi Zhi Hui bs->backing_file, len); 29784b0ec02SLi Zhi Hui if (ret < 0) { 298019d6b8fSAnthony Liguori goto fail; 29984b0ec02SLi Zhi Hui } 300019d6b8fSAnthony Liguori bs->backing_file[len] = '\0'; 301019d6b8fSAnthony Liguori } 302de33b1f3SScott Wood 303fd9f102cSKevin Wolf /* Disable migration when qcow images are used */ 30481e5f78aSAlberto Garcia error_setg(&s->migration_blocker, "The qcow format used by node '%s' " 30581e5f78aSAlberto Garcia "does not support live migration", 30681e5f78aSAlberto Garcia bdrv_get_device_or_node_name(bs)); 307fe44dc91SAshijeet Acharya ret = migrate_add_blocker(s->migration_blocker, &local_err); 308fe44dc91SAshijeet Acharya if (local_err) { 309fe44dc91SAshijeet Acharya error_propagate(errp, local_err); 310fe44dc91SAshijeet Acharya error_free(s->migration_blocker); 311fe44dc91SAshijeet Acharya goto fail; 312fe44dc91SAshijeet Acharya } 313fd9f102cSKevin Wolf 314d85f4222SDaniel P. Berrange QDECREF(encryptopts); 315d85f4222SDaniel P. Berrange qapi_free_QCryptoBlockOpenOptions(crypto_opts); 316de33b1f3SScott Wood qemu_co_mutex_init(&s->lock); 317019d6b8fSAnthony Liguori return 0; 318019d6b8fSAnthony Liguori 319019d6b8fSAnthony Liguori fail: 3207267c094SAnthony Liguori g_free(s->l1_table); 3210df93305SKevin Wolf qemu_vfree(s->l2_cache); 3227267c094SAnthony Liguori g_free(s->cluster_cache); 3237267c094SAnthony Liguori g_free(s->cluster_data); 324d85f4222SDaniel P. Berrange qcrypto_block_free(s->crypto); 325d85f4222SDaniel P. Berrange QDECREF(encryptopts); 326d85f4222SDaniel P. Berrange qapi_free_QCryptoBlockOpenOptions(crypto_opts); 32784b0ec02SLi Zhi Hui return ret; 328019d6b8fSAnthony Liguori } 329019d6b8fSAnthony Liguori 330d177692eSJeff Cody 331d177692eSJeff Cody /* We have nothing to do for QCOW reopen, stubs just return 332d177692eSJeff Cody * success */ 333d177692eSJeff Cody static int qcow_reopen_prepare(BDRVReopenState *state, 334d177692eSJeff Cody BlockReopenQueue *queue, Error **errp) 335d177692eSJeff Cody { 336d177692eSJeff Cody return 0; 337d177692eSJeff Cody } 338d177692eSJeff Cody 339019d6b8fSAnthony Liguori 340019d6b8fSAnthony Liguori /* 'allocate' is: 341019d6b8fSAnthony Liguori * 342019d6b8fSAnthony Liguori * 0 to not allocate. 343019d6b8fSAnthony Liguori * 344019d6b8fSAnthony Liguori * 1 to allocate a normal cluster (for sector indexes 'n_start' to 345019d6b8fSAnthony Liguori * 'n_end') 346019d6b8fSAnthony Liguori * 347019d6b8fSAnthony Liguori * 2 to allocate a compressed cluster of size 348019d6b8fSAnthony Liguori * 'compressed_size'. 'compressed_size' must be > 0 and < 349019d6b8fSAnthony Liguori * cluster_size 350019d6b8fSAnthony Liguori * 35156439e9dSEric Blake * return 0 if not allocated, 1 if *result is assigned, and negative 35256439e9dSEric Blake * errno on failure. 353019d6b8fSAnthony Liguori */ 35456439e9dSEric Blake static int get_cluster_offset(BlockDriverState *bs, 355019d6b8fSAnthony Liguori uint64_t offset, int allocate, 356019d6b8fSAnthony Liguori int compressed_size, 35756439e9dSEric Blake int n_start, int n_end, uint64_t *result) 358019d6b8fSAnthony Liguori { 359019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 36056439e9dSEric Blake int min_index, i, j, l1_index, l2_index, ret; 361d7a753a1SEric Blake int64_t l2_offset; 362d7a753a1SEric Blake uint64_t *l2_table, cluster_offset, tmp; 363019d6b8fSAnthony Liguori uint32_t min_count; 364019d6b8fSAnthony Liguori int new_l2_table; 365019d6b8fSAnthony Liguori 36656439e9dSEric Blake *result = 0; 367019d6b8fSAnthony Liguori l1_index = offset >> (s->l2_bits + s->cluster_bits); 368019d6b8fSAnthony Liguori l2_offset = s->l1_table[l1_index]; 369019d6b8fSAnthony Liguori new_l2_table = 0; 370019d6b8fSAnthony Liguori if (!l2_offset) { 371019d6b8fSAnthony Liguori if (!allocate) 372019d6b8fSAnthony Liguori return 0; 373019d6b8fSAnthony Liguori /* allocate a new l2 entry */ 3749a4f4c31SKevin Wolf l2_offset = bdrv_getlength(bs->file->bs); 375d7a753a1SEric Blake if (l2_offset < 0) { 376d7a753a1SEric Blake return l2_offset; 377d7a753a1SEric Blake } 378019d6b8fSAnthony Liguori /* round to cluster size */ 379d7a753a1SEric Blake l2_offset = QEMU_ALIGN_UP(l2_offset, s->cluster_size); 380019d6b8fSAnthony Liguori /* update the L1 entry */ 381019d6b8fSAnthony Liguori s->l1_table[l1_index] = l2_offset; 382019d6b8fSAnthony Liguori tmp = cpu_to_be64(l2_offset); 3830abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); 38456439e9dSEric Blake ret = bdrv_pwrite_sync(bs->file, 3855e5557d9SKevin Wolf s->l1_table_offset + l1_index * sizeof(tmp), 38656439e9dSEric Blake &tmp, sizeof(tmp)); 38756439e9dSEric Blake if (ret < 0) { 38856439e9dSEric Blake return ret; 38956439e9dSEric Blake } 390019d6b8fSAnthony Liguori new_l2_table = 1; 391019d6b8fSAnthony Liguori } 392019d6b8fSAnthony Liguori for(i = 0; i < L2_CACHE_SIZE; i++) { 393019d6b8fSAnthony Liguori if (l2_offset == s->l2_cache_offsets[i]) { 394019d6b8fSAnthony Liguori /* increment the hit count */ 395019d6b8fSAnthony Liguori if (++s->l2_cache_counts[i] == 0xffffffff) { 396019d6b8fSAnthony Liguori for(j = 0; j < L2_CACHE_SIZE; j++) { 397019d6b8fSAnthony Liguori s->l2_cache_counts[j] >>= 1; 398019d6b8fSAnthony Liguori } 399019d6b8fSAnthony Liguori } 400019d6b8fSAnthony Liguori l2_table = s->l2_cache + (i << s->l2_bits); 401019d6b8fSAnthony Liguori goto found; 402019d6b8fSAnthony Liguori } 403019d6b8fSAnthony Liguori } 404019d6b8fSAnthony Liguori /* not found: load a new entry in the least used one */ 405019d6b8fSAnthony Liguori min_index = 0; 406019d6b8fSAnthony Liguori min_count = 0xffffffff; 407019d6b8fSAnthony Liguori for(i = 0; i < L2_CACHE_SIZE; i++) { 408019d6b8fSAnthony Liguori if (s->l2_cache_counts[i] < min_count) { 409019d6b8fSAnthony Liguori min_count = s->l2_cache_counts[i]; 410019d6b8fSAnthony Liguori min_index = i; 411019d6b8fSAnthony Liguori } 412019d6b8fSAnthony Liguori } 413019d6b8fSAnthony Liguori l2_table = s->l2_cache + (min_index << s->l2_bits); 4140abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); 415019d6b8fSAnthony Liguori if (new_l2_table) { 416019d6b8fSAnthony Liguori memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); 41756439e9dSEric Blake ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table, 41856439e9dSEric Blake s->l2_size * sizeof(uint64_t)); 41956439e9dSEric Blake if (ret < 0) { 42056439e9dSEric Blake return ret; 42156439e9dSEric Blake } 422019d6b8fSAnthony Liguori } else { 42356439e9dSEric Blake ret = bdrv_pread(bs->file, l2_offset, l2_table, 42456439e9dSEric Blake s->l2_size * sizeof(uint64_t)); 42556439e9dSEric Blake if (ret < 0) { 42656439e9dSEric Blake return ret; 42756439e9dSEric Blake } 428019d6b8fSAnthony Liguori } 429019d6b8fSAnthony Liguori s->l2_cache_offsets[min_index] = l2_offset; 430019d6b8fSAnthony Liguori s->l2_cache_counts[min_index] = 1; 431019d6b8fSAnthony Liguori found: 432019d6b8fSAnthony Liguori l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); 433019d6b8fSAnthony Liguori cluster_offset = be64_to_cpu(l2_table[l2_index]); 434019d6b8fSAnthony Liguori if (!cluster_offset || 435019d6b8fSAnthony Liguori ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) { 436019d6b8fSAnthony Liguori if (!allocate) 437019d6b8fSAnthony Liguori return 0; 4380abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC); 439019d6b8fSAnthony Liguori /* allocate a new cluster */ 440019d6b8fSAnthony Liguori if ((cluster_offset & QCOW_OFLAG_COMPRESSED) && 441019d6b8fSAnthony Liguori (n_end - n_start) < s->cluster_sectors) { 442019d6b8fSAnthony Liguori /* if the cluster is already compressed, we must 443019d6b8fSAnthony Liguori decompress it in the case it is not completely 444019d6b8fSAnthony Liguori overwritten */ 44556439e9dSEric Blake if (decompress_cluster(bs, cluster_offset) < 0) { 44656439e9dSEric Blake return -EIO; 44756439e9dSEric Blake } 4489a4f4c31SKevin Wolf cluster_offset = bdrv_getlength(bs->file->bs); 449d7a753a1SEric Blake if ((int64_t) cluster_offset < 0) { 450d7a753a1SEric Blake return cluster_offset; 451d7a753a1SEric Blake } 452d7a753a1SEric Blake cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size); 453019d6b8fSAnthony Liguori /* write the cluster content */ 4540abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); 45556439e9dSEric Blake ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache, 45656439e9dSEric Blake s->cluster_size); 45756439e9dSEric Blake if (ret < 0) { 45856439e9dSEric Blake return ret; 45956439e9dSEric Blake } 460019d6b8fSAnthony Liguori } else { 4619a4f4c31SKevin Wolf cluster_offset = bdrv_getlength(bs->file->bs); 462d7a753a1SEric Blake if ((int64_t) cluster_offset < 0) { 463d7a753a1SEric Blake return cluster_offset; 464d7a753a1SEric Blake } 465019d6b8fSAnthony Liguori if (allocate == 1) { 466019d6b8fSAnthony Liguori /* round to cluster size */ 467d7a753a1SEric Blake cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size); 468d7a753a1SEric Blake if (cluster_offset + s->cluster_size > INT64_MAX) { 469d7a753a1SEric Blake return -E2BIG; 470d7a753a1SEric Blake } 471d7a753a1SEric Blake ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size, 4727ea37c30SMax Reitz PREALLOC_MODE_OFF, NULL); 473d7a753a1SEric Blake if (ret < 0) { 474d7a753a1SEric Blake return ret; 475d7a753a1SEric Blake } 476019d6b8fSAnthony Liguori /* if encrypted, we must initialize the cluster 477019d6b8fSAnthony Liguori content which won't be written */ 4788336aafaSDaniel P. Berrange if (bs->encrypted && 479019d6b8fSAnthony Liguori (n_end - n_start) < s->cluster_sectors) { 480019d6b8fSAnthony Liguori uint64_t start_sect; 481d85f4222SDaniel P. Berrange assert(s->crypto); 482019d6b8fSAnthony Liguori start_sect = (offset & ~(s->cluster_size - 1)) >> 9; 483019d6b8fSAnthony Liguori for(i = 0; i < s->cluster_sectors; i++) { 484019d6b8fSAnthony Liguori if (i < n_start || i >= n_end) { 4851fad1f94SDaniel P. Berrange memset(s->cluster_data, 0x00, 512); 4864609742aSDaniel P. Berrange if (qcrypto_block_encrypt(s->crypto, 4874609742aSDaniel P. Berrange (start_sect + i) * 4884609742aSDaniel P. Berrange BDRV_SECTOR_SIZE, 489d85f4222SDaniel P. Berrange s->cluster_data, 490d85f4222SDaniel P. Berrange BDRV_SECTOR_SIZE, 491c3a8fe33SAlberto Garcia NULL) < 0) { 49256439e9dSEric Blake return -EIO; 493f6fa64f6SDaniel P. Berrange } 4940abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); 49556439e9dSEric Blake ret = bdrv_pwrite(bs->file, 4969a4f4c31SKevin Wolf cluster_offset + i * 512, 49756439e9dSEric Blake s->cluster_data, 512); 49856439e9dSEric Blake if (ret < 0) { 49956439e9dSEric Blake return ret; 50056439e9dSEric Blake } 501019d6b8fSAnthony Liguori } 502019d6b8fSAnthony Liguori } 503019d6b8fSAnthony Liguori } 504019d6b8fSAnthony Liguori } else if (allocate == 2) { 505019d6b8fSAnthony Liguori cluster_offset |= QCOW_OFLAG_COMPRESSED | 506019d6b8fSAnthony Liguori (uint64_t)compressed_size << (63 - s->cluster_bits); 507019d6b8fSAnthony Liguori } 508019d6b8fSAnthony Liguori } 509019d6b8fSAnthony Liguori /* update L2 table */ 510019d6b8fSAnthony Liguori tmp = cpu_to_be64(cluster_offset); 511019d6b8fSAnthony Liguori l2_table[l2_index] = tmp; 5120abb1475SMax Reitz if (allocate == 2) { 5130abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); 5140abb1475SMax Reitz } else { 5150abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); 5160abb1475SMax Reitz } 51756439e9dSEric Blake ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), 51856439e9dSEric Blake &tmp, sizeof(tmp)); 51956439e9dSEric Blake if (ret < 0) { 52056439e9dSEric Blake return ret; 521019d6b8fSAnthony Liguori } 52256439e9dSEric Blake } 52356439e9dSEric Blake *result = cluster_offset; 52456439e9dSEric Blake return 1; 525019d6b8fSAnthony Liguori } 526019d6b8fSAnthony Liguori 527*d63b4c93SEric Blake static int coroutine_fn qcow_co_block_status(BlockDriverState *bs, 528*d63b4c93SEric Blake bool want_zero, 529*d63b4c93SEric Blake int64_t offset, int64_t bytes, 530*d63b4c93SEric Blake int64_t *pnum, int64_t *map, 531*d63b4c93SEric Blake BlockDriverState **file) 532019d6b8fSAnthony Liguori { 533019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 534*d63b4c93SEric Blake int index_in_cluster, ret; 535*d63b4c93SEric Blake int64_t n; 536019d6b8fSAnthony Liguori uint64_t cluster_offset; 537019d6b8fSAnthony Liguori 538f8a2e5e3SStefan Hajnoczi qemu_co_mutex_lock(&s->lock); 539*d63b4c93SEric Blake ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset); 540f8a2e5e3SStefan Hajnoczi qemu_co_mutex_unlock(&s->lock); 54156439e9dSEric Blake if (ret < 0) { 54256439e9dSEric Blake return ret; 54356439e9dSEric Blake } 544*d63b4c93SEric Blake index_in_cluster = offset & (s->cluster_size - 1); 545*d63b4c93SEric Blake n = s->cluster_size - index_in_cluster; 546*d63b4c93SEric Blake if (n > bytes) { 547*d63b4c93SEric Blake n = bytes; 548*d63b4c93SEric Blake } 549019d6b8fSAnthony Liguori *pnum = n; 5504bc74be9SPaolo Bonzini if (!cluster_offset) { 5514bc74be9SPaolo Bonzini return 0; 5524bc74be9SPaolo Bonzini } 553d85f4222SDaniel P. Berrange if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypto) { 5544bc74be9SPaolo Bonzini return BDRV_BLOCK_DATA; 5554bc74be9SPaolo Bonzini } 556*d63b4c93SEric Blake *map = cluster_offset | index_in_cluster; 5573064bf6fSFam Zheng *file = bs->file->bs; 558*d63b4c93SEric Blake return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; 559019d6b8fSAnthony Liguori } 560019d6b8fSAnthony Liguori 561019d6b8fSAnthony Liguori static int decompress_buffer(uint8_t *out_buf, int out_buf_size, 562019d6b8fSAnthony Liguori const uint8_t *buf, int buf_size) 563019d6b8fSAnthony Liguori { 564019d6b8fSAnthony Liguori z_stream strm1, *strm = &strm1; 565019d6b8fSAnthony Liguori int ret, out_len; 566019d6b8fSAnthony Liguori 567019d6b8fSAnthony Liguori memset(strm, 0, sizeof(*strm)); 568019d6b8fSAnthony Liguori 569019d6b8fSAnthony Liguori strm->next_in = (uint8_t *)buf; 570019d6b8fSAnthony Liguori strm->avail_in = buf_size; 571019d6b8fSAnthony Liguori strm->next_out = out_buf; 572019d6b8fSAnthony Liguori strm->avail_out = out_buf_size; 573019d6b8fSAnthony Liguori 574019d6b8fSAnthony Liguori ret = inflateInit2(strm, -12); 575019d6b8fSAnthony Liguori if (ret != Z_OK) 576019d6b8fSAnthony Liguori return -1; 577019d6b8fSAnthony Liguori ret = inflate(strm, Z_FINISH); 578019d6b8fSAnthony Liguori out_len = strm->next_out - out_buf; 579019d6b8fSAnthony Liguori if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || 580019d6b8fSAnthony Liguori out_len != out_buf_size) { 581019d6b8fSAnthony Liguori inflateEnd(strm); 582019d6b8fSAnthony Liguori return -1; 583019d6b8fSAnthony Liguori } 584019d6b8fSAnthony Liguori inflateEnd(strm); 585019d6b8fSAnthony Liguori return 0; 586019d6b8fSAnthony Liguori } 587019d6b8fSAnthony Liguori 58866f82ceeSKevin Wolf static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) 589019d6b8fSAnthony Liguori { 59066f82ceeSKevin Wolf BDRVQcowState *s = bs->opaque; 591019d6b8fSAnthony Liguori int ret, csize; 592019d6b8fSAnthony Liguori uint64_t coffset; 593019d6b8fSAnthony Liguori 594019d6b8fSAnthony Liguori coffset = cluster_offset & s->cluster_offset_mask; 595019d6b8fSAnthony Liguori if (s->cluster_cache_offset != coffset) { 596019d6b8fSAnthony Liguori csize = cluster_offset >> (63 - s->cluster_bits); 597019d6b8fSAnthony Liguori csize &= (s->cluster_size - 1); 5980abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); 599cf2ab8fcSKevin Wolf ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize); 600019d6b8fSAnthony Liguori if (ret != csize) 601019d6b8fSAnthony Liguori return -1; 602019d6b8fSAnthony Liguori if (decompress_buffer(s->cluster_cache, s->cluster_size, 603019d6b8fSAnthony Liguori s->cluster_data, csize) < 0) { 604019d6b8fSAnthony Liguori return -1; 605019d6b8fSAnthony Liguori } 606019d6b8fSAnthony Liguori s->cluster_cache_offset = coffset; 607019d6b8fSAnthony Liguori } 608019d6b8fSAnthony Liguori return 0; 609019d6b8fSAnthony Liguori } 610019d6b8fSAnthony Liguori 611a968168cSDong Xu Wang static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, 61227deebe8SFrediano Ziglio int nb_sectors, QEMUIOVector *qiov) 613ad53089bSChristoph Hellwig { 614019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 615019d6b8fSAnthony Liguori int index_in_cluster; 61627deebe8SFrediano Ziglio int ret = 0, n; 61743ca85b5SFrediano Ziglio uint64_t cluster_offset; 618430bbaaaSFrediano Ziglio struct iovec hd_iov; 619430bbaaaSFrediano Ziglio QEMUIOVector hd_qiov; 62027deebe8SFrediano Ziglio uint8_t *buf; 62127deebe8SFrediano Ziglio void *orig_buf; 622019d6b8fSAnthony Liguori 62327deebe8SFrediano Ziglio if (qiov->niov > 1) { 6240df93305SKevin Wolf buf = orig_buf = qemu_try_blockalign(bs, qiov->size); 6250df93305SKevin Wolf if (buf == NULL) { 6260df93305SKevin Wolf return -ENOMEM; 6270df93305SKevin Wolf } 62827deebe8SFrediano Ziglio } else { 62927deebe8SFrediano Ziglio orig_buf = NULL; 63027deebe8SFrediano Ziglio buf = (uint8_t *)qiov->iov->iov_base; 631019d6b8fSAnthony Liguori } 632019d6b8fSAnthony Liguori 63327deebe8SFrediano Ziglio qemu_co_mutex_lock(&s->lock); 63427deebe8SFrediano Ziglio 63527deebe8SFrediano Ziglio while (nb_sectors != 0) { 63643ca85b5SFrediano Ziglio /* prepare next request */ 63756439e9dSEric Blake ret = get_cluster_offset(bs, sector_num << 9, 63856439e9dSEric Blake 0, 0, 0, 0, &cluster_offset); 63956439e9dSEric Blake if (ret < 0) { 64056439e9dSEric Blake break; 64156439e9dSEric Blake } 64227deebe8SFrediano Ziglio index_in_cluster = sector_num & (s->cluster_sectors - 1); 643430bbaaaSFrediano Ziglio n = s->cluster_sectors - index_in_cluster; 64427deebe8SFrediano Ziglio if (n > nb_sectors) { 64527deebe8SFrediano Ziglio n = nb_sectors; 646430bbaaaSFrediano Ziglio } 647019d6b8fSAnthony Liguori 648430bbaaaSFrediano Ziglio if (!cluster_offset) { 649760e0063SKevin Wolf if (bs->backing) { 650019d6b8fSAnthony Liguori /* read from the base image */ 65127deebe8SFrediano Ziglio hd_iov.iov_base = (void *)buf; 652430bbaaaSFrediano Ziglio hd_iov.iov_len = n * 512; 653430bbaaaSFrediano Ziglio qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); 65452b8eb60SKevin Wolf qemu_co_mutex_unlock(&s->lock); 6550abb1475SMax Reitz /* qcow2 emits this on bs->file instead of bs->backing */ 6560abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); 65728b04a8fSKevin Wolf ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov); 65852b8eb60SKevin Wolf qemu_co_mutex_lock(&s->lock); 65952b8eb60SKevin Wolf if (ret < 0) { 66056439e9dSEric Blake break; 6615614c188SStefan Weil } 662019d6b8fSAnthony Liguori } else { 663019d6b8fSAnthony Liguori /* Note: in this case, no need to wait */ 66427deebe8SFrediano Ziglio memset(buf, 0, 512 * n); 665019d6b8fSAnthony Liguori } 666430bbaaaSFrediano Ziglio } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { 667019d6b8fSAnthony Liguori /* add AIO support for compressed blocks ? */ 668430bbaaaSFrediano Ziglio if (decompress_cluster(bs, cluster_offset) < 0) { 66956439e9dSEric Blake ret = -EIO; 67056439e9dSEric Blake break; 6715614c188SStefan Weil } 67227deebe8SFrediano Ziglio memcpy(buf, 673430bbaaaSFrediano Ziglio s->cluster_cache + index_in_cluster * 512, 512 * n); 674019d6b8fSAnthony Liguori } else { 675430bbaaaSFrediano Ziglio if ((cluster_offset & 511) != 0) { 67656439e9dSEric Blake ret = -EIO; 67756439e9dSEric Blake break; 678019d6b8fSAnthony Liguori } 67927deebe8SFrediano Ziglio hd_iov.iov_base = (void *)buf; 680430bbaaaSFrediano Ziglio hd_iov.iov_len = n * 512; 681430bbaaaSFrediano Ziglio qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); 68252b8eb60SKevin Wolf qemu_co_mutex_unlock(&s->lock); 6830abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); 68428b04a8fSKevin Wolf ret = bdrv_co_readv(bs->file, 685430bbaaaSFrediano Ziglio (cluster_offset >> 9) + index_in_cluster, 686430bbaaaSFrediano Ziglio n, &hd_qiov); 68752b8eb60SKevin Wolf qemu_co_mutex_lock(&s->lock); 68852b8eb60SKevin Wolf if (ret < 0) { 68927deebe8SFrediano Ziglio break; 690019d6b8fSAnthony Liguori } 6918336aafaSDaniel P. Berrange if (bs->encrypted) { 692d85f4222SDaniel P. Berrange assert(s->crypto); 6934609742aSDaniel P. Berrange if (qcrypto_block_decrypt(s->crypto, 6944609742aSDaniel P. Berrange sector_num * BDRV_SECTOR_SIZE, buf, 695c3a8fe33SAlberto Garcia n * BDRV_SECTOR_SIZE, NULL) < 0) { 69656439e9dSEric Blake ret = -EIO; 69756439e9dSEric Blake break; 698f6fa64f6SDaniel P. Berrange } 69943ca85b5SFrediano Ziglio } 70043ca85b5SFrediano Ziglio } 70127deebe8SFrediano Ziglio ret = 0; 70243ca85b5SFrediano Ziglio 70327deebe8SFrediano Ziglio nb_sectors -= n; 70427deebe8SFrediano Ziglio sector_num += n; 70527deebe8SFrediano Ziglio buf += n * 512; 70652b8eb60SKevin Wolf } 707019d6b8fSAnthony Liguori 70852b8eb60SKevin Wolf qemu_co_mutex_unlock(&s->lock); 70952b8eb60SKevin Wolf 71027deebe8SFrediano Ziglio if (qiov->niov > 1) { 71103396148SMichael Tokarev qemu_iovec_from_buf(qiov, 0, orig_buf, qiov->size); 71227deebe8SFrediano Ziglio qemu_vfree(orig_buf); 713019d6b8fSAnthony Liguori } 71452b8eb60SKevin Wolf 71552b8eb60SKevin Wolf return ret; 716019d6b8fSAnthony Liguori } 717019d6b8fSAnthony Liguori 718a968168cSDong Xu Wang static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, 71927deebe8SFrediano Ziglio int nb_sectors, QEMUIOVector *qiov) 720019d6b8fSAnthony Liguori { 721019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 722019d6b8fSAnthony Liguori int index_in_cluster; 723019d6b8fSAnthony Liguori uint64_t cluster_offset; 72427deebe8SFrediano Ziglio int ret = 0, n; 725430bbaaaSFrediano Ziglio struct iovec hd_iov; 726430bbaaaSFrediano Ziglio QEMUIOVector hd_qiov; 72727deebe8SFrediano Ziglio uint8_t *buf; 72827deebe8SFrediano Ziglio void *orig_buf; 729019d6b8fSAnthony Liguori 73027deebe8SFrediano Ziglio s->cluster_cache_offset = -1; /* disable compressed cache */ 73127deebe8SFrediano Ziglio 7321fad1f94SDaniel P. Berrange /* We must always copy the iov when encrypting, so we 7331fad1f94SDaniel P. Berrange * don't modify the original data buffer during encryption */ 7341fad1f94SDaniel P. Berrange if (bs->encrypted || qiov->niov > 1) { 7350df93305SKevin Wolf buf = orig_buf = qemu_try_blockalign(bs, qiov->size); 7360df93305SKevin Wolf if (buf == NULL) { 7370df93305SKevin Wolf return -ENOMEM; 7380df93305SKevin Wolf } 739d5e6b161SMichael Tokarev qemu_iovec_to_buf(qiov, 0, buf, qiov->size); 74027deebe8SFrediano Ziglio } else { 74127deebe8SFrediano Ziglio orig_buf = NULL; 74227deebe8SFrediano Ziglio buf = (uint8_t *)qiov->iov->iov_base; 743019d6b8fSAnthony Liguori } 744019d6b8fSAnthony Liguori 74527deebe8SFrediano Ziglio qemu_co_mutex_lock(&s->lock); 74627deebe8SFrediano Ziglio 74727deebe8SFrediano Ziglio while (nb_sectors != 0) { 74827deebe8SFrediano Ziglio 74927deebe8SFrediano Ziglio index_in_cluster = sector_num & (s->cluster_sectors - 1); 750430bbaaaSFrediano Ziglio n = s->cluster_sectors - index_in_cluster; 75127deebe8SFrediano Ziglio if (n > nb_sectors) { 75227deebe8SFrediano Ziglio n = nb_sectors; 753430bbaaaSFrediano Ziglio } 75456439e9dSEric Blake ret = get_cluster_offset(bs, sector_num << 9, 1, 0, 755019d6b8fSAnthony Liguori index_in_cluster, 75656439e9dSEric Blake index_in_cluster + n, &cluster_offset); 75756439e9dSEric Blake if (ret < 0) { 75856439e9dSEric Blake break; 75956439e9dSEric Blake } 760019d6b8fSAnthony Liguori if (!cluster_offset || (cluster_offset & 511) != 0) { 76127deebe8SFrediano Ziglio ret = -EIO; 76227deebe8SFrediano Ziglio break; 763019d6b8fSAnthony Liguori } 7648336aafaSDaniel P. Berrange if (bs->encrypted) { 765d85f4222SDaniel P. Berrange assert(s->crypto); 7664609742aSDaniel P. Berrange if (qcrypto_block_encrypt(s->crypto, sector_num * BDRV_SECTOR_SIZE, 7674609742aSDaniel P. Berrange buf, n * BDRV_SECTOR_SIZE, NULL) < 0) { 768f6fa64f6SDaniel P. Berrange ret = -EIO; 769f6fa64f6SDaniel P. Berrange break; 770f6fa64f6SDaniel P. Berrange } 771019d6b8fSAnthony Liguori } 772019d6b8fSAnthony Liguori 7731fad1f94SDaniel P. Berrange hd_iov.iov_base = (void *)buf; 774430bbaaaSFrediano Ziglio hd_iov.iov_len = n * 512; 775430bbaaaSFrediano Ziglio qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); 77652b8eb60SKevin Wolf qemu_co_mutex_unlock(&s->lock); 7770abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); 77825ec177dSKevin Wolf ret = bdrv_co_writev(bs->file, 779019d6b8fSAnthony Liguori (cluster_offset >> 9) + index_in_cluster, 780430bbaaaSFrediano Ziglio n, &hd_qiov); 78152b8eb60SKevin Wolf qemu_co_mutex_lock(&s->lock); 78252b8eb60SKevin Wolf if (ret < 0) { 78327deebe8SFrediano Ziglio break; 7845614c188SStefan Weil } 78527deebe8SFrediano Ziglio ret = 0; 78643ca85b5SFrediano Ziglio 78727deebe8SFrediano Ziglio nb_sectors -= n; 78827deebe8SFrediano Ziglio sector_num += n; 78927deebe8SFrediano Ziglio buf += n * 512; 790019d6b8fSAnthony Liguori } 79152b8eb60SKevin Wolf qemu_co_mutex_unlock(&s->lock); 792019d6b8fSAnthony Liguori 79327deebe8SFrediano Ziglio qemu_vfree(orig_buf); 794b11a24deSKevin Wolf 79552b8eb60SKevin Wolf return ret; 796019d6b8fSAnthony Liguori } 797019d6b8fSAnthony Liguori 798019d6b8fSAnthony Liguori static void qcow_close(BlockDriverState *bs) 799019d6b8fSAnthony Liguori { 800019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 801fd9f102cSKevin Wolf 802d85f4222SDaniel P. Berrange qcrypto_block_free(s->crypto); 803d85f4222SDaniel P. Berrange s->crypto = NULL; 8047267c094SAnthony Liguori g_free(s->l1_table); 8050df93305SKevin Wolf qemu_vfree(s->l2_cache); 8067267c094SAnthony Liguori g_free(s->cluster_cache); 8077267c094SAnthony Liguori g_free(s->cluster_data); 808fd9f102cSKevin Wolf 809fd9f102cSKevin Wolf migrate_del_blocker(s->migration_blocker); 810fd9f102cSKevin Wolf error_free(s->migration_blocker); 811019d6b8fSAnthony Liguori } 812019d6b8fSAnthony Liguori 81316d12159SChunyan Liu static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) 814019d6b8fSAnthony Liguori { 8152b16c9ffSLi Zhi Hui int header_size, backing_filename_len, l1_size, shift, i; 816019d6b8fSAnthony Liguori QCowHeader header; 8172b16c9ffSLi Zhi Hui uint8_t *tmp; 8180e7e1989SKevin Wolf int64_t total_size = 0; 81916d12159SChunyan Liu char *backing_file = NULL; 82034b5d2c6SMax Reitz Error *local_err = NULL; 8213e1a8134SKirill A. Shutemov int ret; 8226af40160SKevin Wolf BlockBackend *qcow_blk; 8230696ae2cSDaniel P. Berrange char *encryptfmt = NULL; 824d85f4222SDaniel P. Berrange QDict *options; 825d85f4222SDaniel P. Berrange QDict *encryptopts = NULL; 826d85f4222SDaniel P. Berrange QCryptoBlockCreateOptions *crypto_opts = NULL; 827d85f4222SDaniel P. Berrange QCryptoBlock *crypto = NULL; 8280e7e1989SKevin Wolf 8290e7e1989SKevin Wolf /* Read out options */ 830180e9526SHu Tao total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), 831c2eb918eSHu Tao BDRV_SECTOR_SIZE); 8326aa837f7SDaniel P. Berrange if (total_size == 0) { 8336aa837f7SDaniel P. Berrange error_setg(errp, "Image size is too small, cannot be zero length"); 8346aa837f7SDaniel P. Berrange ret = -EINVAL; 8356aa837f7SDaniel P. Berrange goto cleanup; 8366aa837f7SDaniel P. Berrange } 8376aa837f7SDaniel P. Berrange 83816d12159SChunyan Liu backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); 8390cb8d47bSDaniel P. Berrange encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); 8400cb8d47bSDaniel P. Berrange if (encryptfmt) { 8410cb8d47bSDaniel P. Berrange if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) { 8420cb8d47bSDaniel P. Berrange error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and " 8430cb8d47bSDaniel P. Berrange BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive"); 8440cb8d47bSDaniel P. Berrange ret = -EINVAL; 8450cb8d47bSDaniel P. Berrange goto cleanup; 8460cb8d47bSDaniel P. Berrange } 8470cb8d47bSDaniel P. Berrange } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { 8480696ae2cSDaniel P. Berrange encryptfmt = g_strdup("aes"); 8490e7e1989SKevin Wolf } 850019d6b8fSAnthony Liguori 851c282e1fdSChunyan Liu ret = bdrv_create_file(filename, opts, &local_err); 8522b16c9ffSLi Zhi Hui if (ret < 0) { 853b6d5066dSPaolo Bonzini error_propagate(errp, local_err); 85416d12159SChunyan Liu goto cleanup; 8552b16c9ffSLi Zhi Hui } 8562b16c9ffSLi Zhi Hui 857efaa7c4eSMax Reitz qcow_blk = blk_new_open(filename, NULL, NULL, 85855880601SKevin Wolf BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, 85955880601SKevin Wolf &local_err); 8606af40160SKevin Wolf if (qcow_blk == NULL) { 861b6d5066dSPaolo Bonzini error_propagate(errp, local_err); 8626af40160SKevin Wolf ret = -EIO; 86316d12159SChunyan Liu goto cleanup; 8642b16c9ffSLi Zhi Hui } 8652b16c9ffSLi Zhi Hui 8666af40160SKevin Wolf blk_set_allow_write_beyond_eof(qcow_blk, true); 8676af40160SKevin Wolf 8683a691c50SMax Reitz ret = blk_truncate(qcow_blk, 0, PREALLOC_MODE_OFF, errp); 8692b16c9ffSLi Zhi Hui if (ret < 0) { 8702b16c9ffSLi Zhi Hui goto exit; 8712b16c9ffSLi Zhi Hui } 8722b16c9ffSLi Zhi Hui 873019d6b8fSAnthony Liguori memset(&header, 0, sizeof(header)); 874019d6b8fSAnthony Liguori header.magic = cpu_to_be32(QCOW_MAGIC); 875019d6b8fSAnthony Liguori header.version = cpu_to_be32(QCOW_VERSION); 876180e9526SHu Tao header.size = cpu_to_be64(total_size); 877019d6b8fSAnthony Liguori header_size = sizeof(header); 878019d6b8fSAnthony Liguori backing_filename_len = 0; 879019d6b8fSAnthony Liguori if (backing_file) { 880019d6b8fSAnthony Liguori if (strcmp(backing_file, "fat:")) { 881019d6b8fSAnthony Liguori header.backing_file_offset = cpu_to_be64(header_size); 882019d6b8fSAnthony Liguori backing_filename_len = strlen(backing_file); 883019d6b8fSAnthony Liguori header.backing_file_size = cpu_to_be32(backing_filename_len); 884019d6b8fSAnthony Liguori header_size += backing_filename_len; 885019d6b8fSAnthony Liguori } else { 886019d6b8fSAnthony Liguori /* special backing file for vvfat */ 887272545cfSPeter Maydell g_free(backing_file); 888019d6b8fSAnthony Liguori backing_file = NULL; 889019d6b8fSAnthony Liguori } 890019d6b8fSAnthony Liguori header.cluster_bits = 9; /* 512 byte cluster to avoid copying 891dc6fb73dSDeepak Kathayat unmodified sectors */ 892019d6b8fSAnthony Liguori header.l2_bits = 12; /* 32 KB L2 tables */ 893019d6b8fSAnthony Liguori } else { 894019d6b8fSAnthony Liguori header.cluster_bits = 12; /* 4 KB clusters */ 895019d6b8fSAnthony Liguori header.l2_bits = 9; /* 4 KB L2 tables */ 896019d6b8fSAnthony Liguori } 897019d6b8fSAnthony Liguori header_size = (header_size + 7) & ~7; 898019d6b8fSAnthony Liguori shift = header.cluster_bits + header.l2_bits; 899180e9526SHu Tao l1_size = (total_size + (1LL << shift) - 1) >> shift; 900019d6b8fSAnthony Liguori 901019d6b8fSAnthony Liguori header.l1_table_offset = cpu_to_be64(header_size); 902d85f4222SDaniel P. Berrange 903d85f4222SDaniel P. Berrange options = qemu_opts_to_qdict(opts, NULL); 904d85f4222SDaniel P. Berrange qdict_extract_subqdict(options, &encryptopts, "encrypt."); 905d85f4222SDaniel P. Berrange QDECREF(options); 9060cb8d47bSDaniel P. Berrange if (encryptfmt) { 9070cb8d47bSDaniel P. Berrange if (!g_str_equal(encryptfmt, "aes")) { 9080cb8d47bSDaniel P. Berrange error_setg(errp, "Unknown encryption format '%s', expected 'aes'", 9090cb8d47bSDaniel P. Berrange encryptfmt); 9100cb8d47bSDaniel P. Berrange ret = -EINVAL; 9110cb8d47bSDaniel P. Berrange goto exit; 9120cb8d47bSDaniel P. Berrange } 913019d6b8fSAnthony Liguori header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); 914d85f4222SDaniel P. Berrange 915d85f4222SDaniel P. Berrange crypto_opts = block_crypto_create_opts_init( 916d85f4222SDaniel P. Berrange Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); 917d85f4222SDaniel P. Berrange if (!crypto_opts) { 918d85f4222SDaniel P. Berrange ret = -EINVAL; 919d85f4222SDaniel P. Berrange goto exit; 920d85f4222SDaniel P. Berrange } 921d85f4222SDaniel P. Berrange 9221cd9a787SDaniel P. Berrange crypto = qcrypto_block_create(crypto_opts, "encrypt.", 9231cd9a787SDaniel P. Berrange NULL, NULL, NULL, errp); 924d85f4222SDaniel P. Berrange if (!crypto) { 925d85f4222SDaniel P. Berrange ret = -EINVAL; 926d85f4222SDaniel P. Berrange goto exit; 927d85f4222SDaniel P. Berrange } 928019d6b8fSAnthony Liguori } else { 929019d6b8fSAnthony Liguori header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); 930019d6b8fSAnthony Liguori } 931019d6b8fSAnthony Liguori 932019d6b8fSAnthony Liguori /* write all the data */ 9338341f00dSEric Blake ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header), 0); 9343e1a8134SKirill A. Shutemov if (ret != sizeof(header)) { 9353e1a8134SKirill A. Shutemov goto exit; 9363e1a8134SKirill A. Shutemov } 9373e1a8134SKirill A. Shutemov 938019d6b8fSAnthony Liguori if (backing_file) { 9396af40160SKevin Wolf ret = blk_pwrite(qcow_blk, sizeof(header), 9408341f00dSEric Blake backing_file, backing_filename_len, 0); 9413e1a8134SKirill A. Shutemov if (ret != backing_filename_len) { 9423e1a8134SKirill A. Shutemov goto exit; 943019d6b8fSAnthony Liguori } 9443e1a8134SKirill A. Shutemov } 9453e1a8134SKirill A. Shutemov 9462b16c9ffSLi Zhi Hui tmp = g_malloc0(BDRV_SECTOR_SIZE); 947d737b78cSLaurent Vivier for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE); 948d737b78cSLaurent Vivier i++) { 9498341f00dSEric Blake ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, 9508341f00dSEric Blake tmp, BDRV_SECTOR_SIZE, 0); 9512b16c9ffSLi Zhi Hui if (ret != BDRV_SECTOR_SIZE) { 9522b16c9ffSLi Zhi Hui g_free(tmp); 9532b16c9ffSLi Zhi Hui goto exit; 9542b16c9ffSLi Zhi Hui } 9552b16c9ffSLi Zhi Hui } 9562b16c9ffSLi Zhi Hui 9572b16c9ffSLi Zhi Hui g_free(tmp); 9583e1a8134SKirill A. Shutemov ret = 0; 9593e1a8134SKirill A. Shutemov exit: 9606af40160SKevin Wolf blk_unref(qcow_blk); 96116d12159SChunyan Liu cleanup: 962d85f4222SDaniel P. Berrange QDECREF(encryptopts); 9630696ae2cSDaniel P. Berrange g_free(encryptfmt); 964d85f4222SDaniel P. Berrange qcrypto_block_free(crypto); 965d85f4222SDaniel P. Berrange qapi_free_QCryptoBlockCreateOptions(crypto_opts); 96616d12159SChunyan Liu g_free(backing_file); 9673e1a8134SKirill A. Shutemov return ret; 968019d6b8fSAnthony Liguori } 969019d6b8fSAnthony Liguori 970019d6b8fSAnthony Liguori static int qcow_make_empty(BlockDriverState *bs) 971019d6b8fSAnthony Liguori { 972019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 973019d6b8fSAnthony Liguori uint32_t l1_length = s->l1_size * sizeof(uint64_t); 974019d6b8fSAnthony Liguori int ret; 975019d6b8fSAnthony Liguori 976019d6b8fSAnthony Liguori memset(s->l1_table, 0, l1_length); 977d9ca2ea2SKevin Wolf if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table, 9785e5557d9SKevin Wolf l1_length) < 0) 979019d6b8fSAnthony Liguori return -1; 9807ea37c30SMax Reitz ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, 9817ea37c30SMax Reitz PREALLOC_MODE_OFF, NULL); 982019d6b8fSAnthony Liguori if (ret < 0) 983019d6b8fSAnthony Liguori return ret; 984019d6b8fSAnthony Liguori 985019d6b8fSAnthony Liguori memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); 986019d6b8fSAnthony Liguori memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t)); 987019d6b8fSAnthony Liguori memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t)); 988019d6b8fSAnthony Liguori 989019d6b8fSAnthony Liguori return 0; 990019d6b8fSAnthony Liguori } 991019d6b8fSAnthony Liguori 992019d6b8fSAnthony Liguori /* XXX: put compressed sectors first, then all the cluster aligned 993019d6b8fSAnthony Liguori tables to avoid losing bytes in alignment */ 994f2b95a12SPavel Butsykin static coroutine_fn int 995f2b95a12SPavel Butsykin qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, 996f2b95a12SPavel Butsykin uint64_t bytes, QEMUIOVector *qiov) 997019d6b8fSAnthony Liguori { 998019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 999f2b95a12SPavel Butsykin QEMUIOVector hd_qiov; 1000f2b95a12SPavel Butsykin struct iovec iov; 1001019d6b8fSAnthony Liguori z_stream strm; 1002019d6b8fSAnthony Liguori int ret, out_len; 1003f2b95a12SPavel Butsykin uint8_t *buf, *out_buf; 1004019d6b8fSAnthony Liguori uint64_t cluster_offset; 1005019d6b8fSAnthony Liguori 1006f2b95a12SPavel Butsykin buf = qemu_blockalign(bs, s->cluster_size); 1007655923dfSPavel Butsykin if (bytes != s->cluster_size) { 1008655923dfSPavel Butsykin if (bytes > s->cluster_size || 1009655923dfSPavel Butsykin offset + bytes != bs->total_sectors << BDRV_SECTOR_BITS) 1010655923dfSPavel Butsykin { 1011655923dfSPavel Butsykin qemu_vfree(buf); 1012655923dfSPavel Butsykin return -EINVAL; 1013655923dfSPavel Butsykin } 1014655923dfSPavel Butsykin /* Zero-pad last write if image size is not cluster aligned */ 1015655923dfSPavel Butsykin memset(buf + bytes, 0, s->cluster_size - bytes); 1016655923dfSPavel Butsykin } 1017f2b95a12SPavel Butsykin qemu_iovec_to_buf(qiov, 0, buf, qiov->size); 1018019d6b8fSAnthony Liguori 1019ebf7bba0SVladimir Sementsov-Ogievskiy out_buf = g_malloc(s->cluster_size); 1020019d6b8fSAnthony Liguori 1021019d6b8fSAnthony Liguori /* best compression, small window, no zlib header */ 1022019d6b8fSAnthony Liguori memset(&strm, 0, sizeof(strm)); 1023019d6b8fSAnthony Liguori ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, 1024019d6b8fSAnthony Liguori Z_DEFLATED, -12, 1025019d6b8fSAnthony Liguori 9, Z_DEFAULT_STRATEGY); 1026019d6b8fSAnthony Liguori if (ret != 0) { 102764ebe71aSKevin Wolf ret = -EINVAL; 102864ebe71aSKevin Wolf goto fail; 1029019d6b8fSAnthony Liguori } 1030019d6b8fSAnthony Liguori 1031019d6b8fSAnthony Liguori strm.avail_in = s->cluster_size; 1032019d6b8fSAnthony Liguori strm.next_in = (uint8_t *)buf; 1033019d6b8fSAnthony Liguori strm.avail_out = s->cluster_size; 1034019d6b8fSAnthony Liguori strm.next_out = out_buf; 1035019d6b8fSAnthony Liguori 1036019d6b8fSAnthony Liguori ret = deflate(&strm, Z_FINISH); 1037019d6b8fSAnthony Liguori if (ret != Z_STREAM_END && ret != Z_OK) { 1038019d6b8fSAnthony Liguori deflateEnd(&strm); 103964ebe71aSKevin Wolf ret = -EINVAL; 104064ebe71aSKevin Wolf goto fail; 1041019d6b8fSAnthony Liguori } 1042019d6b8fSAnthony Liguori out_len = strm.next_out - out_buf; 1043019d6b8fSAnthony Liguori 1044019d6b8fSAnthony Liguori deflateEnd(&strm); 1045019d6b8fSAnthony Liguori 1046019d6b8fSAnthony Liguori if (ret != Z_STREAM_END || out_len >= s->cluster_size) { 1047019d6b8fSAnthony Liguori /* could not compress: write normal cluster */ 1048f2b95a12SPavel Butsykin ret = qcow_co_writev(bs, offset >> BDRV_SECTOR_BITS, 1049f2b95a12SPavel Butsykin bytes >> BDRV_SECTOR_BITS, qiov); 105064ebe71aSKevin Wolf if (ret < 0) { 105164ebe71aSKevin Wolf goto fail; 105264ebe71aSKevin Wolf } 1053f2b95a12SPavel Butsykin goto success; 1054f2b95a12SPavel Butsykin } 1055f2b95a12SPavel Butsykin qemu_co_mutex_lock(&s->lock); 105656439e9dSEric Blake ret = get_cluster_offset(bs, offset, 2, out_len, 0, 0, &cluster_offset); 1057f2b95a12SPavel Butsykin qemu_co_mutex_unlock(&s->lock); 105856439e9dSEric Blake if (ret < 0) { 105956439e9dSEric Blake goto fail; 106056439e9dSEric Blake } 106164ebe71aSKevin Wolf if (cluster_offset == 0) { 106264ebe71aSKevin Wolf ret = -EIO; 106364ebe71aSKevin Wolf goto fail; 106464ebe71aSKevin Wolf } 1065019d6b8fSAnthony Liguori cluster_offset &= s->cluster_offset_mask; 1066f2b95a12SPavel Butsykin 1067f2b95a12SPavel Butsykin iov = (struct iovec) { 1068f2b95a12SPavel Butsykin .iov_base = out_buf, 1069f2b95a12SPavel Butsykin .iov_len = out_len, 1070f2b95a12SPavel Butsykin }; 1071f2b95a12SPavel Butsykin qemu_iovec_init_external(&hd_qiov, &iov, 1); 10720abb1475SMax Reitz BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED); 1073f2b95a12SPavel Butsykin ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0); 107464ebe71aSKevin Wolf if (ret < 0) { 107564ebe71aSKevin Wolf goto fail; 1076019d6b8fSAnthony Liguori } 1077f2b95a12SPavel Butsykin success: 107864ebe71aSKevin Wolf ret = 0; 107964ebe71aSKevin Wolf fail: 1080f2b95a12SPavel Butsykin qemu_vfree(buf); 10817267c094SAnthony Liguori g_free(out_buf); 108264ebe71aSKevin Wolf return ret; 1083019d6b8fSAnthony Liguori } 1084019d6b8fSAnthony Liguori 1085019d6b8fSAnthony Liguori static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 1086019d6b8fSAnthony Liguori { 1087019d6b8fSAnthony Liguori BDRVQcowState *s = bs->opaque; 1088019d6b8fSAnthony Liguori bdi->cluster_size = s->cluster_size; 1089019d6b8fSAnthony Liguori return 0; 1090019d6b8fSAnthony Liguori } 1091019d6b8fSAnthony Liguori 109216d12159SChunyan Liu static QemuOptsList qcow_create_opts = { 109316d12159SChunyan Liu .name = "qcow-create-opts", 109416d12159SChunyan Liu .head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head), 109516d12159SChunyan Liu .desc = { 1096db08adf5SKevin Wolf { 1097db08adf5SKevin Wolf .name = BLOCK_OPT_SIZE, 109816d12159SChunyan Liu .type = QEMU_OPT_SIZE, 1099db08adf5SKevin Wolf .help = "Virtual disk size" 1100db08adf5SKevin Wolf }, 1101db08adf5SKevin Wolf { 1102db08adf5SKevin Wolf .name = BLOCK_OPT_BACKING_FILE, 110316d12159SChunyan Liu .type = QEMU_OPT_STRING, 1104db08adf5SKevin Wolf .help = "File name of a base image" 1105db08adf5SKevin Wolf }, 1106db08adf5SKevin Wolf { 1107db08adf5SKevin Wolf .name = BLOCK_OPT_ENCRYPT, 110816d12159SChunyan Liu .type = QEMU_OPT_BOOL, 11090cb8d47bSDaniel P. Berrange .help = "Encrypt the image with format 'aes'. (Deprecated " 11100cb8d47bSDaniel P. Berrange "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", 11110cb8d47bSDaniel P. Berrange }, 11120cb8d47bSDaniel P. Berrange { 11130cb8d47bSDaniel P. Berrange .name = BLOCK_OPT_ENCRYPT_FORMAT, 11140cb8d47bSDaniel P. Berrange .type = QEMU_OPT_STRING, 11150cb8d47bSDaniel P. Berrange .help = "Encrypt the image, format choices: 'aes'", 1116db08adf5SKevin Wolf }, 1117d85f4222SDaniel P. Berrange BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), 111816d12159SChunyan Liu { /* end of list */ } 111916d12159SChunyan Liu } 11200e7e1989SKevin Wolf }; 11210e7e1989SKevin Wolf 1122019d6b8fSAnthony Liguori static BlockDriver bdrv_qcow = { 1123019d6b8fSAnthony Liguori .format_name = "qcow", 1124019d6b8fSAnthony Liguori .instance_size = sizeof(BDRVQcowState), 1125019d6b8fSAnthony Liguori .bdrv_probe = qcow_probe, 1126019d6b8fSAnthony Liguori .bdrv_open = qcow_open, 1127019d6b8fSAnthony Liguori .bdrv_close = qcow_close, 1128862f215fSKevin Wolf .bdrv_child_perm = bdrv_format_default_perms, 1129d177692eSJeff Cody .bdrv_reopen_prepare = qcow_reopen_prepare, 1130c282e1fdSChunyan Liu .bdrv_create = qcow_create, 11313ac21627SPeter Lieven .bdrv_has_zero_init = bdrv_has_zero_init_1, 11328ee79e70SKevin Wolf .supports_backing = true, 1133c68b89acSKevin Wolf 113452b8eb60SKevin Wolf .bdrv_co_readv = qcow_co_readv, 113552b8eb60SKevin Wolf .bdrv_co_writev = qcow_co_writev, 1136*d63b4c93SEric Blake .bdrv_co_block_status = qcow_co_block_status, 1137c68b89acSKevin Wolf 1138c68b89acSKevin Wolf .bdrv_make_empty = qcow_make_empty, 1139f2b95a12SPavel Butsykin .bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed, 1140019d6b8fSAnthony Liguori .bdrv_get_info = qcow_get_info, 11410e7e1989SKevin Wolf 114216d12159SChunyan Liu .create_opts = &qcow_create_opts, 1143019d6b8fSAnthony Liguori }; 1144019d6b8fSAnthony Liguori 1145019d6b8fSAnthony Liguori static void bdrv_qcow_init(void) 1146019d6b8fSAnthony Liguori { 1147019d6b8fSAnthony Liguori bdrv_register(&bdrv_qcow); 1148019d6b8fSAnthony Liguori } 1149019d6b8fSAnthony Liguori 1150019d6b8fSAnthony Liguori block_init(bdrv_qcow_init); 1151