Skip to contentSkip to conversation

block: .bdrv_co_create for format drivers

PATCH Applied Kevin Wolf 2 participants 14 messages Mar 13, 2018 Block layer

lore
Share & tools
lore

Kevin Wolf

author
#0 lore raw

v2 cover block: .bdrv_co_create for format drivers

This series adds a .bdrv_co_create implementation to almost all format drivers that support creating images where its still missing. The only exception is VMDK because its support for extents will make the QAPI design a bit more complicated.

The other format driver not covered in this series are qcow2 (already merged) and luks (already posted in a separate series).

v2:
- Rebased, the vdi patch consists just of some cosmetic cleanups now
- vhdx, vpc: Don't do any silent rounding in .bdrv_co_create, error out if the passed size isn't properly aligned yet. The legacy code paths compensate for this.

Kevin Wolf (8):
parallels: Support .bdrv_co_create
qemu-iotests: Enable write tests for parallels
qcow: Support .bdrv_co_create
qed: Support .bdrv_co_create
vdi: Make comments consistent with other drivers
vhdx: Support .bdrv_co_create
vpc: Support .bdrv_co_create
vpc: Require aligned size in .bdrv_co_create

 qapi/block-core.json     | 137 ++++++++++++++++++++++++++-
 block/parallels.c        | 199 ++++++++++++++++++++++++++++----------
 block/qcow.c             | 196 +++++++++++++++++++++++++-------------
 block/qed.c              | 204 ++++++++++++++++++++++++++-------------
 block/vdi.c              |  12 ++-
 block/vhdx.c             | 216 ++++++++++++++++++++++++++++++++----------
 block/vpc.c              | 241 ++++++++++++++++++++++++++++++++++++-----------
 tests/qemu-iotests/181   |   2 +-
 tests/qemu-iotests/check |   1 -
 9 files changed, 910 insertions(+), 298 deletions(-)
Signature · 1 line
2.13.6
author
#1 lore raw

PATCH v2 1/8 parallels: Support .bdrv_co_create

This adds the .bdrv_co_create driver callback to parallels, which enables image creation over QMP.

---
 qapi/block-core.json |  18 ++++-
 block/parallels.c    | 199 ++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 168 insertions(+), 49 deletions(-)
qapi/block-core.json +17 -1
index 6211b8222c..e0ab01d92d 100644
@@ -3625,6 +3625,22 @@
             'size':             'size' } }
 
 ##
+# @BlockdevCreateOptionsParallels:
+#
+# Driver specific image creation options for parallels.
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @cluster-size     Cluster size in bytes (default: 1 MB)
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsParallels',
+  'data': { 'file':             'BlockdevRef',
+            'size':             'size',
+            '*cluster-size':    'size' } }
+
+##
 # @BlockdevQcow2Version:
 #
 # @v2:  The original QCOW2 format as introduced in qemu 0.10 (version 2)
@@ -3826,7 +3842,7 @@
       'null-aio':       'BlockdevCreateNotSupported',
       'null-co':        'BlockdevCreateNotSupported',
       'nvme':           'BlockdevCreateNotSupported',
-      'parallels':      'BlockdevCreateNotSupported',
+      'parallels':      'BlockdevCreateOptionsParallels',
       'qcow2':          'BlockdevCreateOptionsQcow2',
       'qcow':           'BlockdevCreateNotSupported',
       'qed':            'BlockdevCreateNotSupported',
block/parallels.c +151 -48

264 lines not on this page · raw message

Signature · 1 line
2.13.6
author
#2 lore raw

PATCH v2 2/8 qemu-iotests: Enable write tests for parallels

In reply to Kevin Wolf

Originally we added parallels as a read-only format to qemu-iotests where we did just some tests with a binary image. Since then, write and image creation support has been added to the driver, so we can now enable it in _supported_fmt generic.

The driver doesn't support migration yet, though, so we need to add it to the list of exceptions in 181.

---
 tests/qemu-iotests/181   | 2 +-
 tests/qemu-iotests/check | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)
tests/qemu-iotests/181 +1 -1
index 0c91e8f9de..5e767c6195 100755
@@ -44,7 +44,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt generic
 # Formats that do not support live migration
