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