All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Lieven <pl@kamp.de>
To: qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org, kwolf@redhat.com, lersek@redhat.com,
	den@openvz.org, mreitz@redhat.com, eblake@redhat.com,
	berrange@redhat.com, Peter Lieven <pl@kamp.de>
Subject: [Qemu-devel] [PATCH V5 03/10] block/qcow2: parse compress create options
Date: Tue, 25 Jul 2017 16:41:32 +0200	[thread overview]
Message-ID: <1500993699-19299-4-git-send-email-pl@kamp.de> (raw)
In-Reply-To: <1500993699-19299-1-git-send-email-pl@kamp.de>

this adds parsing and validation for the compress create
options. They are only validated but not yet used.

Signed-off-by: Peter Lieven <pl@kamp.de>
---
 block/qcow2.c             | 86 +++++++++++++++++++++++++++++++++++++++++++++--
 include/block/block_int.h | 39 +++++++++++----------
 2 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 90efa44..a5270a6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -31,6 +31,8 @@
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/util.h"
+#include "qapi-visit.h"
+#include "qapi/qobject-input-visitor.h"
 #include "qapi/qmp/types.h"
 #include "qapi-event.h"
 #include "trace.h"
@@ -161,6 +163,34 @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
     return ret;
 }
 
+static void
+qcow2_check_compress_settings(Qcow2Compress *compress, Error **errp)
+{
+    if (compress->format == QCOW2_COMPRESS_FORMAT_DEFLATE) {
+        if (!compress->u.deflate.has_level) {
+            compress->u.deflate.has_level = true;
+            compress->u.deflate.level = 0;
+        }
+        if (compress->u.deflate.level > 9) {
+            error_setg(errp, "Compress level %" PRIu8 " is not supported for"
+                       " format '%s'", compress->u.deflate.level,
+                       Qcow2CompressFormat_lookup[compress->format]);
+            return;
+        }
+        if (!compress->u.deflate.has_window_size) {
+            compress->u.deflate.has_window_size = true;
+            compress->u.deflate.window_size = 15;
+        }
+        if (compress->u.deflate.window_size < 8 ||
+            compress->u.deflate.window_size > 15) {
+            error_setg(errp, "Compress window size %" PRIu8 " is not supported"
+                       " for format '%s'", compress->u.deflate.window_size,
+                       Qcow2CompressFormat_lookup[compress->format]);
+            return;
+        }
+    }
+}
+
 
 /* 
  * read qcow2 extension and fill bs
@@ -2706,7 +2736,8 @@ 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, PreallocMode prealloc,
                          QemuOpts *opts, int version, int refcount_order,
-                         const char *encryptfmt, Error **errp)
+                         const char *encryptfmt, Qcow2Compress *compress,
+                         Error **errp)
 {
     QDict *options;
 
@@ -2898,6 +2929,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
     char *backing_file = NULL;
     char *backing_fmt = NULL;
     char *buf = NULL;
+    Qcow2Compress compress, *compress_ptr = NULL;
     uint64_t size = 0;
     int flags = 0;
     size_t cluster_size = DEFAULT_CLUSTER_SIZE;
@@ -2975,9 +3007,42 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
 
     refcount_order = ctz32(refcount_bits);
 
+    if (qemu_opt_get(opts, BLOCK_OPT_COMPRESS_FORMAT) ||
+        qemu_opt_get(opts, BLOCK_OPT_COMPRESS_LEVEL) ||
+        qemu_opt_get(opts, BLOCK_OPT_COMPRESS_WINDOW_SIZE)) {
+        QDict *options, *compressopts = NULL;
+        Visitor *v;
+        options = qemu_opts_to_qdict(opts, NULL);
+        qdict_extract_subqdict(options, &compressopts, "compress.");
+        v = qobject_input_visitor_new_keyval(QOBJECT(compressopts));
+        visit_start_struct(v, NULL, NULL, 0, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            ret = -EINVAL;
+            goto finish;
+        }
+        visit_type_Qcow2Compress_members(v, &compress, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            ret = -EINVAL;
+            goto finish;
+        }
+        visit_end_struct(v, NULL);
+        visit_free(v);
+        QDECREF(compressopts);
+        QDECREF(options);
+        qcow2_check_compress_settings(&compress, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            ret = -EINVAL;
+            goto finish;
+        }
+        compress_ptr = &compress;
+    }
+
     ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
                         cluster_size, prealloc, opts, version, refcount_order,
-                        encryptfmt, &local_err);
+                        encryptfmt, compress_ptr, &local_err);
     error_propagate(errp, local_err);
 
 finish:
@@ -4287,6 +4352,23 @@ static QemuOptsList qcow2_create_opts = {
             .help = "Width of a reference count entry in bits",
             .def_value_str = "16"
         },
+        {
+            .name = BLOCK_OPT_COMPRESS_FORMAT,
+            .type = QEMU_OPT_STRING,
+            .help = "Compress format used for compressed clusters (deflate)",
+        },
+        {
+            .name = BLOCK_OPT_COMPRESS_LEVEL,
+            .type = QEMU_OPT_NUMBER,
+            .help = "Compress level used for compressed clusters (0 = default,"
+                    " further valid options for deflate: 1=fastest ... 9=best)",
+        },
+        {
+            .name = BLOCK_OPT_COMPRESS_WINDOW_SIZE,
+            .type = QEMU_OPT_NUMBER,
+            .help = "Compress windows size used for compression (valid for"
+                    " deflate compression with values from 8 to 15)",
+        },
         { /* end of list */ }
     }
 };