-_unsupported_fmt qcow vdi vhdx vmdk vpc vvfat
+_unsupported_fmt qcow vdi vhdx vmdk vpc vvfat parallels
 _supported_proto generic
 _supported_os Linux
 
tests/qemu-iotests/check +0 -1
index e6b6ff7a04..469142cd58 100755
@@ -284,7 +284,6 @@ testlist options
 
         -parallels)
             IMGFMT=parallels
-            IMGFMT_GENERIC=false
             xpand=false
             ;;
 
Signature · 1 line
2.13.6
author
#3 lore raw

PATCH v2 3/8 qcow: Support .bdrv_co_create

In reply to Kevin Wolf

This adds the .bdrv_co_create driver callback to qcow, which enables image creation over QMP.

---
 qapi/block-core.json |  21 +++++-
 block/qcow.c         | 196 ++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 150 insertions(+), 67 deletions(-)
qapi/block-core.json +20 -1
index e0ab01d92d..7b7d5a01fd 100644
@@ -3641,6 +3641,25 @@
             '*cluster-size':    'size' } }
 
 ##
+# @BlockdevCreateOptionsQcow:
+#
+# Driver specific image creation options for qcow.
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @backing-file     File name of the backing file if a backing file
+#                   should be used
+# @encrypt          Encryption options if the image should be encrypted
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsQcow',
+  'data': { 'file':             'BlockdevRef',
+            'size':             'size',
+            '*backing-file':    'str',
+            '*encrypt':         'QCryptoBlockCreateOptions' } }
+
+##
 # @BlockdevQcow2Version:
 #
 # @v2:  The original QCOW2 format as introduced in qemu 0.10 (version 2)
@@ -3843,8 +3862,8 @@
       'null-co':        'BlockdevCreateNotSupported',
       'nvme':           'BlockdevCreateNotSupported',
       'parallels':      'BlockdevCreateOptionsParallels',
+      'qcow':           'BlockdevCreateOptionsQcow',
       'qcow2':          'BlockdevCreateOptionsQcow2',
-      'qcow':           'BlockdevCreateNotSupported',
       'qed':            'BlockdevCreateNotSupported',
       'quorum':         'BlockdevCreateNotSupported',
       'raw':            'BlockdevCreateNotSupported',
block/qcow.c +130 -66

273 lines not on this page · raw message

Signature · 1 line
2.13.6
author
#4 lore raw

PATCH v2 4/8 qed: Support .bdrv_co_create

In reply to Kevin Wolf

This adds the .bdrv_co_create driver callback to qed, which enables image creation over QMP.

---
 qapi/block-core.json |  25 ++++++-
 block/qed.c          | 204 ++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 162 insertions(+), 67 deletions(-)
qapi/block-core.json +24 -1
index 7b7d5a01fd..d091817855 100644
@@ -3703,6 +3703,29 @@
             '*refcount-bits':   'int' } }
 
 ##
+# @BlockdevCreateOptionsQed:
+#
+# Driver specific image creation options for qed.
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @backing-file     File name of the backing file if a backing file
+#                   should be used
+# @backing-fmt      Name of the block driver to use for the backing file
+# @cluster-size     Cluster size in bytes (default: 65536)
+# @table-size       L1/L2 table size (in clusters)
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsQed',
+  'data': { 'file':             'BlockdevRef',
+            'size':             'size',
+            '*backing-file':    'str',
+            '*backing-fmt':     'BlockdevDriver',
+            '*cluster-size':    'size',
+            '*table-size':      'int' } }
+
+##
 # @BlockdevCreateOptionsRbd:
 #
 # Driver specific image creation options for rbd/Ceph.
@@ -3864,7 +3887,7 @@
       'parallels':      'BlockdevCreateOptionsParallels',
       'qcow':           'BlockdevCreateOptionsQcow',
       'qcow2':          'BlockdevCreateOptionsQcow2',
-      'qed':            'BlockdevCreateNotSupported',
+      'qed':            'BlockdevCreateOptionsQed',
       'quorum':         'BlockdevCreateNotSupported',
       'raw':            'BlockdevCreateNotSupported',
       'rbd':            'BlockdevCreateOptionsRbd',
block/qed.c +138 -66

271 lines not on this page · raw message

