diff mbox

[07/27] qcow2: Handle full/falloc preallocation in qcow2_create2()

Message ID 20180208192328.16550-8-kwolf@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kevin Wolf Feb. 8, 2018, 7:23 p.m. UTC
Once qcow2_create2() can be called directly on an already existing node,
we must provide the 'full' and 'falloc' preallocation modes outside of
creating the image on the protocol layer. Fortunately, we have
preallocated truncate now which can provide this functionality.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 block/qcow2.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

Comments

Max Reitz Feb. 9, 2018, 6:04 p.m. UTC | #1
On 2018-02-08 20:23, Kevin Wolf wrote:
> Once qcow2_create2() can be called directly on an already existing node,
> we must provide the 'full' and 'falloc' preallocation modes outside of
> creating the image on the protocol layer. Fortunately, we have
> preallocated truncate now which can provide this functionality.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> ---
>  block/qcow2.c | 28 +++++++++++++++++++---------
>  1 file changed, 19 insertions(+), 9 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>
Max Reitz Feb. 12, 2018, 2:19 p.m. UTC | #2
On 2018-02-08 20:23, Kevin Wolf wrote:
> Once qcow2_create2() can be called directly on an already existing node,
> we must provide the 'full' and 'falloc' preallocation modes outside of
> creating the image on the protocol layer. Fortunately, we have
> preallocated truncate now which can provide this functionality.

When reviewing the gluster patch, I noticed that this will break
full/falloc preallocation on anything but the file protocol because
nothing else yet supports preallocated truncate...

Max

> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> ---
>  block/qcow2.c | 28 +++++++++++++++++++---------
>  1 file changed, 19 insertions(+), 9 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 3f08cff1fa..0316335614 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -2845,6 +2845,25 @@ static int qcow2_create2(BlockdevCreateOptions *create_options, Error **errp)
>      }
>      blk_set_allow_write_beyond_eof(blk, true);
>  
> +    /* Clear the protocol layer and preallocate it if necessary */
> +    ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
> +    if (ret < 0) {
> +        goto out;
> +    }
> +
> +    if (qcow2_opts->preallocation == PREALLOC_MODE_FULL ||
> +        qcow2_opts->preallocation == PREALLOC_MODE_FALLOC)
> +    {
> +        int64_t prealloc_size =
> +            qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size,
> +                                     refcount_order);
> +
> +        ret = blk_truncate(blk, prealloc_size, qcow2_opts->preallocation, errp);
> +        if (ret < 0) {
> +            goto out;
> +        }
> +    }
> +
>      /* Write the header */
>      QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
>      header = g_malloc0(cluster_size);
> @@ -3081,15 +3100,6 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
>  
>  
>      /* Create and open the file (protocol layer) */
> -    if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
> -        int refcount_order = ctz32(refcount_bits);
> -        int64_t prealloc_size =
> -            qcow2_calc_prealloc_size(size, cluster_size, refcount_order);
> -        qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort);
> -        qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc),
> -                     &error_abort);
> -    }
> -
>      ret = bdrv_create_file(filename, opts, errp);
>      if (ret < 0) {
>          goto finish;
>
diff mbox

Patch

diff --git a/block/qcow2.c b/block/qcow2.c
index 3f08cff1fa..0316335614 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2845,6 +2845,25 @@  static int qcow2_create2(BlockdevCreateOptions *create_options, Error **errp)
     }
     blk_set_allow_write_beyond_eof(blk, true);
 
+    /* Clear the protocol layer and preallocate it if necessary */
+    ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
+    if (ret < 0) {
+        goto out;
+    }
+
+    if (qcow2_opts->preallocation == PREALLOC_MODE_FULL ||
+        qcow2_opts->preallocation == PREALLOC_MODE_FALLOC)
+    {
+        int64_t prealloc_size =
+            qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size,
+                                     refcount_order);
+
+        ret = blk_truncate(blk, prealloc_size, qcow2_opts->preallocation, errp);
+        if (ret < 0) {
+            goto out;
+        }
+    }
+
     /* Write the header */
     QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
     header = g_malloc0(cluster_size);
@@ -3081,15 +3100,6 @@  static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
 
 
     /* Create and open the file (protocol layer) */
-    if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
-        int refcount_order = ctz32(refcount_bits);
-        int64_t prealloc_size =
-            qcow2_calc_prealloc_size(size, cluster_size, refcount_order);
-        qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort);
-        qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc),
-                     &error_abort);
-    }
-
     ret = bdrv_create_file(filename, opts, errp);
     if (ret < 0) {
         goto finish;