diff --git a/include/block/block_int.h b/include/block/block_int.h
index d4f4ea7..91428d8 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -39,24 +39,27 @@
 
 #define BLOCK_FLAG_LAZY_REFCOUNTS   8
 
-#define BLOCK_OPT_SIZE              "size"
-#define BLOCK_OPT_ENCRYPT           "encryption"
-#define BLOCK_OPT_ENCRYPT_FORMAT    "encrypt.format"
-#define BLOCK_OPT_COMPAT6           "compat6"
-#define BLOCK_OPT_HWVERSION         "hwversion"
-#define BLOCK_OPT_BACKING_FILE      "backing_file"
-#define BLOCK_OPT_BACKING_FMT       "backing_fmt"
-#define BLOCK_OPT_CLUSTER_SIZE      "cluster_size"
-#define BLOCK_OPT_TABLE_SIZE        "table_size"
-#define BLOCK_OPT_PREALLOC          "preallocation"
-#define BLOCK_OPT_SUBFMT            "subformat"
-#define BLOCK_OPT_COMPAT_LEVEL      "compat"
-#define BLOCK_OPT_LAZY_REFCOUNTS    "lazy_refcounts"
-#define BLOCK_OPT_ADAPTER_TYPE      "adapter_type"
-#define BLOCK_OPT_REDUNDANCY        "redundancy"
-#define BLOCK_OPT_NOCOW             "nocow"
-#define BLOCK_OPT_OBJECT_SIZE       "object_size"
-#define BLOCK_OPT_REFCOUNT_BITS     "refcount_bits"
+#define BLOCK_OPT_SIZE                 "size"
+#define BLOCK_OPT_ENCRYPT              "encryption"
+#define BLOCK_OPT_ENCRYPT_FORMAT       "encrypt.format"
+#define BLOCK_OPT_COMPAT6              "compat6"
+#define BLOCK_OPT_HWVERSION            "hwversion"
+#define BLOCK_OPT_BACKING_FILE         "backing_file"
+#define BLOCK_OPT_BACKING_FMT          "backing_fmt"
+#define BLOCK_OPT_CLUSTER_SIZE         "cluster_size"
+#define BLOCK_OPT_TABLE_SIZE           "table_size"
+#define BLOCK_OPT_PREALLOC             "preallocation"
+#define BLOCK_OPT_SUBFMT               "subformat"
+#define BLOCK_OPT_COMPAT_LEVEL         "compat"
+#define BLOCK_OPT_LAZY_REFCOUNTS       "lazy_refcounts"
+#define BLOCK_OPT_ADAPTER_TYPE         "adapter_type"
+#define BLOCK_OPT_REDUNDANCY           "redundancy"
+#define BLOCK_OPT_NOCOW                "nocow"
+#define BLOCK_OPT_OBJECT_SIZE          "object_size"
+#define BLOCK_OPT_REFCOUNT_BITS        "refcount_bits"
+#define BLOCK_OPT_COMPRESS_FORMAT      "compress.format"
+#define BLOCK_OPT_COMPRESS_LEVEL       "compress.level"
+#define BLOCK_OPT_COMPRESS_WINDOW_SIZE "compress.window-size"
 
 #define BLOCK_PROBE_BUF_SIZE        512
 
-- 
1.9.1

  parent reply	other threads:[~2017-07-25 14:41 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-25 14:41 [Qemu-devel] [PATCH V5 00/10] add Qcow2 compress format extension Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 01/10] specs/qcow2: add " Peter Lieven
2017-07-25 15:03   ` Eric Blake
2017-07-25 20:29     ` Peter Lieven
2017-07-25 21:01       ` Eric Blake
2017-09-11 14:22   ` Kevin Wolf
2017-09-18 10:09     ` Peter Lieven
2017-09-18 10:50       ` Kevin Wolf
2017-12-13 16:43         ` Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 02/10] qapi/block-core: add Qcow2Compress parameters Peter Lieven
2017-07-25 21:21   ` Eric Blake
2017-07-25 14:41 ` Peter Lieven [this message]
2017-07-25 21:26   ` [Qemu-devel] [PATCH V5 03/10] block/qcow2: parse compress create options Eric Blake
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 04/10] qemu-img: add documentation for compress settings Peter Lieven
2017-07-25 21:34   ` Eric Blake
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 05/10] block/qcow2: read and write the compress format extension Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 06/10] block/qcow2: simplify ret usage in qcow2_create Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 07/10] block/qcow2: optimize qcow2_co_pwritev_compressed Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 08/10] block/qcow2: start using the compress format extension Peter Lieven
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 09/10] block/qcow2: add lzo compress format Peter Lieven
2017-07-25 21:41   ` Eric Blake
2017-07-25 14:41 ` [Qemu-devel] [PATCH V5 10/10] block/qcow2: add compress info to image specific info Peter Lieven
2017-07-25 21:55   ` Eric Blake
2017-07-26  9:05     ` Peter Lieven
2017-08-03 18:59     ` Peter Lieven
2017-09-11 14:08     ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1500993699-19299-4-git-send-email-pl@kamp.de \
    --to=pl@kamp.de \
    --cc=berrange@redhat.com \
    --cc=den@openvz.org \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lersek@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.