Signature · 1 line
2.13.6
author
#5 lore raw

PATCH v2 5/8 vdi: Make comments consistent with other drivers

In reply to Kevin Wolf

This makes the .bdrv_co_create(_opts) implementation of vdi look more like the other recently converted block drivers.

---
 block/vdi.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
block/vdi.c +9 -3
index 8132e3adfe..d939b034c4 100644
@@ -742,7 +742,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
 
     logout("\n");
 
-    /* Read out options. */
+    /* Validate options and set default values */
     bytes = vdi_opts->size;
     if (vdi_opts->q_static) {
         image_type = VDI_TYPE_STATIC;
@@ -772,6 +772,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
         goto exit;
     }
 
+    /* Create BlockBackend to write to the image */
     bs_file = bdrv_open_blockdev_ref(vdi_opts->file, errp);
     if (!bs_file) {
         ret = -EIO;
@@ -877,7 +878,9 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
     Error *local_err = NULL;
     int ret;
 
-    /* Since CONFIG_VDI_BLOCK_SIZE is disabled by default,
+    /* Parse options and convert legacy syntax.
+     *
+     * Since CONFIG_VDI_BLOCK_SIZE is disabled by default,
      * cluster-size is not part of the QAPI schema; therefore we have
      * to parse it before creating the QAPI object. */
 #if defined(CONFIG_VDI_BLOCK_SIZE)
@@ -895,6 +898,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
 
     qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vdi_create_opts, true);
 
+    /* Create and open the file (protocol layer) */
     ret = bdrv_create_file(filename, opts, errp);
     if (ret < 0) {
         goto done;
@@ -921,10 +925,12 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
         goto done;
     }
 
+    /* Silently round up size */
     assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
     create_options->u.vdi.size = ROUND_UP(create_options->u.vdi.size,
                                           BDRV_SECTOR_SIZE);
 
+    /* Create the vdi image (format layer) */
     ret = vdi_co_do_create(create_options, block_size, errp);
 done:
     QDECREF(qdict);
@@ -981,8 +987,8 @@ static BlockDriver bdrv_vdi = {
     .bdrv_close = vdi_close,
     .bdrv_reopen_prepare = vdi_reopen_prepare,
     .bdrv_child_perm          = bdrv_format_default_perms,
-    .bdrv_co_create_opts = vdi_co_create_opts,
     .bdrv_co_create      = vdi_co_create,
+    .bdrv_co_create_opts = vdi_co_create_opts,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_block_status = vdi_co_block_status,
     .bdrv_make_empty = vdi_make_empty,
Signature · 1 line
2.13.6
Reviewed-by on v2 5/8
#6 lore raw

Re: [Qemu-devel] [PATCH v2 5/8] vdi: Make comments consistent with other drivers

Quoted 7 lines · Kevin Wolf

This makes the .bdrv_co_create(_opts) implementation of vdi look more like the other recently converted block drivers.

---
 block/vdi.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
author
#7 lore raw

PATCH v2 6/8 vhdx: Support .bdrv_co_create

In reply to Kevin Wolf

This adds the .bdrv_co_create driver callback to vhdx, which enables image creation over QMP.

---
 qapi/block-core.json |  40 +++++++++-
 block/vhdx.c         | 216 ++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 203 insertions(+), 53 deletions(-)
qapi/block-core.json +39 -1
index d091817855..350094f46a 100644
@@ -3842,6 +3842,44 @@
             '*static':          'bool' } }
 
 ##
+# @BlockdevVhdxSubformat:
+#
+# @dynamic: Growing image file
+# @fixed:   Preallocated fixed-size image file
+#
+# Since: 2.12
+##
+{ 'enum': 'BlockdevVhdxSubformat',
+  'data': [ 'dynamic', 'fixed' ] }
+
+##
+# @BlockdevCreateOptionsVhdx:
+#
+# Driver specific image creation options for vhdx.
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @log-size         Log size in bytes, must be a multiple of 1 MB
+#                   (default: 1 MB)
+# @block-size       Block size in bytes, must be a multiple of 1 MB and not
+#                   larger than 256 MB (default: automatically choose a block
+#                   size depending on the image size)
+# @subformat        vhdx subformat (default: dynamic)
+# @block-state-zero Force use of payload blocks of type 'ZERO'. Non-standard,
+#                   but default.  Do not set to 'off' when using 'qemu-img
+#                   convert' with subformat=dynamic.
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsVhdx',
+  'data': { 'file':                 'BlockdevRef',
+            'size':                 'size',
+            '*log-size':            'size',
+            '*block-size':          'size',
+            '*subformat':           'BlockdevVhdxSubformat',
+            '*block-state-zero':    'bool' } }
+
+##
 # @BlockdevCreateNotSupported:
 #
 # This is used for all drivers that don't support creating images.
