1 /* 2 * Threaded data processing for Qcow2: compression, encryption 3 * 4 * Copyright (c) 2004-2006 Fabrice Bellard 5 * Copyright (c) 2018 Virtuozzo International GmbH. All rights reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #include "qemu/osdep.h" 27 28 #define ZLIB_CONST 29 #include <zlib.h> 30 31 #include "qcow2.h" 32 #include "block/thread-pool.h" 33 #include "crypto.h" 34 35 static int coroutine_fn 36 qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg) 37 { 38 int ret; 39 BDRVQcow2State *s = bs->opaque; 40 ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); 41 42 qemu_co_mutex_lock(&s->lock); 43 while (s->nb_threads >= QCOW2_MAX_THREADS) { 44 qemu_co_queue_wait(&s->thread_task_queue, &s->lock); 45 } 46 s->nb_threads++; 47 qemu_co_mutex_unlock(&s->lock); 48 49 ret = thread_pool_submit_co(pool, func, arg); 50 51 qemu_co_mutex_lock(&s->lock); 52 s->nb_threads--; 53 qemu_co_queue_next(&s->thread_task_queue); 54 qemu_co_mutex_unlock(&s->lock); 55 56 return ret; 57 } 58 59 60 /* 61 * Compression 62 */ 63 64 typedef ssize_t (*Qcow2CompressFunc)(void *dest, size_t dest_size, 65 const void *src, size_t src_size); 66 typedef struct Qcow2CompressData { 67 void *dest; 68 size_t dest_size; 69 const void *src; 70 size_t src_size; 71 ssize_t ret; 72 73 Qcow2CompressFunc func; 74 } Qcow2CompressData; 75 76 /* 77 * qcow2_compress() 78 * 79 * @dest - destination buffer, @dest_size bytes 80 * @src - source buffer, @src_size bytes 81 * 82 * Returns: compressed size on success 83 * -ENOMEM destination buffer is not enough to store compressed data 84 * -EIO on any other error 85 */ 86 static ssize_t qcow2_compress(void *dest, size_t dest_size, 87 const void *src, size_t src_size) 88 { 89 ssize_t ret; 90 z_stream strm; 91 92 /* best compression, small window, no zlib header */ 93 memset(&strm, 0, sizeof(strm)); 94 ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 95 -12, 9, Z_DEFAULT_STRATEGY); 96 if (ret != Z_OK) { 97 return -EIO; 98 } 99 100 /* 101 * strm.next_in is not const in old zlib versions, such as those used on 102 * OpenBSD/NetBSD, so cast the const away 103 */ 104 strm.avail_in = src_size; 105 strm.next_in = (void *) src; 106 strm.avail_out = dest_size; 107 strm.next_out = dest; 108 109 ret = deflate(&strm, Z_FINISH); 110 if (ret == Z_STREAM_END) { 111 ret = dest_size - strm.avail_out; 112 } else { 113 ret = (ret == Z_OK ? -ENOMEM : -EIO); 114 } 115 116 deflateEnd(&strm); 117 118 return ret; 119 } 120 121 /* 122 * qcow2_decompress() 123 * 124 * Decompress some data (not more than @src_size bytes) to produce exactly 125 * @dest_size bytes. 126 * 127 * @dest - destination buffer, @dest_size bytes 128 * @src - source buffer, @src_size bytes 129 * 130 * Returns: 0 on success 131 * -1 on fail 132 */ 133 static ssize_t qcow2_decompress(void *dest, size_t dest_size, 134 const void *src, size_t src_size) 135 { 136 int ret = 0; 137 z_stream strm; 138 139 memset(&strm, 0, sizeof(strm)); 140 strm.avail_in = src_size; 141 strm.next_in = (void *) src; 142 strm.avail_out = dest_size; 143 strm.next_out = dest; 144 145 ret = inflateInit2(&strm, -12); 146 if (ret != Z_OK) { 147 return -1; 148 } 149 150 ret = inflate(&strm, Z_FINISH); 151 if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) { 152 /* 153 * We approve Z_BUF_ERROR because we need @dest buffer to be filled, but 154 * @src buffer may be processed partly (because in qcow2 we know size of 155 * compressed data with precision of one sector) 156 */ 157 ret = -1; 158 } 159 160 inflateEnd(&strm); 161 162 return ret; 163 } 164 165 static int qcow2_compress_pool_func(void *opaque) 166 { 167 Qcow2CompressData *data = opaque; 168 169 data->ret = data->func(data->dest, data->dest_size, 170 data->src, data->src_size); 171 172 return 0; 173 } 174 175 static ssize_t coroutine_fn 176 qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size, 177 const void *src, size_t src_size, Qcow2CompressFunc func) 178 { 179 Qcow2CompressData arg = { 180 .dest = dest, 181 .dest_size = dest_size, 182 .src = src, 183 .src_size = src_size, 184 .func = func, 185 }; 186 187 qcow2_co_process(bs, qcow2_compress_pool_func, &arg); 188 189 return arg.ret; 190 } 191 192 ssize_t coroutine_fn 193 qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size, 194 const void *src, size_t src_size) 195 { 196 return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, 197 qcow2_compress); 198 } 199 200 ssize_t coroutine_fn 201 qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size, 202 const void *src, size_t src_size) 203 { 204 return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, 205 qcow2_decompress); 206 } 207 208 209 /* 210 * Cryptography 211 */ 212 213 /* 214 * Qcow2EncDecFunc: common prototype of qcrypto_block_encrypt() and 215 * qcrypto_block_decrypt() functions. 216 */ 217 typedef int (*Qcow2EncDecFunc)(QCryptoBlock *block, uint64_t offset, 218 uint8_t *buf, size_t len, Error **errp); 219 220 typedef struct Qcow2EncDecData { 221 QCryptoBlock *block; 222 uint64_t offset; 223 uint8_t *buf; 224 size_t len; 225 226 Qcow2EncDecFunc func; 227 } Qcow2EncDecData; 228 229 static int qcow2_encdec_pool_func(void *opaque) 230 { 231 Qcow2EncDecData *data = opaque; 232 233 return data->func(data->block, data->offset, data->buf, data->len, NULL); 234 } 235 236 static int coroutine_fn 237 qcow2_co_encdec(BlockDriverState *bs, uint64_t host_offset, 238 uint64_t guest_offset, void *buf, size_t len, 239 Qcow2EncDecFunc func) 240 { 241 BDRVQcow2State *s = bs->opaque; 242 Qcow2EncDecData arg = { 243 .block = s->crypto, 244 .offset = s->crypt_physical_offset ? host_offset : guest_offset, 245 .buf = buf, 246 .len = len, 247 .func = func, 248 }; 249 uint64_t sector_size; 250 251 assert(s->crypto); 252 253 sector_size = qcrypto_block_get_sector_size(s->crypto); 254 assert(QEMU_IS_ALIGNED(guest_offset, sector_size)); 255 assert(QEMU_IS_ALIGNED(host_offset, sector_size)); 256 assert(QEMU_IS_ALIGNED(len, sector_size)); 257 258 return len == 0 ? 0 : qcow2_co_process(bs, qcow2_encdec_pool_func, &arg); 259 } 260 261 /* 262 * qcow2_co_encrypt() 263 * 264 * Encrypts one or more contiguous aligned sectors 265 * 266 * @host_offset - underlying storage offset of the first sector of the 267 * data to be encrypted 268 * 269 * @guest_offset - guest (virtual) offset of the first sector of the 270 * data to be encrypted 271 * 272 * @buf - buffer with the data to encrypt, that after encryption 273 * will be written to the underlying storage device at 274 * @host_offset 275 * 276 * @len - length of the buffer (must be a multiple of the encryption 277 * sector size) 278 * 279 * Depending on the encryption method, @host_offset and/or @guest_offset 280 * may be used for generating the initialization vector for 281 * encryption. 282 * 283 * Note that while the whole range must be aligned on sectors, it 284 * does not have to be aligned on clusters and can also cross cluster 285 * boundaries 286 */ 287 int coroutine_fn 288 qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_offset, 289 uint64_t guest_offset, void *buf, size_t len) 290 { 291 return qcow2_co_encdec(bs, host_offset, guest_offset, buf, len, 292 qcrypto_block_encrypt); 293 } 294 295 /* 296 * qcow2_co_decrypt() 297 * 298 * Decrypts one or more contiguous aligned sectors 299 * Similar to qcow2_co_encrypt 300 */ 301 int coroutine_fn 302 qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_offset, 303 uint64_t guest_offset, void *buf, size_t len) 304 { 305 return qcow2_co_encdec(bs, host_offset, guest_offset, buf, len, 306 qcrypto_block_decrypt); 307 } 308