]> git.proxmox.com Git - mirror_qemu.git/blame - block/vpc.c
qobject: Replace qobject_incref/QINCREF qobject_decref/QDECREF
[mirror_qemu.git] / block / vpc.c
CommitLineData
6a0f9e82 1/*
cc2040f8 2 * Block driver for Connectix / Microsoft Virtual PC images
5fafdf24 3 *
6a0f9e82 4 * Copyright (c) 2005 Alex Beregszaszi
15d35bc5 5 * Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
5fafdf24 6 *
6a0f9e82
FB
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 */
922a01a0 25
80c71a24 26#include "qemu/osdep.h"
da34e65c 27#include "qapi/error.h"
737e150e 28#include "block/block_int.h"
b8f45cdf 29#include "sysemu/block-backend.h"
1de7afc9 30#include "qemu/module.h"
922a01a0 31#include "qemu/option.h"
795c40b8 32#include "migration/blocker.h"
58369e22 33#include "qemu/bswap.h"
38440a21 34#include "qemu/uuid.h"
182c8835
KW
35#include "qapi/qmp/qdict.h"
36#include "qapi/qobject-input-visitor.h"
37#include "qapi/qapi-visit-block-core.h"
6a0f9e82
FB
38
39/**************************************************************/
40
41#define HEADER_SIZE 512
42
43//#define CACHE
44
2cfacb62
AL
45enum vhd_type {
46 VHD_FIXED = 2,
47 VHD_DYNAMIC = 3,
48 VHD_DIFFERENCING = 4,
49};
50
9c057d0b 51/* Seconds since Jan 1, 2000 0:00:00 (UTC) */
57c7d9e5
AL
52#define VHD_TIMESTAMP_BASE 946684800
53
fb9245c2
JC
54#define VHD_CHS_MAX_C 65535LL
55#define VHD_CHS_MAX_H 16
56#define VHD_CHS_MAX_S 255
57
c23fb11b 58#define VHD_MAX_SECTORS 0xff000000 /* 2040 GiB max image size */
fb9245c2
JC
59#define VHD_MAX_GEOMETRY (VHD_CHS_MAX_C * VHD_CHS_MAX_H * VHD_CHS_MAX_S)
60
61#define VPC_OPT_FORCE_SIZE "force_size"
97f1c45c 62
9c057d0b 63/* always big-endian */
e54835c0 64typedef struct vhd_footer {
9c057d0b 65 char creator[8]; /* "conectix" */
2cfacb62
AL
66 uint32_t features;
67 uint32_t version;
68
9c057d0b 69 /* Offset of next header structure, 0xFFFFFFFF if none */
2cfacb62
AL
70 uint64_t data_offset;
71
9c057d0b 72 /* Seconds since Jan 1, 2000 0:00:00 (UTC) */
2cfacb62
AL
73 uint32_t timestamp;
74
9c057d0b 75 char creator_app[4]; /* e.g., "vpc " */
2cfacb62
AL
76 uint16_t major;
77 uint16_t minor;
9c057d0b 78 char creator_os[4]; /* "Wi2k" */
2cfacb62
AL
79
80 uint64_t orig_size;
03671ded 81 uint64_t current_size;
2cfacb62
AL
82
83 uint16_t cyls;
84 uint8_t heads;
85 uint8_t secs_per_cyl;
86
87 uint32_t type;
88
9c057d0b
JC
89 /* Checksum of the Hard Disk Footer ("one's complement of the sum of all
90 the bytes in the footer without the checksum field") */
2cfacb62
AL
91 uint32_t checksum;
92
9c057d0b 93 /* UUID used to identify a parent hard disk (backing file) */
38440a21 94 QemuUUID uuid;
2cfacb62
AL
95
96 uint8_t in_saved_state;
e54835c0 97} QEMU_PACKED VHDFooter;
b9fa33a6 98
e54835c0 99typedef struct vhd_dyndisk_header {
9c057d0b 100 char magic[8]; /* "cxsparse" */
2cfacb62 101
9c057d0b 102 /* Offset of next header structure, 0xFFFFFFFF if none */
2cfacb62
AL
103 uint64_t data_offset;
104
9c057d0b 105 /* Offset of the Block Allocation Table (BAT) */
2cfacb62
AL
106 uint64_t table_offset;
107
108 uint32_t version;
9c057d0b 109 uint32_t max_table_entries; /* 32bit/entry */
2cfacb62 110
9c057d0b 111 /* 2 MB by default, must be a power of two */
2cfacb62
AL
112 uint32_t block_size;
113
114 uint32_t checksum;
115 uint8_t parent_uuid[16];
116 uint32_t parent_timestamp;
117 uint32_t reserved;
118
9c057d0b 119 /* Backing file name (in UTF-16) */
2cfacb62
AL
120 uint8_t parent_name[512];
121
122 struct {
123 uint32_t platform;
124 uint32_t data_space;
125 uint32_t data_length;
126 uint32_t reserved;
127 uint64_t data_offset;
128 } parent_locator[8];
e54835c0 129} QEMU_PACKED VHDDynDiskHeader;
6a0f9e82
FB
130
131typedef struct BDRVVPCState {
848c66e8 132 CoMutex lock;
15d35bc5
AL
133 uint8_t footer_buf[HEADER_SIZE];
134 uint64_t free_data_block_offset;
2cfacb62 135 int max_table_entries;
6a0f9e82 136 uint32_t *pagetable;
15d35bc5
AL
137 uint64_t bat_offset;
138 uint64_t last_bitmap_offset;
6a0f9e82 139
2cfacb62 140 uint32_t block_size;
15d35bc5 141 uint32_t bitmap_size;
c540d53a
JC
142 bool force_use_chs;
143 bool force_use_sz;
15d35bc5 144
6a0f9e82
FB
145#ifdef CACHE
146 uint8_t *pageentry_u8;
147 uint32_t *pageentry_u32;
148 uint16_t *pageentry_u16;
3b46e624 149
6a0f9e82
FB
150 uint64_t last_bitmap;
151#endif
612ff3d8
KW
152
153 Error *migration_blocker;
6a0f9e82
FB
154} BDRVVPCState;
155
c540d53a
JC
156#define VPC_OPT_SIZE_CALC "force_size_calc"
157static QemuOptsList vpc_runtime_opts = {
158 .name = "vpc-runtime-opts",
159 .head = QTAILQ_HEAD_INITIALIZER(vpc_runtime_opts.head),
160 .desc = {
161 {
162 .name = VPC_OPT_SIZE_CALC,
163 .type = QEMU_OPT_STRING,
164 .help = "Force disk size calculation to use either CHS geometry, "
165 "or use the disk current_size specified in the VHD footer. "
166 "{chs, current_size}"
167 },
168 { /* end of list */ }
169 }
170};
171
182c8835
KW
172static QemuOptsList vpc_create_opts;
173
57c7d9e5
AL
174static uint32_t vpc_checksum(uint8_t* buf, size_t size)
175{
176 uint32_t res = 0;
177 int i;
178
179 for (i = 0; i < size; i++)
180 res += buf[i];
181
182 return ~res;
183}
184
185
6a0f9e82
FB
186static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
187{
ffe8ab83 188 if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
6a0f9e82 189 return 100;
6a0f9e82
FB
190 return 0;
191}
192
c540d53a
JC
193static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
194 Error **errp)
195{
196 BDRVVPCState *s = bs->opaque;
197 const char *size_calc;
198
199 size_calc = qemu_opt_get(opts, VPC_OPT_SIZE_CALC);
200
201 if (!size_calc) {
202 /* no override, use autodetect only */
203 } else if (!strcmp(size_calc, "current_size")) {
204 s->force_use_sz = true;
205 } else if (!strcmp(size_calc, "chs")) {
206 s->force_use_chs = true;
207 } else {
208 error_setg(errp, "Invalid size calculation mode: '%s'", size_calc);
209 }
210}
211
015a1036
HR
212static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
213 Error **errp)
6a0f9e82
FB
214{
215 BDRVVPCState *s = bs->opaque;
66f82cee 216 int i;
e54835c0
JC
217 VHDFooter *footer;
218 VHDDynDiskHeader *dyndisk_header;
c540d53a
JC
219 QemuOpts *opts = NULL;
220 Error *local_err = NULL;
221 bool use_chs;
b9fa33a6 222 uint8_t buf[HEADER_SIZE];
57c7d9e5 223 uint32_t checksum;
97f1c45c 224 uint64_t computed_size;
b15deac7 225 uint64_t pagetable_size;
24da78db 226 int disk_type = VHD_DYNAMIC;
59294e46 227 int ret;
81caa3cc 228 int64_t bs_size;
6a0f9e82 229
4e4bf5c4
KW
230 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
231 false, errp);
232 if (!bs->file) {
233 return -EINVAL;
234 }
235
c540d53a
JC
236 opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort);
237 qemu_opts_absorb_qdict(opts, options, &local_err);
238 if (local_err) {
239 error_propagate(errp, local_err);
240 ret = -EINVAL;
241 goto fail;
242 }
243
244 vpc_parse_options(bs, opts, &local_err);
245 if (local_err) {
246 error_propagate(errp, local_err);
247 ret = -EINVAL;
248 goto fail;
249 }
250
cf2ab8fc 251 ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);
59294e46 252 if (ret < 0) {
32f6439c 253 error_setg(errp, "Unable to read VHD header");
6a0f9e82 254 goto fail;
59294e46 255 }
6a0f9e82 256
e54835c0 257 footer = (VHDFooter *) s->footer_buf;
24da78db 258 if (strncmp(footer->creator, "conectix", 8)) {
9a4f4c31 259 int64_t offset = bdrv_getlength(bs->file->bs);
59294e46
KW
260 if (offset < 0) {
261 ret = offset;
32f6439c 262 error_setg(errp, "Invalid file size");
59294e46
KW
263 goto fail;
264 } else if (offset < HEADER_SIZE) {
265 ret = -EINVAL;
32f6439c 266 error_setg(errp, "File too small for a VHD header");
24da78db
CA
267 goto fail;
268 }
59294e46 269
24da78db 270 /* If a fixed disk, the footer is found only at the end of the file */
cf2ab8fc 271 ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,
59294e46
KW
272 HEADER_SIZE);
273 if (ret < 0) {
24da78db
CA
274 goto fail;
275 }
276 if (strncmp(footer->creator, "conectix", 8)) {
76abe407
PB
277 error_setg(errp, "invalid VPC image");
278 ret = -EINVAL;
24da78db
CA
279 goto fail;
280 }
281 disk_type = VHD_FIXED;
282 }
6a0f9e82 283
57c7d9e5
AL
284 checksum = be32_to_cpu(footer->checksum);
285 footer->checksum = 0;
286 if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)
287 fprintf(stderr, "block-vpc: The header checksum of '%s' is "
66f82cee 288 "incorrect.\n", bs->filename);
57c7d9e5 289
c088b691 290 /* Write 'checksum' back to footer, or else will leave it with zero. */
a4127c42 291 footer->checksum = cpu_to_be32(checksum);
c088b691 292
9c057d0b
JC
293 /* The visible size of a image in Virtual PC depends on the geometry
294 rather than on the size stored in the footer (the size in the footer
295 is too large usually) */
33ccf667
SH
296 bs->total_sectors = (int64_t)
297 be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
1fa79228 298
c540d53a
JC
299 /* Microsoft Virtual PC and Microsoft Hyper-V produce and read
300 * VHD image sizes differently. VPC will rely on CHS geometry,
301 * while Hyper-V and disk2vhd use the size specified in the footer.
302 *
303 * We use a couple of approaches to try and determine the correct method:
304 * look at the Creator App field, and look for images that have CHS
305 * geometry that is the maximum value.
306 *
307 * If the CHS geometry is the maximum CHS geometry, then we assume that
308 * the size is the footer->current_size to avoid truncation. Otherwise,
309 * we follow the table based on footer->creator_app:
310 *
311 * Known creator apps:
312 * 'vpc ' : CHS Virtual PC (uses disk geometry)
313 * 'qemu' : CHS QEMU (uses disk geometry)
fb9245c2 314 * 'qem2' : current_size QEMU (uses current_size)
c540d53a
JC
315 * 'win ' : current_size Hyper-V
316 * 'd2v ' : current_size Disk2vhd
9bdfb9e8 317 * 'tap\0' : current_size XenServer
bab246db 318 * 'CTXS' : current_size XenConverter
c540d53a
JC
319 *
320 * The user can override the table values via drive options, however
321 * even with an override we will still use current_size for images
322 * that have CHS geometry of the maximum size.
323 */
324 use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
fb9245c2 325 !!strncmp(footer->creator_app, "qem2", 4) &&
9bdfb9e8 326 !!strncmp(footer->creator_app, "d2v ", 4) &&
bab246db 327 !!strncmp(footer->creator_app, "CTXS", 4) &&
9bdfb9e8 328 !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs;
c540d53a
JC
329
330 if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) {
03671ded 331 bs->total_sectors = be64_to_cpu(footer->current_size) /
c540d53a 332 BDRV_SECTOR_SIZE;
0173e7bb
PL
333 }
334
c23fb11b
JC
335 /* Allow a maximum disk size of 2040 GiB */
336 if (bs->total_sectors > VHD_MAX_SECTORS) {
59294e46 337 ret = -EFBIG;
efc8243d
SH
338 goto fail;
339 }
340
24da78db 341 if (disk_type == VHD_DYNAMIC) {
cf2ab8fc 342 ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
59294e46
KW
343 HEADER_SIZE);
344 if (ret < 0) {
32f6439c 345 error_setg(errp, "Error reading dynamic VHD header");
24da78db
CA
346 goto fail;
347 }
b9fa33a6 348
e54835c0 349 dyndisk_header = (VHDDynDiskHeader *) buf;
6a0f9e82 350
24da78db 351 if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
32f6439c 352 error_setg(errp, "Invalid header magic");
59294e46 353 ret = -EINVAL;
24da78db
CA
354 goto fail;
355 }
6a0f9e82 356
24da78db 357 s->block_size = be32_to_cpu(dyndisk_header->block_size);
5e71dfad
KW
358 if (!is_power_of_2(s->block_size) || s->block_size < BDRV_SECTOR_SIZE) {
359 error_setg(errp, "Invalid block size %" PRIu32, s->block_size);
360 ret = -EINVAL;
361 goto fail;
362 }
24da78db 363 s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
15d35bc5 364
24da78db 365 s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
97f1c45c
JC
366
367 if ((bs->total_sectors * 512) / s->block_size > 0xffffffffU) {
32f6439c 368 error_setg(errp, "Too many blocks");
97f1c45c
JC
369 ret = -EINVAL;
370 goto fail;
371 }
97f1c45c
JC
372
373 computed_size = (uint64_t) s->max_table_entries * s->block_size;
374 if (computed_size < bs->total_sectors * 512) {
32f6439c 375 error_setg(errp, "Page table too small");
97f1c45c
JC
376 ret = -EINVAL;
377 goto fail;
378 }
379
b15deac7
JC
380 if (s->max_table_entries > SIZE_MAX / 4 ||
381 s->max_table_entries > (int) INT_MAX / 4) {
382 error_setg(errp, "Max Table Entries too large (%" PRId32 ")",
383 s->max_table_entries);
384 ret = -EINVAL;
385 goto fail;
386 }
387
388 pagetable_size = (uint64_t) s->max_table_entries * 4;
389
9a4f4c31 390 s->pagetable = qemu_try_blockalign(bs->file->bs, pagetable_size);
5fb09cd5 391 if (s->pagetable == NULL) {
32f6439c 392 error_setg(errp, "Unable to allocate memory for page table");
5fb09cd5
KW
393 ret = -ENOMEM;
394 goto fail;
395 }
b71d1c2e 396
24da78db 397 s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
59294e46 398
cf2ab8fc 399 ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
9a4f4c31 400 pagetable_size);
59294e46 401 if (ret < 0) {
32f6439c 402 error_setg(errp, "Error reading pagetable");
24da78db
CA
403 goto fail;
404 }
b71d1c2e 405
24da78db 406 s->free_data_block_offset =
b15deac7 407 ROUND_UP(s->bat_offset + pagetable_size, 512);
15d35bc5 408
24da78db
CA
409 for (i = 0; i < s->max_table_entries; i++) {
410 be32_to_cpus(&s->pagetable[i]);
411 if (s->pagetable[i] != 0xFFFFFFFF) {
412 int64_t next = (512 * (int64_t) s->pagetable[i]) +
413 s->bitmap_size + s->block_size;
15d35bc5 414
24da78db
CA
415 if (next > s->free_data_block_offset) {
416 s->free_data_block_offset = next;
417 }
418 }
15d35bc5 419 }
15d35bc5 420
81caa3cc
EB
421 bs_size = bdrv_getlength(bs->file->bs);
422 if (bs_size < 0) {
423 error_setg_errno(errp, -bs_size, "Unable to learn image size");
424 ret = bs_size;
425 goto fail;
426 }
427 if (s->free_data_block_offset > bs_size) {
fb8fe35f
PL
428 error_setg(errp, "block-vpc: free_data_block_offset points after "
429 "the end of file. The image has been truncated.");
430 ret = -EINVAL;
431 goto fail;
432 }
433
24da78db 434 s->last_bitmap_offset = (int64_t) -1;
6a0f9e82 435
6a0f9e82 436#ifdef CACHE
24da78db
CA
437 s->pageentry_u8 = g_malloc(512);
438 s->pageentry_u32 = s->pageentry_u8;
439 s->pageentry_u16 = s->pageentry_u8;
440 s->last_pagetable = -1;
6a0f9e82 441#endif
24da78db 442 }
6a0f9e82 443
612ff3d8 444 /* Disable migration when VHD images are used */
81e5f78a
AG
445 error_setg(&s->migration_blocker, "The vpc format used by node '%s' "
446 "does not support live migration",
447 bdrv_get_device_or_node_name(bs));
fe44dc91
AA
448 ret = migrate_add_blocker(s->migration_blocker, &local_err);
449 if (local_err) {
450 error_propagate(errp, local_err);
451 error_free(s->migration_blocker);
452 goto fail;
453 }
454
455 qemu_co_mutex_init(&s->lock);
612ff3d8 456
6a0f9e82 457 return 0;
59294e46
KW
458
459fail:
97f1c45c 460 qemu_vfree(s->pagetable);
59294e46
KW
461#ifdef CACHE
462 g_free(s->pageentry_u8);
463#endif
464 return ret;
6a0f9e82
FB
465}
466
3fe4b700
JC
467static int vpc_reopen_prepare(BDRVReopenState *state,
468 BlockReopenQueue *queue, Error **errp)
469{
470 return 0;
471}
472
b71d1c2e
AL
473/*
474 * Returns the absolute byte offset of the given sector in the image file.
475 * If the sector is not allocated, -1 is returned instead.
cfc87e00
PM
476 * If an error occurred trying to write an updated block bitmap back to
477 * the file, -2 is returned, and the error value is written to *err.
478 * This can only happen for a write operation.
15d35bc5
AL
479 *
480 * The parameter write must be 1 if the offset will be used for a write
481 * operation (the block bitmaps is updated then), 0 otherwise.
cfc87e00 482 * If write is true then err must not be NULL.
b71d1c2e 483 */
d46b7cc6 484static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
cfc87e00 485 bool write, int *err)
6a0f9e82
FB
486{
487 BDRVVPCState *s = bs->opaque;
6a0f9e82 488 uint64_t bitmap_offset, block_offset;
d46b7cc6 489 uint32_t pagetable_index, offset_in_block;
6a0f9e82 490
cfc87e00
PM
491 assert(!(write && err == NULL));
492
2cfacb62 493 pagetable_index = offset / s->block_size;
d46b7cc6 494 offset_in_block = offset % s->block_size;
3b46e624 495
15d35bc5 496 if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
9c057d0b 497 return -1; /* not allocated */
6a0f9e82 498
378e2aea 499 bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
d46b7cc6 500 block_offset = bitmap_offset + s->bitmap_size + offset_in_block;
15d35bc5 501
9c057d0b
JC
502 /* We must ensure that we don't write to any sectors which are marked as
503 unused in the bitmap. We get away with setting all bits in the block
504 bitmap each time we write to a new block. This might cause Virtual PC to
505 miss sparse read optimization, but it's not a problem in terms of
506 correctness. */
15d35bc5
AL
507 if (write && (s->last_bitmap_offset != bitmap_offset)) {
508 uint8_t bitmap[s->bitmap_size];
cfc87e00 509 int r;
15d35bc5
AL
510
511 s->last_bitmap_offset = bitmap_offset;
512 memset(bitmap, 0xff, s->bitmap_size);
cfc87e00
PM
513 r = bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
514 if (r < 0) {
515 *err = r;
516 return -2;
517 }
15d35bc5 518 }
3b46e624 519
b71d1c2e 520 return block_offset;
6a0f9e82
FB
521}
522
15d35bc5
AL
523/*
524 * Writes the footer to the end of the image file. This is needed when the
525 * file grows as it overwrites the old footer
526 *
527 * Returns 0 on success and < 0 on error
528 */
529static int rewrite_footer(BlockDriverState* bs)
530{
531 int ret;
532 BDRVVPCState *s = bs->opaque;
533 int64_t offset = s->free_data_block_offset;
534
d9ca2ea2 535 ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
15d35bc5
AL
536 if (ret < 0)
537 return ret;
538
539 return 0;
540}
541
542/*
543 * Allocates a new block. This involves writing a new footer and updating
544 * the Block Allocation Table to use the space at the old end of the image
545 * file (overwriting the old footer)
546 *
547 * Returns the sectors' offset in the image file on success and < 0 on error
548 */
513b0f02 549static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
15d35bc5
AL
550{
551 BDRVVPCState *s = bs->opaque;
552 int64_t bat_offset;
553 uint32_t index, bat_value;
554 int ret;
555 uint8_t bitmap[s->bitmap_size];
556
9c057d0b 557 /* Check if sector_num is valid */
513b0f02
KW
558 if ((offset < 0) || (offset > bs->total_sectors * BDRV_SECTOR_SIZE)) {
559 return -EINVAL;
560 }
15d35bc5 561
9c057d0b 562 /* Write entry into in-memory BAT */
513b0f02
KW
563 index = offset / s->block_size;
564 assert(s->pagetable[index] == 0xFFFFFFFF);
15d35bc5
AL
565 s->pagetable[index] = s->free_data_block_offset / 512;
566
9c057d0b 567 /* Initialize the block's bitmap */
15d35bc5 568 memset(bitmap, 0xff, s->bitmap_size);
d9ca2ea2 569 ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
078a458e 570 s->bitmap_size);
5bb1cbac
KW
571 if (ret < 0) {
572 return ret;
573 }
15d35bc5 574
9c057d0b 575 /* Write new footer (the old one will be overwritten) */
15d35bc5
AL
576 s->free_data_block_offset += s->block_size + s->bitmap_size;
577 ret = rewrite_footer(bs);
578 if (ret < 0)
579 goto fail;
580
9c057d0b 581 /* Write BAT entry to disk */
15d35bc5 582 bat_offset = s->bat_offset + (4 * index);
a4127c42 583 bat_value = cpu_to_be32(s->pagetable[index]);
d9ca2ea2 584 ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
15d35bc5
AL
585 if (ret < 0)
586 goto fail;
587
cfc87e00 588 return get_image_offset(bs, offset, false, NULL);
15d35bc5
AL
589
590fail:
591 s->free_data_block_offset -= (s->block_size + s->bitmap_size);
513b0f02 592 return ret;
15d35bc5
AL
593}
594
97b00e28
PB
595static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
596{
597 BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
598 VHDFooter *footer = (VHDFooter *) s->footer_buf;
599
0d4cc3e7 600 if (be32_to_cpu(footer->type) != VHD_FIXED) {
97b00e28
PB
601 bdi->cluster_size = s->block_size;
602 }
603
95de6d70 604 bdi->unallocated_blocks_are_zero = true;
97b00e28
PB
605 return 0;
606}
607
d46b7cc6
KW
608static int coroutine_fn
609vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
610 QEMUIOVector *qiov, int flags)
6a0f9e82 611{
6c6ea921 612 BDRVVPCState *s = bs->opaque;
6a0f9e82 613 int ret;
d46b7cc6
KW
614 int64_t image_offset;
615 int64_t n_bytes;
616 int64_t bytes_done = 0;
e54835c0 617 VHDFooter *footer = (VHDFooter *) s->footer_buf;
d46b7cc6 618 QEMUIOVector local_qiov;
6a0f9e82 619
0d4cc3e7 620 if (be32_to_cpu(footer->type) == VHD_FIXED) {
a03ef88f 621 return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
24da78db 622 }
b71d1c2e 623
d46b7cc6
KW
624 qemu_co_mutex_lock(&s->lock);
625 qemu_iovec_init(&local_qiov, qiov->niov);
6c6ea921 626
d46b7cc6 627 while (bytes > 0) {
cfc87e00 628 image_offset = get_image_offset(bs, offset, false, NULL);
d46b7cc6
KW
629 n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
630
631 if (image_offset == -1) {
632 qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
b71d1c2e 633 } else {
d46b7cc6
KW
634 qemu_iovec_reset(&local_qiov);
635 qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
636
a03ef88f 637 ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
d46b7cc6
KW
638 &local_qiov, 0);
639 if (ret < 0) {
640 goto fail;
6c6ea921 641 }
b71d1c2e
AL
642 }
643
d46b7cc6
KW
644 bytes -= n_bytes;
645 offset += n_bytes;
646 bytes_done += n_bytes;
6a0f9e82 647 }
6a0f9e82 648
d46b7cc6
KW
649 ret = 0;
650fail:
651 qemu_iovec_destroy(&local_qiov);
2914caa0 652 qemu_co_mutex_unlock(&s->lock);
d46b7cc6 653
2914caa0
PB
654 return ret;
655}
656
513b0f02
KW
657static int coroutine_fn
658vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
659 QEMUIOVector *qiov, int flags)
15d35bc5 660{
6c6ea921 661 BDRVVPCState *s = bs->opaque;
513b0f02
KW
662 int64_t image_offset;
663 int64_t n_bytes;
664 int64_t bytes_done = 0;
c8115f8e 665 int ret = 0;
e54835c0 666 VHDFooter *footer = (VHDFooter *) s->footer_buf;
513b0f02 667 QEMUIOVector local_qiov;
15d35bc5 668
0d4cc3e7 669 if (be32_to_cpu(footer->type) == VHD_FIXED) {
a03ef88f 670 return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
24da78db 671 }
15d35bc5 672
513b0f02
KW
673 qemu_co_mutex_lock(&s->lock);
674 qemu_iovec_init(&local_qiov, qiov->niov);
675
676 while (bytes > 0) {
cfc87e00
PM
677 image_offset = get_image_offset(bs, offset, true, &ret);
678 if (image_offset == -2) {
679 /* Failed to write block bitmap: can't proceed with write */
680 goto fail;
681 }
513b0f02 682 n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
6c6ea921 683
513b0f02
KW
684 if (image_offset == -1) {
685 image_offset = alloc_block(bs, offset);
686 if (image_offset < 0) {
687 ret = image_offset;
688 goto fail;
689 }
15d35bc5
AL
690 }
691
513b0f02
KW
692 qemu_iovec_reset(&local_qiov);
693 qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
694
a03ef88f 695 ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
513b0f02
KW
696 &local_qiov, 0);
697 if (ret < 0) {
698 goto fail;
6c6ea921 699 }
15d35bc5 700
513b0f02
KW
701 bytes -= n_bytes;
702 offset += n_bytes;
703 bytes_done += n_bytes;
15d35bc5
AL
704 }
705
513b0f02
KW
706 ret = 0;
707fail:
708 qemu_iovec_destroy(&local_qiov);
e183ef75 709 qemu_co_mutex_unlock(&s->lock);
513b0f02 710
e183ef75
PB
711 return ret;
712}
713
2f83673b
EB
714static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
715 bool want_zero,
716 int64_t offset, int64_t bytes,
717 int64_t *pnum, int64_t *map,
718 BlockDriverState **file)
0cc84887
KW
719{
720 BDRVVPCState *s = bs->opaque;
721 VHDFooter *footer = (VHDFooter*) s->footer_buf;
2f83673b 722 int64_t image_offset;
0cc84887 723 bool allocated;
2f83673b
EB
724 int ret;
725 int64_t n;
0cc84887
KW
726
727 if (be32_to_cpu(footer->type) == VHD_FIXED) {
2f83673b
EB
728 *pnum = bytes;
729 *map = offset;
7429e207 730 *file = bs->file->bs;
2f83673b 731 return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
0cc84887
KW
732 }
733
778b087e
PB
734 qemu_co_mutex_lock(&s->lock);
735
2f83673b
EB
736 image_offset = get_image_offset(bs, offset, false, NULL);
737 allocated = (image_offset != -1);
0cc84887 738 *pnum = 0;
778b087e 739 ret = 0;
0cc84887
KW
740
741 do {
742 /* All sectors in a block are contiguous (without using the bitmap) */
2f83673b
EB
743 n = ROUND_UP(offset + 1, s->block_size) - offset;
744 n = MIN(n, bytes);
0cc84887
KW
745
746 *pnum += n;
2f83673b
EB
747 offset += n;
748 bytes -= n;
2ec711dc
PL
749 /* *pnum can't be greater than one block for allocated
750 * sectors since there is always a bitmap in between. */
751 if (allocated) {
7429e207 752 *file = bs->file->bs;
2f83673b
EB
753 *map = image_offset;
754 ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
778b087e 755 break;
2ec711dc 756 }
2f83673b 757 if (bytes == 0) {
0cc84887
KW
758 break;
759 }
2f83673b
EB
760 image_offset = get_image_offset(bs, offset, false, NULL);
761 } while (image_offset == -1);
0cc84887 762
778b087e
PB
763 qemu_co_mutex_unlock(&s->lock);
764 return ret;
0cc84887
KW
765}
766
57c7d9e5
AL
767/*
768 * Calculates the number of cylinders, heads and sectors per cylinder
769 * based on a given number of sectors. This is the algorithm described
770 * in the VHD specification.
771 *
772 * Note that the geometry doesn't always exactly match total_sectors but
773 * may round it down.
6e9ea0c0 774 *
c23fb11b 775 * Returns 0 on success, -EFBIG if the size is larger than 2040 GiB. Override
258d2edb
CA
776 * the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
777 * and instead allow up to 255 heads.
57c7d9e5 778 */
6e9ea0c0 779static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
57c7d9e5
AL
780 uint8_t* heads, uint8_t* secs_per_cyl)
781{
782 uint32_t cyls_times_heads;
783
690cbb09 784 total_sectors = MIN(total_sectors, VHD_MAX_GEOMETRY);
57c7d9e5 785
690cbb09 786 if (total_sectors >= 65535LL * 16 * 63) {
57c7d9e5 787 *secs_per_cyl = 255;
690cbb09 788 *heads = 16;
57c7d9e5
AL
789 cyls_times_heads = total_sectors / *secs_per_cyl;
790 } else {
791 *secs_per_cyl = 17;
792 cyls_times_heads = total_sectors / *secs_per_cyl;
13f1493f 793 *heads = DIV_ROUND_UP(cyls_times_heads, 1024);
57c7d9e5 794
690cbb09 795 if (*heads < 4) {
57c7d9e5 796 *heads = 4;
690cbb09 797 }
57c7d9e5
AL
798
799 if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {
800 *secs_per_cyl = 31;
801 *heads = 16;
802 cyls_times_heads = total_sectors / *secs_per_cyl;
803 }
804
805 if (cyls_times_heads >= (*heads * 1024)) {
806 *secs_per_cyl = 63;
807 *heads = 16;
808 cyls_times_heads = total_sectors / *secs_per_cyl;
809 }
810 }
811
dede4188 812 *cyls = cyls_times_heads / *heads;
6e9ea0c0
AJ
813
814 return 0;
57c7d9e5
AL
815}
816
b8f45cdf 817static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
fef6070e 818 int64_t total_sectors)
57c7d9e5 819{
e54835c0
JC
820 VHDDynDiskHeader *dyndisk_header =
821 (VHDDynDiskHeader *) buf;
57c7d9e5 822 size_t block_size, num_bat_entries;
24da78db 823 int i;
fef6070e
JC
824 int ret;
825 int64_t offset = 0;
57c7d9e5 826
9c057d0b 827 /* Write the footer (twice: at the beginning and at the end) */
57c7d9e5
AL
828 block_size = 0x200000;
829 num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
830
8341f00d 831 ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
40a99aac 832 if (ret < 0) {
f0ff243a
BS
833 goto fail;
834 }
57c7d9e5 835
fef6070e 836 offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
8341f00d 837 ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
fef6070e 838 if (ret < 0) {
f0ff243a
BS
839 goto fail;
840 }
57c7d9e5 841
9c057d0b 842 /* Write the initial BAT */
fef6070e 843 offset = 3 * 512;
57c7d9e5
AL
844
845 memset(buf, 0xFF, 512);
13f1493f 846 for (i = 0; i < DIV_ROUND_UP(num_bat_entries * 4, 512); i++) {
8341f00d 847 ret = blk_pwrite(blk, offset, buf, 512, 0);
fef6070e 848 if (ret < 0) {
f0ff243a
BS
849 goto fail;
850 }
fef6070e 851 offset += 512;
f0ff243a 852 }
57c7d9e5 853
9c057d0b 854 /* Prepare the Dynamic Disk Header */
57c7d9e5
AL
855 memset(buf, 0, 1024);
856
5ec4d682 857 memcpy(dyndisk_header->magic, "cxsparse", 8);
57c7d9e5 858
78439f6a
CA
859 /*
860 * Note: The spec is actually wrong here for data_offset, it says
861 * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
862 */
a4127c42
SH
863 dyndisk_header->data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
864 dyndisk_header->table_offset = cpu_to_be64(3 * 512);
865 dyndisk_header->version = cpu_to_be32(0x00010000);
866 dyndisk_header->block_size = cpu_to_be32(block_size);
867 dyndisk_header->max_table_entries = cpu_to_be32(num_bat_entries);
57c7d9e5 868
a4127c42 869 dyndisk_header->checksum = cpu_to_be32(vpc_checksum(buf, 1024));
57c7d9e5 870
9c057d0b 871 /* Write the header */
fef6070e 872 offset = 512;
57c7d9e5 873
8341f00d 874 ret = blk_pwrite(blk, offset, buf, 1024, 0);
fef6070e 875 if (ret < 0) {
f0ff243a
BS
876 goto fail;
877 }
f0ff243a 878
24da78db
CA
879 fail:
880 return ret;
881}
882
b8f45cdf 883static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
ed3d2ec9 884 int64_t total_size, Error **errp)
24da78db 885{
fef6070e 886 int ret;
24da78db
CA
887
888 /* Add footer to total size */
fef6070e
JC
889 total_size += HEADER_SIZE;
890
3a691c50 891 ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, errp);
fef6070e
JC
892 if (ret < 0) {
893 return ret;
24da78db
CA
894 }
895
8341f00d 896 ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
fef6070e 897 if (ret < 0) {
ed3d2ec9 898 error_setg_errno(errp, -ret, "Unable to write VHD header");
fef6070e
JC
899 return ret;
900 }
24da78db 901
24da78db
CA
902 return ret;
903}
904
1cfeaf38
KW
905static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
906 uint16_t *out_cyls,
907 uint8_t *out_heads,
908 uint8_t *out_secs_per_cyl,
909 int64_t *out_total_sectors,
910 Error **errp)
911{
912 int64_t total_size = vpc_opts->size;
913 uint16_t cyls = 0;
914 uint8_t heads = 0;
915 uint8_t secs_per_cyl = 0;
916 int64_t total_sectors;
917 int i;
918
919 /*
920 * Calculate matching total_size and geometry. Increase the number of
921 * sectors requested until we get enough (or fail). This ensures that
922 * qemu-img convert doesn't truncate images, but rather rounds up.
923 *
924 * If the image size can't be represented by a spec conformant CHS geometry,
925 * we set the geometry to 65535 x 16 x 255 (CxHxS) sectors and use
926 * the image size from the VHD footer to calculate total_sectors.
927 */
928 if (vpc_opts->force_size) {
929 /* This will force the use of total_size for sector count, below */
930 cyls = VHD_CHS_MAX_C;
931 heads = VHD_CHS_MAX_H;
932 secs_per_cyl = VHD_CHS_MAX_S;
933 } else {
934 total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE);
935 for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
936 calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl);
937 }
938 }
939
940 if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
941 total_sectors = total_size / BDRV_SECTOR_SIZE;
942 /* Allow a maximum disk size of 2040 GiB */
943 if (total_sectors > VHD_MAX_SECTORS) {
944 error_setg(errp, "Disk size is too large, max size is 2040 GiB");
945 return -EFBIG;
946 }
947 } else {
948 total_sectors = (int64_t) cyls * heads * secs_per_cyl;
949 }
950
951 *out_total_sectors = total_sectors;
952 if (out_cyls) {
953 *out_cyls = cyls;
954 *out_heads = heads;
955 *out_secs_per_cyl = secs_per_cyl;
956 }
957
958 return 0;
959}
960
182c8835
KW
961static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
962 Error **errp)
24da78db 963{
182c8835
KW
964 BlockdevCreateOptionsVpc *vpc_opts;
965 BlockBackend *blk = NULL;
966 BlockDriverState *bs = NULL;
967
24da78db 968 uint8_t buf[1024];
e54835c0 969 VHDFooter *footer = (VHDFooter *) buf;
24da78db
CA
970 uint16_t cyls = 0;
971 uint8_t heads = 0;
972 uint8_t secs_per_cyl = 0;
973 int64_t total_sectors;
974 int64_t total_size;
975 int disk_type;
976 int ret = -EIO;
977
182c8835
KW
978 assert(opts->driver == BLOCKDEV_DRIVER_VPC);
979 vpc_opts = &opts->u.vpc;
980
981 /* Validate options and set default values */
982 total_size = vpc_opts->size;
983
984 if (!vpc_opts->has_subformat) {
985 vpc_opts->subformat = BLOCKDEV_VPC_SUBFORMAT_DYNAMIC;
986 }
987 switch (vpc_opts->subformat) {
988 case BLOCKDEV_VPC_SUBFORMAT_DYNAMIC:
24da78db 989 disk_type = VHD_DYNAMIC;
182c8835
KW
990 break;
991 case BLOCKDEV_VPC_SUBFORMAT_FIXED:
992 disk_type = VHD_FIXED;
993 break;
994 default:
995 g_assert_not_reached();
24da78db
CA
996 }
997
182c8835
KW
998 /* Create BlockBackend to write to the image */
999 bs = bdrv_open_blockdev_ref(vpc_opts->file, errp);
1000 if (bs == NULL) {
1001 return -EIO;
24da78db 1002 }
b8f45cdf 1003
182c8835
KW
1004 blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
1005 ret = blk_insert_bs(blk, bs, errp);
1006 if (ret < 0) {
fef6070e 1007 goto out;
4ab15590 1008 }
b8f45cdf
KW
1009 blk_set_allow_write_beyond_eof(blk, true);
1010
1cfeaf38
KW
1011 /* Get geometry and check that it matches the image size*/
1012 ret = calculate_rounded_image_size(vpc_opts, &cyls, &heads, &secs_per_cyl,
1013 &total_sectors, errp);
1014 if (ret < 0) {
1015 goto out;
690cbb09
PL
1016 }
1017
1cfeaf38
KW
1018 if (total_size != total_sectors * BDRV_SECTOR_SIZE) {
1019 error_setg(errp, "The requested image size cannot be represented in "
1020 "CHS geometry");
1021 error_append_hint(errp, "Try size=%llu or force-size=on (the "
1022 "latter makes the image incompatible with "
1023 "Virtual PC)",
1024 total_sectors * BDRV_SECTOR_SIZE);
1025 ret = -EINVAL;
1026 goto out;
24da78db 1027 }
ecd880d9 1028
24da78db
CA
1029 /* Prepare the Hard Disk Footer */
1030 memset(buf, 0, 1024);
1031
1032 memcpy(footer->creator, "conectix", 8);
182c8835 1033 if (vpc_opts->force_size) {
fb9245c2
JC
1034 memcpy(footer->creator_app, "qem2", 4);
1035 } else {
1036 memcpy(footer->creator_app, "qemu", 4);
1037 }
24da78db
CA
1038 memcpy(footer->creator_os, "Wi2k", 4);
1039
a4127c42
SH
1040 footer->features = cpu_to_be32(0x02);
1041 footer->version = cpu_to_be32(0x00010000);
24da78db 1042 if (disk_type == VHD_DYNAMIC) {
a4127c42 1043 footer->data_offset = cpu_to_be64(HEADER_SIZE);
24da78db 1044 } else {
a4127c42 1045 footer->data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
24da78db 1046 }
a4127c42 1047 footer->timestamp = cpu_to_be32(time(NULL) - VHD_TIMESTAMP_BASE);
24da78db
CA
1048
1049 /* Version of Virtual PC 2007 */
a4127c42
SH
1050 footer->major = cpu_to_be16(0x0005);
1051 footer->minor = cpu_to_be16(0x0003);
3f3f20dc 1052 footer->orig_size = cpu_to_be64(total_size);
03671ded 1053 footer->current_size = cpu_to_be64(total_size);
a4127c42 1054 footer->cyls = cpu_to_be16(cyls);
24da78db
CA
1055 footer->heads = heads;
1056 footer->secs_per_cyl = secs_per_cyl;
1057
a4127c42 1058 footer->type = cpu_to_be32(disk_type);
24da78db 1059
38440a21 1060 qemu_uuid_generate(&footer->uuid);
24da78db 1061
a4127c42 1062 footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
24da78db
CA
1063
1064 if (disk_type == VHD_DYNAMIC) {
b8f45cdf 1065 ret = create_dynamic_disk(blk, buf, total_sectors);
ed3d2ec9
HR
1066 if (ret < 0) {
1067 error_setg(errp, "Unable to create or write VHD header");
1068 }
24da78db 1069 } else {
ed3d2ec9 1070 ret = create_fixed_disk(blk, buf, total_size, errp);
0211b9be 1071 }
24da78db 1072
fec9921f 1073out:
b8f45cdf 1074 blk_unref(blk);
182c8835
KW
1075 bdrv_unref(bs);
1076 return ret;
1077}
1078
1079static int coroutine_fn vpc_co_create_opts(const char *filename,
1080 QemuOpts *opts, Error **errp)
1081{
1082 BlockdevCreateOptions *create_options = NULL;
1083 QDict *qdict = NULL;
1084 QObject *qobj;
1085 Visitor *v;
1086 BlockDriverState *bs = NULL;
1087 Error *local_err = NULL;
1088 int ret;
1089
1090 static const QDictRenames opt_renames[] = {
1091 { VPC_OPT_FORCE_SIZE, "force-size" },
1092 { NULL, NULL },
1093 };
1094
1095 /* Parse options and convert legacy syntax */
1096 qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vpc_create_opts, true);
1097
1098 if (!qdict_rename_keys(qdict, opt_renames, errp)) {
1099 ret = -EINVAL;
1100 goto fail;
1101 }
1102
1103 /* Create and open the file (protocol layer) */
1104 ret = bdrv_create_file(filename, opts, &local_err);
1105 if (ret < 0) {
1106 error_propagate(errp, local_err);
1107 goto fail;
1108 }
1109
1110 bs = bdrv_open(filename, NULL, NULL,
1111 BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
1112 if (bs == NULL) {
1113 ret = -EIO;
1114 goto fail;
1115 }
1116
1117 /* Now get the QAPI type BlockdevCreateOptions */
1118 qdict_put_str(qdict, "driver", "vpc");
1119 qdict_put_str(qdict, "file", bs->node_name);
1120
1121 qobj = qdict_crumple(qdict, errp);
cb3e7f08 1122 qobject_unref(qdict);
7dc847eb 1123 qdict = qobject_to(QDict, qobj);
182c8835
KW
1124 if (qdict == NULL) {
1125 ret = -EINVAL;
1126 goto fail;
1127 }
1128
1129 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
1130 visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
1131 visit_free(v);
1132
1133 if (local_err) {
1134 error_propagate(errp, local_err);
1135 ret = -EINVAL;
1136 goto fail;
1137 }
1138
1139 /* Silently round up size */
1140 assert(create_options->driver == BLOCKDEV_DRIVER_VPC);
1141 create_options->u.vpc.size =
1142 ROUND_UP(create_options->u.vpc.size, BDRV_SECTOR_SIZE);
1143
1cfeaf38
KW
1144 if (!create_options->u.vpc.force_size) {
1145 int64_t total_sectors;
1146 ret = calculate_rounded_image_size(&create_options->u.vpc, NULL, NULL,
1147 NULL, &total_sectors, errp);
1148 if (ret < 0) {
1149 goto fail;
1150 }
1151
1152 create_options->u.vpc.size = total_sectors * BDRV_SECTOR_SIZE;
1153 }
1154
1155
182c8835
KW
1156 /* Create the vpc image (format layer) */
1157 ret = vpc_co_create(create_options, errp);
1158
1159fail:
cb3e7f08 1160 qobject_unref(qdict);
182c8835
KW
1161 bdrv_unref(bs);
1162 qapi_free_BlockdevCreateOptions(create_options);
f0ff243a 1163 return ret;
57c7d9e5
AL
1164}
1165
182c8835 1166
72c6cc94
KW
1167static int vpc_has_zero_init(BlockDriverState *bs)
1168{
1169 BDRVVPCState *s = bs->opaque;
e54835c0 1170 VHDFooter *footer = (VHDFooter *) s->footer_buf;
72c6cc94 1171
0d4cc3e7 1172 if (be32_to_cpu(footer->type) == VHD_FIXED) {
9a4f4c31 1173 return bdrv_has_zero_init(bs->file->bs);
72c6cc94
KW
1174 } else {
1175 return 1;
1176 }
1177}
1178
6a0f9e82
FB
1179static void vpc_close(BlockDriverState *bs)
1180{
1181 BDRVVPCState *s = bs->opaque;
97f1c45c 1182 qemu_vfree(s->pagetable);
6a0f9e82 1183#ifdef CACHE
7267c094 1184 g_free(s->pageentry_u8);
6a0f9e82 1185#endif
612ff3d8
KW
1186
1187 migrate_del_blocker(s->migration_blocker);
1188 error_free(s->migration_blocker);
6a0f9e82
FB
1189}
1190
fec9921f
CL
1191static QemuOptsList vpc_create_opts = {
1192 .name = "vpc-create-opts",
1193 .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
1194 .desc = {
1195 {
1196 .name = BLOCK_OPT_SIZE,
1197 .type = QEMU_OPT_SIZE,
1198 .help = "Virtual disk size"
1199 },
1200 {
1201 .name = BLOCK_OPT_SUBFMT,
1202 .type = QEMU_OPT_STRING,
1203 .help =
1204 "Type of virtual hard disk format. Supported formats are "
1205 "{dynamic (default) | fixed} "
1206 },
fb9245c2
JC
1207 {
1208 .name = VPC_OPT_FORCE_SIZE,
1209 .type = QEMU_OPT_BOOL,
1210 .help = "Force disk size calculation to use the actual size "
1211 "specified, rather than using the nearest CHS-based "
1212 "calculation"
1213 },
fec9921f
CL
1214 { /* end of list */ }
1215 }
0e7e1989
KW
1216};
1217
5efa9d5a 1218static BlockDriver bdrv_vpc = {
4a411185
KW
1219 .format_name = "vpc",
1220 .instance_size = sizeof(BDRVVPCState),
c68b89ac 1221
72c6cc94
KW
1222 .bdrv_probe = vpc_probe,
1223 .bdrv_open = vpc_open,
1224 .bdrv_close = vpc_close,
1225 .bdrv_reopen_prepare = vpc_reopen_prepare,
862f215f 1226 .bdrv_child_perm = bdrv_format_default_perms,
182c8835 1227 .bdrv_co_create = vpc_co_create,
efc75e2a 1228 .bdrv_co_create_opts = vpc_co_create_opts,
0e7e1989 1229
d46b7cc6 1230 .bdrv_co_preadv = vpc_co_preadv,
513b0f02 1231 .bdrv_co_pwritev = vpc_co_pwritev,
2f83673b 1232 .bdrv_co_block_status = vpc_co_block_status,
c68b89ac 1233
97b00e28
PB
1234 .bdrv_get_info = vpc_get_info,
1235
fec9921f 1236 .create_opts = &vpc_create_opts,
72c6cc94 1237 .bdrv_has_zero_init = vpc_has_zero_init,
6a0f9e82 1238};
5efa9d5a
AL
1239
1240static void bdrv_vpc_init(void)
1241{
1242 bdrv_register(&bdrv_vpc);
1243}
1244
1245block_init(bdrv_vpc_init);