@@ -3896,7 +3934,7 @@
       'ssh':            'BlockdevCreateOptionsSsh',
       'throttle':       'BlockdevCreateNotSupported',
       'vdi':            'BlockdevCreateOptionsVdi',
-      'vhdx':           'BlockdevCreateNotSupported',
+      'vhdx':           'BlockdevCreateOptionsVhdx',
       'vmdk':           'BlockdevCreateNotSupported',
       'vpc':            'BlockdevCreateNotSupported',
       'vvfat':          'BlockdevCreateNotSupported',
block/vhdx.c +164 -52

283 lines not on this page · raw message

Signature · 1 line
2.13.6
Reviewed-by on v2 6/8
#8 lore raw

Re: [Qemu-devel] [PATCH v2 6/8] vhdx: Support .bdrv_co_create

Quoted 8 lines · Kevin Wolf

This adds the .bdrv_co_create driver callback to vhdx, which enables image creation over QMP.

---
 qapi/block-core.json |  40 +++++++++-
 block/vhdx.c         | 216 ++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 203 insertions(+), 53 deletions(-)
Quoted 4 lines
block/vhdx.c +0 -0
index d82350d07c..f1b97f4b49 100644

[...]

Quoted 9 lines
block/vhdx.c +2 -2
@@ -1792,59 +1797,71 @@ exit:
  *    .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
  *   1MB
  */
-static int coroutine_fn vhdx_co_create_opts(const char *filename, QemuOpts *opts,
-                                            Error **errp)
+static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
+                                       Error **errp)
 {

[...]

block/vhdx.c exit: · line 1864

Quoted 6 lines

/* These are pretty arbitrary, and mainly designed to keep the BAT
* size reasonable to load into RAM */

block/vhdx.c +3 -1
-    if (block_size == 0) {
+    if (vhdx_opts->has_block_size) {
+        block_size = vhdx_opts->block_size;
+    } else {

Ah, good. I have to admit I was a bit worried you'd keep the special meaning of cluster_size == 0.

Max

Quoted 3 lines
         if (image_size > 32 * TiB) {
             block_size = 64 * MiB;
         } else if (image_size > (uint64_t) 100 * GiB) {
author
#9 lore raw

PATCH v2 7/8 vpc: Support .bdrv_co_create

In reply to Kevin Wolf

This adds the .bdrv_co_create driver callback to vpc, which enables image creation over QMP.

---
 qapi/block-core.json |  33 ++++++++++-
 block/vpc.c          | 152 ++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 147 insertions(+), 38 deletions(-)
qapi/block-core.json +32 -1
index 350094f46a..47ff5f8ce5 100644
@@ -3880,6 +3880,37 @@
             '*block-state-zero':    'bool' } }
 
 ##
+# @BlockdevVpcSubformat:
+#
+# @dynamic: Growing image file
+# @fixed:   Preallocated fixed-size image file
+#
+# Since: 2.12
+##
+{ 'enum': 'BlockdevVpcSubformat',
+  'data': [ 'dynamic', 'fixed' ] }
+
+##
+# @BlockdevCreateOptionsVpc:
+#
+# Driver specific image creation options for vpc (VHD).
+#
+# @file             Node to create the image format on
+# @size             Size of the virtual disk in bytes
+# @subformat        vhdx subformat (default: dynamic)
+# @force-size       Force use of the exact byte size instead of rounding to the
+#                   next size that can be represented in CHS geometry
+#                   (default: false)
+#
+# Since: 2.12
+##
+{ 'struct': 'BlockdevCreateOptionsVpc',
+  'data': { 'file':                 'BlockdevRef',
+            'size':                 'size',
+            '*subformat':           'BlockdevVpcSubformat',
+            '*force-size':          'bool' } }
+
+##
 # @BlockdevCreateNotSupported:
 #
 # This is used for all drivers that don't support creating images.
@@ -3936,7 +3967,7 @@
       'vdi':            'BlockdevCreateOptionsVdi',
       'vhdx':           'BlockdevCreateOptionsVhdx',
       'vmdk':           'BlockdevCreateNotSupported',
-      'vpc':            'BlockdevCreateNotSupported',
+      'vpc':            'BlockdevCreateOptionsVpc',
       'vvfat':          'BlockdevCreateNotSupported',
       'vxhs':           'BlockdevCreateNotSupported'
   } }
