From 4cdde263aa0334fa3f09ee6e6de5e9dd6ed3000d Mon Sep 17 00:00:00 2001
Message-Id: <4cdde263aa0334fa3f09ee6e6de5e9dd6ed3000d.1422637807.git.jen@redhat.com>
In-Reply-To: <d57bff8cf3457c2e855eeca4b18266bf5956270d.1422637807.git.jen@redhat.com>
References: <d57bff8cf3457c2e855eeca4b18266bf5956270d.1422637807.git.jen@redhat.com>
From: Max Reitz <mreitz@redhat.com>
Date: Mon, 19 Jan 2015 14:52:05 -0500
Subject: [CHANGE 04/10] qapi: introduce PreallocMode and new PreallocModes
 full and falloc.
To: rhvirt-patches@redhat.com,
    jen@redhat.com

RH-Author: Max Reitz <mreitz@redhat.com>
Message-id: <1421679130-22714-5-git-send-email-mreitz@redhat.com>
Patchwork-id: 63364
O-Subject: [RHEL-6.7 qemu-kvm PATCH 4/9] qapi: introduce PreallocMode and new PreallocModes full and falloc.
Bugzilla: 1040220
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>

From: Hu Tao <hutao@cn.fujitsu.com>

BZ: 1040220

This patch prepares for the subsequent patches.

Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ffeaac9b4e23a3033e8120cc34bacadc09487f1b)
Signed-off-by: Jeff E. Nelson <jen@redhat.com>

Conflicts:
	block/qcow2.c
	qapi/block-core.json
	qapi-schema.json
	tests/qemu-iotests/049.out

In block/qcow2.c, the option handling is fundamentally different from
upstream; furthermore, indentation is different (broken, but this commit
does not fix it) for the qcow2_create2() function header; then, there
are some contextual conflicts; and finally, the block layer has not yet
been converted to use Error objects for passing errors, so emitting
errors is different.

qapi/block-core.json does not exist downstream, here it is
qapi-schema.json. In addition to moving the added hunk, I fixed the
formatting of its description by adding a "##" line at the start.

The conflict in the 049 reference output results from said error
handling being different upstream and downstream.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block/qcow2.c              | 31 ++++++++++++++++++++-----------
 qapi-schema.json           | 18 ++++++++++++++++++
 tests/qemu-iotests/049.out |  2 +-
 3 files changed, 39 insertions(+), 12 deletions(-)

Signed-off-by: Jeff E. Nelson <jen@redhat.com>
---
 block/qcow2.c              | 31 ++++++++++++++++++++-----------
 qapi-schema.json           | 18 ++++++++++++++++++
 tests/qemu-iotests/049.out |  2 +-
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 1d7f3c5..7f96ba9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -29,6 +29,8 @@
 #include "block/qcow2.h"
 #include "qemu-error.h"
 #include "qerror.h"
+#include "qapi/util.h"
+#include "qapi-visit.h"
 
 /*
   Differences with QCOW:
@@ -1031,7 +1033,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
 
 static int qcow2_create2(const char *filename, int64_t total_size,
                         const char *backing_file, const char *backing_format,
-                        int flags, size_t cluster_size, int prealloc,
+                        int flags, size_t cluster_size, PreallocMode prealloc,
                         QEMUOptionParameter *options)
 {
     /* Calulate cluster_bits */
@@ -1144,7 +1146,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     }
 
     /* And if we're supposed to preallocate metadata, do that now */
-    if (prealloc) {
+    if (prealloc == PREALLOC_MODE_METADATA) {
         ret = preallocate(bs);
         if (ret < 0) {
             goto out;
@@ -1172,7 +1174,8 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
     uint64_t sectors = 0;
     int flags = 0;
     size_t cluster_size = DEFAULT_CLUSTER_SIZE;
-    int prealloc = 0;
+    PreallocMode prealloc = PREALLOC_MODE_OFF;
+    Error *local_err = NULL;
 
     /* Read out options */
     while (options && options->name) {
@@ -1189,20 +1192,26 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
                 cluster_size = options->value.n;
             }
         } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-            if (!options->value.s || !strcmp(options->value.s, "off")) {
-                prealloc = 0;
-            } else if (!strcmp(options->value.s, "metadata")) {
-                prealloc = 1;
-            } else {
-                fprintf(stderr, "Invalid preallocation mode: '%s'\n",
-                    options->value.s);
+            prealloc = qapi_enum_parse(PreallocMode_lookup,
+                                       options->value.s, PREALLOC_MODE_MAX,
+                                       PREALLOC_MODE_OFF, &local_err);
+            if (local_err) {
+                qerror_report_err(local_err);
+                error_free(local_err);
                 return -EINVAL;
             }
         }
         options++;
     }
 
-    if (backing_file && prealloc) {
+    if (prealloc != PREALLOC_MODE_OFF &&
+        prealloc != PREALLOC_MODE_METADATA) {
+        fprintf(stderr, "Unsupported preallocate mode: %s",
+                PreallocMode_lookup[prealloc]);
+        return -EINVAL;
+    }
+
+    if (backing_file && prealloc != PREALLOC_MODE_OFF) {
         fprintf(stderr, "Backing file and preallocation cannot be used at "
             "the same time\n");
         return -EINVAL;
diff --git a/qapi-schema.json b/qapi-schema.json
index 7e76a99..5ecd874 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -298,6 +298,24 @@
   'data': { 'start': 'int', 'length': 'int', 'depth': 'int', 'zero': 'bool',
             'data': 'bool', '*offset': 'int' } }
 
+##
+# @PreallocMode
+#
+# Preallocation mode of QEMU image file
+#
+# @off: no preallocation
+# @metadata: preallocate only for metadata
+# @falloc: like @full preallocation but allocate disk space by
+#          posix_fallocate() rather than writing zeros.
+# @full: preallocate all data by writing zeros to device to ensure disk
+#        space is really available. @full preallocation also sets up
+#        metadata correctly.
+#
+# Since 2.2
+##
+{ 'enum': 'PreallocMode',
+  'data': [ 'off', 'metadata', 'falloc', 'full' ] }
+
 
 ##
 # @EventInfo:
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 387cc4d..c679afb 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -164,7 +164,7 @@ qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' 
 
 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
-Invalid preallocation mode: '1234'
+invalid parameter value: 1234
 TEST_DIR/t.qcow2: error while creating qcow2: Invalid argument
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' 
 
-- 
2.1.0