block/vpc.c +115 -37

214 lines not on this page · raw message

Signature · 1 line
2.13.6
Reviewed-by on v2 7/8
#10 lore raw

Re: [Qemu-devel] [PATCH v2 7/8] vpc: Support .bdrv_co_create

Quoted 8 lines · Kevin Wolf

This adds the .bdrv_co_create driver callback to vpc, which enables image creation over QMP.

---
 qapi/block-core.json |  33 ++++++++++-
 block/vpc.c          | 152 ++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 147 insertions(+), 38 deletions(-)
author
#11 lore raw

PATCH v2 8/8 vpc: Require aligned size in .bdrv_co_create

In reply to Kevin Wolf

Perform the rounding to match a CHS geometry only in the legacy code path in .bdrv_co_create_opts. QMP now requires that the user already passes a CHS aligned image size, unless force-size=true is given.

CHS alignment is required to make the image compatible with Virtual PC, but not for use with newer Microsoft hypervisors.

---
 block/vpc.c | 113 +++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 82 insertions(+), 31 deletions(-)
block/vpc.c +82 -31
index 8824211713..28ffa0d2f8 100644
@@ -902,6 +902,62 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
     return ret;
 }
 
+static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
+                                        uint16_t *out_cyls,
+                                        uint8_t *out_heads,
+                                        uint8_t *out_secs_per_cyl,
+                                        int64_t *out_total_sectors,
+                                        Error **errp)
+{
+    int64_t total_size = vpc_opts->size;
+    uint16_t cyls = 0;
+    uint8_t heads = 0;
+    uint8_t secs_per_cyl = 0;
+    int64_t total_sectors;
+    int i;
+
+    /*
+     * Calculate matching total_size and geometry. Increase the number of
+     * sectors requested until we get enough (or fail). This ensures that
+     * qemu-img convert doesn't truncate images, but rather rounds up.
+     *
+     * If the image size can't be represented by a spec conformant CHS geometry,
+     * we set the geometry to 65535 x 16 x 255 (CxHxS) sectors and use
+     * the image size from the VHD footer to calculate total_sectors.
+     */
+    if (vpc_opts->force_size) {
+        /* This will force the use of total_size for sector count, below */
+        cyls         = VHD_CHS_MAX_C;
+        heads        = VHD_CHS_MAX_H;
+        secs_per_cyl = VHD_CHS_MAX_S;
+    } else {
+        total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE);
+        for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
+            calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl);
+        }
+    }
+
+    if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
+        total_sectors = total_size / BDRV_SECTOR_SIZE;
+        /* Allow a maximum disk size of 2040 GiB */
+        if (total_sectors > VHD_MAX_SECTORS) {
+            error_setg(errp, "Disk size is too large, max size is 2040 GiB");
+            return -EFBIG;
+        }
+    } else {
+        total_sectors = (int64_t) cyls * heads * secs_per_cyl;
+    }
+
+    *out_total_sectors = total_sectors;
+    if (out_cyls) {
+        *out_cyls = cyls;
+        *out_heads = heads;
+        *out_secs_per_cyl = secs_per_cyl;
+    }
+
+    return 0;
+}
+
 static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
                                       Error **errp)
 {
@@ -911,7 +967,6 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
 
     uint8_t buf[1024];
     VHDFooter *footer = (VHDFooter *) buf;
-    int i;
     uint16_t cyls = 0;
     uint8_t heads = 0;
     uint8_t secs_per_cyl = 0;
@@ -953,38 +1008,22 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
     }
     blk_set_allow_write_beyond_eof(blk, true);
 
-    /*
-     * Calculate matching total_size and geometry. Increase the number of
-     * sectors requested until we get enough (or fail). This ensures that
-     * qemu-img convert doesn't truncate images, but rather rounds up.
-     *
-     * If the image size can't be represented by a spec conformant CHS geometry,
-     * we set the geometry to 65535 x 16 x 255 (CxHxS) sectors and use
-     * the image size from the VHD footer to calculate total_sectors.
-     */
-    if (vpc_opts->force_size) {
-        /* This will force the use of total_size for sector count, below */
-        cyls         = VHD_CHS_MAX_C;
-        heads        = VHD_CHS_MAX_H;
-        secs_per_cyl = VHD_CHS_MAX_S;
-    } else {
-        total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE);
-        for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
-            calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl);
-        }
+    /* Get geometry and check that it matches the image size*/
+    ret = calculate_rounded_image_size(vpc_opts, &cyls, &heads, &secs_per_cyl,
+                                       &total_sectors, errp);
+    if (ret < 0) {
+        goto out;
     }
 
-    if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
-        total_sectors = total_size / BDRV_SECTOR_SIZE;
-        /* Allow a maximum disk size of 2040 GiB */
-        if (total_sectors > VHD_MAX_SECTORS) {
-            error_setg(errp, "Disk size is too large, max size is 2040 GiB");
-            ret = -EFBIG;
-            goto out;
-        }
-    } else {
-        total_sectors = (int64_t)cyls * heads * secs_per_cyl;
-        total_size = total_sectors * BDRV_SECTOR_SIZE;
+    if (total_size != total_sectors * BDRV_SECTOR_SIZE) {
+        error_setg(errp, "The requested image size cannot be represented in "
+                         "CHS geometry");
+        error_append_hint(errp, "Try size=%llu or force-size=on (the "
+                                "latter makes the image incompatible with "
+                                "Virtual PC)",
+                          total_sectors * BDRV_SECTOR_SIZE);
+        ret = -EINVAL;
+        goto out;
     }
 
     /* Prepare the Hard Disk Footer */
@@ -1102,6 +1141,18 @@ static int coroutine_fn vpc_co_create_opts(const char *filename,
     create_options->u.vpc.size =
         ROUND_UP(create_options->u.vpc.size, BDRV_SECTOR_SIZE);
 
+    if (!create_options->u.vpc.force_size) {
+        int64_t total_sectors;
+        ret = calculate_rounded_image_size(&create_options->u.vpc, NULL, NULL,
+                                           NULL, &total_sectors, errp);
+        if (ret < 0) {
+            goto fail;
+        }
+
+        create_options->u.vpc.size = total_sectors * BDRV_SECTOR_SIZE;
+    }
+
+
     /* Create the vpc image (format layer) */
     ret = vpc_co_create(create_options, errp);
 
Signature · 1 line
2.13.6
Reviewed-by on v2 8/8
#12 lore raw

Re: [Qemu-devel] [PATCH v2 8/8] vpc: Require aligned size in .bdrv_co_create

Quoted 11 lines · Kevin Wolf

Perform the rounding to match a CHS geometry only in the legacy code path in .bdrv_co_create_opts. QMP now requires that the user already passes a CHS aligned image size, unless force-size=true is given.

CHS alignment is required to make the image compatible with Virtual PC, but not for use with newer Microsoft hypervisors.

---
 block/vpc.c | 113 +++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 82 insertions(+), 31 deletions(-)
author Applied
#13 lore raw
In reply to Kevin Wolf

Am 13.03.2018 um 15:47 hat Kevin Wolf geschrieben:

Quoted 5 lines

This series adds a .bdrv_co_create implementation to almost all format drivers that support creating images where its still missing. The only exception is VMDK because its support for extents will make the QAPI design a bit more complicated.

Quoted 8 lines

The other format driver not covered in this series are qcow2 (already merged) and luks (already posted in a separate series).

v2:
- Rebased, the vdi patch consists just of some cosmetic cleanups now
- vhdx, vpc: Don't do any silent rounding in .bdrv_co_create, error out if the passed size isn't properly aligned yet. The legacy code paths compensate for this.

Applied to the block branch.

Kevin