All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-02-05  9:08 Denis Plotnikov
  2019-04-28 22:32   ` Max Reitz
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Denis Plotnikov @ 2019-02-05  9:08 UTC (permalink / raw)
  To: kwolf, mreitz; +Cc: qemu-block, qemu-devel, den, eblake

The patch adds some preparation parts for incompatible compression type
feature into QCOW2 header that indicates that *all* compressed clusters
must be (de)compressed using a certain compression type.

It is implied that the compression type is set on the image creation and
can be changed only later by image convertion, thus the only compression
algorithm is used for the image.

The plan is to add support for ZSTD and then may be something more effective
in the future.

ZSDT compression algorithm consumes 3-5 times less CPU power with a
comparable comression ratio with zlib. It would be wise to use it for
data compression f.e. for backups.

The default compression is ZLIB.

Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
---
 block/qcow2.c | 25 +++++++++++++++++++++++++
 block/qcow2.h | 26 ++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 8c91b92865..cb3d6cc1c0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -73,6 +73,7 @@ typedef struct {
 #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
 #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
 #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
+#define  QCOW2_EXT_MAGIC_COMPRESSION_TYPE 0x434D5052
 
 static int coroutine_fn
 qcow2_co_preadv_compressed(BlockDriverState *bs,
@@ -397,6 +398,9 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
 #endif
             break;
 
+        case QCOW2_EXT_MAGIC_COMPRESSION_TYPE:
+            /* Setting compression type to BDRVQcow2State->compression_type */
+            /* from the image header is going to be here */
         default:
             /* unknown magic - save it in case we need to rewrite the header */
             /* If you add a new feature, make sure to also update the fast
@@ -2431,6 +2435,11 @@ int qcow2_update_header(BlockDriverState *bs)
                 .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
                 .name = "lazy refcounts",
             },
+            {
+                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+                .bit  = QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
+                .name = "compression type",
+            },
         };
 
         ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
@@ -2461,6 +2470,22 @@ int qcow2_update_header(BlockDriverState *bs)
         buflen -= ret;
     }
 
+    /* Compression type extension */
+    if (s->compression_type != 0) {
+        Qcow2CompressionTypeExt comp_header = {
+            .compression_type = cpu_to_be32(s->compression_type),
+        };
+        ret = header_ext_add(buf, QCOW2_EXT_MAGIC_COMPRESSION_TYPE,
+                             &comp_header,
+                             cpu_to_be64(sizeof(comp_header)),
+                             buflen);
+        if (ret < 0) {
+            goto fail;
+        }
+        buf += ret;
+        buflen -= ret;
+    }
+
     /* Keep unknown header extensions */
     QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
         ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);
diff --git a/block/qcow2.h b/block/qcow2.h
index 32cce9eee2..fdde5bbefd 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -112,6 +112,10 @@
 #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
 #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
 
+/* Compression types */
+#define QCOW2_COMPRESSION_TYPE_ZLIB    0
+#define QCOW2_COMPRESSION_TYPE_ZSTD    1
+
 typedef struct QCowHeader {
     uint32_t magic;
     uint32_t version;
@@ -197,10 +201,13 @@ enum {
 
 /* Incompatible feature bits */
 enum {
-    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
-    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
-    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
-    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
+    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
+    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
+    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
+    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
+    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
+    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
+                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
 
     QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
                                  | QCOW2_INCOMPAT_CORRUPT,
@@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
     uint64_t bitmap_directory_offset;
 } QEMU_PACKED Qcow2BitmapHeaderExt;
 
+typedef struct Qcow2CompressionTypeExt {
+    uint32_t compression_type;
+} QEMU_PACKED Qcow2CompressionTypeExt;
+
 typedef struct BDRVQcow2State {
     int cluster_bits;
     int cluster_size;
@@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
 
     CoQueue compress_wait_queue;
     int nb_compress_threads;
+    /**
+     * Compression type used for the image. Default: 0 - ZLIB
+     * The image compression type is set on image creation.
+     * The only way to change the compression type is to convert the image
+     * with the desired compresion type set
+     */
+    uint32_t compression_type;
 } BDRVQcow2State;
 
 typedef struct Qcow2COWRegion {
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-28 22:32   ` Max Reitz
  0 siblings, 0 replies; 10+ messages in thread
From: Max Reitz @ 2019-04-28 22:32 UTC (permalink / raw)
  To: Denis Plotnikov, kwolf; +Cc: qemu-block, qemu-devel, den, eblake

[-- Attachment #1: Type: text/plain, Size: 3616 bytes --]

On 05.02.19 10:08, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression
> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a
> comparable comression ratio with zlib. It would be wise to use it for
> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)

Are there plans to pursue this further?

[...]

> diff --git a/block/qcow2.h b/block/qcow2.h
> index 32cce9eee2..fdde5bbefd 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -112,6 +112,10 @@
>  #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>  #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>  
> +/* Compression types */
> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1

We probably want QAPI types anyway (qemu-img info should report the
compression type), so I think we could use them instead.

>  typedef struct QCowHeader {
>      uint32_t magic;
>      uint32_t version;
> @@ -197,10 +201,13 @@ enum {
>  
>  /* Incompatible feature bits */
>  enum {
> -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
> -    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
> -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> -    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
> +    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
> +    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> +    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
> +                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
>  
>      QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
>                                   | QCOW2_INCOMPAT_CORRUPT,

This mask needs to be expanded by QCOW2_INCOMPAT_COMPRESSION_TYPE.

> @@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
>      uint64_t bitmap_directory_offset;
>  } QEMU_PACKED Qcow2BitmapHeaderExt;
>  
> +typedef struct Qcow2CompressionTypeExt {
> +    uint32_t compression_type;
> +} QEMU_PACKED Qcow2CompressionTypeExt;
> +
>  typedef struct BDRVQcow2State {
>      int cluster_bits;
>      int cluster_size;
> @@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
>  
>      CoQueue compress_wait_queue;
>      int nb_compress_threads;
> +    /**
> +     * Compression type used for the image. Default: 0 - ZLIB
> +     * The image compression type is set on image creation.
> +     * The only way to change the compression type is to convert the image
> +     * with the desired compresion type set

*compression

And, well, ideally qemu-img amend could perform this operation, too.

Max

> +     */
> +    uint32_t compression_type;
>  } BDRVQcow2State;
>  
>  typedef struct Qcow2COWRegion {
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-28 22:32   ` Max Reitz
  0 siblings, 0 replies; 10+ messages in thread
From: Max Reitz @ 2019-04-28 22:32 UTC (permalink / raw)
  To: Denis Plotnikov, kwolf; +Cc: qemu-devel, qemu-block, den

[-- Attachment #1: Type: text/plain, Size: 3616 bytes --]

On 05.02.19 10:08, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression
> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a
> comparable comression ratio with zlib. It would be wise to use it for
> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)

Are there plans to pursue this further?

[...]

> diff --git a/block/qcow2.h b/block/qcow2.h
> index 32cce9eee2..fdde5bbefd 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -112,6 +112,10 @@
>  #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>  #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>  
> +/* Compression types */
> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1

We probably want QAPI types anyway (qemu-img info should report the
compression type), so I think we could use them instead.

>  typedef struct QCowHeader {
>      uint32_t magic;
>      uint32_t version;
> @@ -197,10 +201,13 @@ enum {
>  
>  /* Incompatible feature bits */
>  enum {
> -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
> -    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
> -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> -    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
> +    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
> +    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> +    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
> +                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
>  
>      QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
>                                   | QCOW2_INCOMPAT_CORRUPT,

This mask needs to be expanded by QCOW2_INCOMPAT_COMPRESSION_TYPE.

> @@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
>      uint64_t bitmap_directory_offset;
>  } QEMU_PACKED Qcow2BitmapHeaderExt;
>  
> +typedef struct Qcow2CompressionTypeExt {
> +    uint32_t compression_type;
> +} QEMU_PACKED Qcow2CompressionTypeExt;
> +
>  typedef struct BDRVQcow2State {
>      int cluster_bits;
>      int cluster_size;
> @@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
>  
>      CoQueue compress_wait_queue;
>      int nb_compress_threads;
> +    /**
> +     * Compression type used for the image. Default: 0 - ZLIB
> +     * The image compression type is set on image creation.
> +     * The only way to change the compression type is to convert the image
> +     * with the desired compresion type set

*compression

And, well, ideally qemu-img amend could perform this operation, too.

Max

> +     */
> +    uint32_t compression_type;
>  } BDRVQcow2State;
>  
>  typedef struct Qcow2COWRegion {
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-30  9:58   ` Stefano Garzarella
  0 siblings, 0 replies; 10+ messages in thread
From: Stefano Garzarella @ 2019-04-30  9:58 UTC (permalink / raw)
  To: Denis Plotnikov; +Cc: kwolf, mreitz, qemu-devel, qemu-block, den

Hi Denis,
few simple comments below regarding the CODING_STYLE (point 7. Comment style)

On Tue, Feb 05, 2019 at 12:08:25PM +0300, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression
> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a
> comparable comression ratio with zlib. It would be wise to use it for
> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 8c91b92865..cb3d6cc1c0 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -73,6 +73,7 @@ typedef struct {
>  #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
>  #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
>  #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
> +#define  QCOW2_EXT_MAGIC_COMPRESSION_TYPE 0x434D5052
>  
>  static int coroutine_fn
>  qcow2_co_preadv_compressed(BlockDriverState *bs,
> @@ -397,6 +398,9 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
>  #endif
>              break;
>  
> +        case QCOW2_EXT_MAGIC_COMPRESSION_TYPE:
> +            /* Setting compression type to BDRVQcow2State->compression_type */
> +            /* from the image header is going to be here */

I'd use a multiline comment block here.

>          default:
>              /* unknown magic - save it in case we need to rewrite the header */
>              /* If you add a new feature, make sure to also update the fast
> @@ -2431,6 +2435,11 @@ int qcow2_update_header(BlockDriverState *bs)
>                  .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
>                  .name = "lazy refcounts",
>              },
> +            {
> +                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
> +                .bit  = QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
> +                .name = "compression type",
> +            },
>          };
>  
>          ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
> @@ -2461,6 +2470,22 @@ int qcow2_update_header(BlockDriverState *bs)
>          buflen -= ret;
>      }
>  
> +    /* Compression type extension */
> +    if (s->compression_type != 0) {
> +        Qcow2CompressionTypeExt comp_header = {
> +            .compression_type = cpu_to_be32(s->compression_type),
> +        };
> +        ret = header_ext_add(buf, QCOW2_EXT_MAGIC_COMPRESSION_TYPE,
> +                             &comp_header,
> +                             cpu_to_be64(sizeof(comp_header)),
> +                             buflen);
> +        if (ret < 0) {
> +            goto fail;
> +        }
> +        buf += ret;
> +        buflen -= ret;
> +    }
> +
>      /* Keep unknown header extensions */
>      QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
>          ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);
> diff --git a/block/qcow2.h b/block/qcow2.h
> index 32cce9eee2..fdde5bbefd 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -112,6 +112,10 @@
>  #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>  #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>  
> +/* Compression types */
> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1
> +
>  typedef struct QCowHeader {
>      uint32_t magic;
>      uint32_t version;
> @@ -197,10 +201,13 @@ enum {
>  
>  /* Incompatible feature bits */
>  enum {
> -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
> -    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
> -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> -    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
> +    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
> +    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> +    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
> +                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
>  
>      QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
>                                   | QCOW2_INCOMPAT_CORRUPT,
> @@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
>      uint64_t bitmap_directory_offset;
>  } QEMU_PACKED Qcow2BitmapHeaderExt;
>  
> +typedef struct Qcow2CompressionTypeExt {
> +    uint32_t compression_type;
> +} QEMU_PACKED Qcow2CompressionTypeExt;
> +
>  typedef struct BDRVQcow2State {
>      int cluster_bits;
>      int cluster_size;
> @@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
>  
>      CoQueue compress_wait_queue;
>      int nb_compress_threads;
> +    /**

I'd remove the second asterisk here.

> +     * Compression type used for the image. Default: 0 - ZLIB
> +     * The image compression type is set on image creation.
> +     * The only way to change the compression type is to convert the image
> +     * with the desired compresion type set
> +     */
> +    uint32_t compression_type;
>  } BDRVQcow2State;
>  
>  typedef struct Qcow2COWRegion {
> -- 
> 2.17.0
> 
> 

Thanks,
Stefano

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-30  9:58   ` Stefano Garzarella
  0 siblings, 0 replies; 10+ messages in thread
From: Stefano Garzarella @ 2019-04-30  9:58 UTC (permalink / raw)
  To: Denis Plotnikov; +Cc: kwolf, den, qemu-devel, qemu-block, mreitz

Hi Denis,
few simple comments below regarding the CODING_STYLE (point 7. Comment style)

On Tue, Feb 05, 2019 at 12:08:25PM +0300, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression
> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a
> comparable comression ratio with zlib. It would be wise to use it for
> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 8c91b92865..cb3d6cc1c0 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -73,6 +73,7 @@ typedef struct {
>  #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
>  #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
>  #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
> +#define  QCOW2_EXT_MAGIC_COMPRESSION_TYPE 0x434D5052
>  
>  static int coroutine_fn
>  qcow2_co_preadv_compressed(BlockDriverState *bs,
> @@ -397,6 +398,9 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
>  #endif
>              break;
>  
> +        case QCOW2_EXT_MAGIC_COMPRESSION_TYPE:
> +            /* Setting compression type to BDRVQcow2State->compression_type */
> +            /* from the image header is going to be here */

I'd use a multiline comment block here.

>          default:
>              /* unknown magic - save it in case we need to rewrite the header */
>              /* If you add a new feature, make sure to also update the fast
> @@ -2431,6 +2435,11 @@ int qcow2_update_header(BlockDriverState *bs)
>                  .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
>                  .name = "lazy refcounts",
>              },
> +            {
> +                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
> +                .bit  = QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
> +                .name = "compression type",
> +            },
>          };
>  
>          ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
> @@ -2461,6 +2470,22 @@ int qcow2_update_header(BlockDriverState *bs)
>          buflen -= ret;
>      }
>  
> +    /* Compression type extension */
> +    if (s->compression_type != 0) {
> +        Qcow2CompressionTypeExt comp_header = {
> +            .compression_type = cpu_to_be32(s->compression_type),
> +        };
> +        ret = header_ext_add(buf, QCOW2_EXT_MAGIC_COMPRESSION_TYPE,
> +                             &comp_header,
> +                             cpu_to_be64(sizeof(comp_header)),
> +                             buflen);
> +        if (ret < 0) {
> +            goto fail;
> +        }
> +        buf += ret;
> +        buflen -= ret;
> +    }
> +
>      /* Keep unknown header extensions */
>      QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
>          ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);
> diff --git a/block/qcow2.h b/block/qcow2.h
> index 32cce9eee2..fdde5bbefd 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -112,6 +112,10 @@
>  #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>  #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>  
> +/* Compression types */
> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1
> +
>  typedef struct QCowHeader {
>      uint32_t magic;
>      uint32_t version;
> @@ -197,10 +201,13 @@ enum {
>  
>  /* Incompatible feature bits */
>  enum {
> -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
> -    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
> -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> -    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
> +    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
> +    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
> +    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
> +    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
> +                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
>  
>      QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
>                                   | QCOW2_INCOMPAT_CORRUPT,
> @@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
>      uint64_t bitmap_directory_offset;
>  } QEMU_PACKED Qcow2BitmapHeaderExt;
>  
> +typedef struct Qcow2CompressionTypeExt {
> +    uint32_t compression_type;
> +} QEMU_PACKED Qcow2CompressionTypeExt;
> +
>  typedef struct BDRVQcow2State {
>      int cluster_bits;
>      int cluster_size;
> @@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
>  
>      CoQueue compress_wait_queue;
>      int nb_compress_threads;
> +    /**

I'd remove the second asterisk here.

> +     * Compression type used for the image. Default: 0 - ZLIB
> +     * The image compression type is set on image creation.
> +     * The only way to change the compression type is to convert the image
> +     * with the desired compresion type set
> +     */
> +    uint32_t compression_type;
>  } BDRVQcow2State;
>  
>  typedef struct Qcow2COWRegion {
> -- 
> 2.17.0
> 
> 

Thanks,
Stefano


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-30 14:56   ` Eric Blake
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Blake @ 2019-04-30 14:56 UTC (permalink / raw)
  To: Denis Plotnikov, kwolf, mreitz; +Cc: qemu-block, qemu-devel, den

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On 2/5/19 3:08 AM, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression

s/convertion/conversion/

> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a

s/ZSDT/ZSTD/

> comparable comression ratio with zlib. It would be wise to use it for

s/comression/compression/

> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 8c91b92865..cb3d6cc1c0 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -73,6 +73,7 @@ typedef struct {
>  #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
>  #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
>  #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
> +#define  QCOW2_EXT_MAGIC_COMPRESSION_TYPE 0x434D5052

This appears to be adding a new header extension magic number, but
didn't actually modify the specification. I'd expect this patch to touch
docs/interop/qcow2.txt before it can be considered complete.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
@ 2019-04-30 14:56   ` Eric Blake
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Blake @ 2019-04-30 14:56 UTC (permalink / raw)
  To: Denis Plotnikov, kwolf, mreitz; +Cc: qemu-devel, qemu-block, den

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On 2/5/19 3:08 AM, Denis Plotnikov wrote:
> The patch adds some preparation parts for incompatible compression type
> feature into QCOW2 header that indicates that *all* compressed clusters
> must be (de)compressed using a certain compression type.
> 
> It is implied that the compression type is set on the image creation and
> can be changed only later by image convertion, thus the only compression

s/convertion/conversion/

> algorithm is used for the image.
> 
> The plan is to add support for ZSTD and then may be something more effective
> in the future.
> 
> ZSDT compression algorithm consumes 3-5 times less CPU power with a

s/ZSDT/ZSTD/

> comparable comression ratio with zlib. It would be wise to use it for

s/comression/compression/

> data compression f.e. for backups.
> 
> The default compression is ZLIB.
> 
> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
> ---
>  block/qcow2.c | 25 +++++++++++++++++++++++++
>  block/qcow2.h | 26 ++++++++++++++++++++++----
>  2 files changed, 47 insertions(+), 4 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 8c91b92865..cb3d6cc1c0 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -73,6 +73,7 @@ typedef struct {
>  #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
>  #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
>  #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
> +#define  QCOW2_EXT_MAGIC_COMPRESSION_TYPE 0x434D5052

This appears to be adding a new header extension magic number, but
didn't actually modify the specification. I'd expect this patch to touch
docs/interop/qcow2.txt before it can be considered complete.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
  2019-04-28 22:32   ` Max Reitz
  (?)
@ 2019-05-16  7:50   ` Denis Plotnikov
  2019-05-16 10:40     ` Max Reitz
  -1 siblings, 1 reply; 10+ messages in thread
From: Denis Plotnikov @ 2019-05-16  7:50 UTC (permalink / raw)
  To: Max Reitz, kwolf; +Cc: qemu-devel, qemu-block, Denis Lunev



On 29.04.2019 1:32, Max Reitz wrote:
> On 05.02.19 10:08, Denis Plotnikov wrote:
>> The patch adds some preparation parts for incompatible compression type
>> feature into QCOW2 header that indicates that *all* compressed clusters
>> must be (de)compressed using a certain compression type.
>>
>> It is implied that the compression type is set on the image creation and
>> can be changed only later by image convertion, thus the only compression
>> algorithm is used for the image.
>>
>> The plan is to add support for ZSTD and then may be something more effective
>> in the future.
>>
>> ZSDT compression algorithm consumes 3-5 times less CPU power with a
>> comparable comression ratio with zlib. It would be wise to use it for
>> data compression f.e. for backups.
>>
>> The default compression is ZLIB.
>>
>> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
>> ---
>>   block/qcow2.c | 25 +++++++++++++++++++++++++
>>   block/qcow2.h | 26 ++++++++++++++++++++++----
>>   2 files changed, 47 insertions(+), 4 deletions(-)
> 
> Are there plans to pursue this further?
Yes, I'm going to come up with the first version in a few weeks
> 
> [...]
> 
>> diff --git a/block/qcow2.h b/block/qcow2.h
>> index 32cce9eee2..fdde5bbefd 100644
>> --- a/block/qcow2.h
>> +++ b/block/qcow2.h
>> @@ -112,6 +112,10 @@
>>   #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>>   #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>>   
>> +/* Compression types */
>> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
>> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1
> 
> We probably want QAPI types anyway (qemu-img info should report the
> compression type), so I think we could use them instead.
I'm not sure that I understood the idea. Could you please explain what 
is meant here? We don't need those constants and should use the 
constants defined somewhere else (where)?

Denis


> 
>>   typedef struct QCowHeader {
>>       uint32_t magic;
>>       uint32_t version;
>> @@ -197,10 +201,13 @@ enum {
>>   
>>   /* Incompatible feature bits */
>>   enum {
>> -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
>> -    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
>> -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
>> -    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
>> +    QCOW2_INCOMPAT_DIRTY_BITNR            = 0,
>> +    QCOW2_INCOMPAT_CORRUPT_BITNR          = 1,
>> +    QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR = 2,
>> +    QCOW2_INCOMPAT_DIRTY                  = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
>> +    QCOW2_INCOMPAT_CORRUPT                = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
>> +    QCOW2_INCOMPAT_COMPRESSION_TYPE       =
>> +                                    1 << QCOW2_INCOMPAT_COMPRESSION_TYPE_BITNR,
>>   
>>       QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
>>                                    | QCOW2_INCOMPAT_CORRUPT,
> 
> This mask needs to be expanded by QCOW2_INCOMPAT_COMPRESSION_TYPE.
> 
>> @@ -256,6 +263,10 @@ typedef struct Qcow2BitmapHeaderExt {
>>       uint64_t bitmap_directory_offset;
>>   } QEMU_PACKED Qcow2BitmapHeaderExt;
>>   
>> +typedef struct Qcow2CompressionTypeExt {
>> +    uint32_t compression_type;
>> +} QEMU_PACKED Qcow2CompressionTypeExt;
>> +
>>   typedef struct BDRVQcow2State {
>>       int cluster_bits;
>>       int cluster_size;
>> @@ -340,6 +351,13 @@ typedef struct BDRVQcow2State {
>>   
>>       CoQueue compress_wait_queue;
>>       int nb_compress_threads;
>> +    /**
>> +     * Compression type used for the image. Default: 0 - ZLIB
>> +     * The image compression type is set on image creation.
>> +     * The only way to change the compression type is to convert the image
>> +     * with the desired compresion type set
> 
> *compression
> 
> And, well, ideally qemu-img amend could perform this operation, too.
> 
> Max
> 
>> +     */
>> +    uint32_t compression_type;
>>   } BDRVQcow2State;
>>   
>>   typedef struct Qcow2COWRegion {
>>
> 
> 

-- 
Best,
Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
  2019-05-16  7:50   ` Denis Plotnikov
@ 2019-05-16 10:40     ` Max Reitz
  2019-05-16 10:56       ` Denis Plotnikov
  0 siblings, 1 reply; 10+ messages in thread
From: Max Reitz @ 2019-05-16 10:40 UTC (permalink / raw)
  To: Denis Plotnikov, kwolf; +Cc: qemu-devel, qemu-block, Denis Lunev

[-- Attachment #1: Type: text/plain, Size: 2490 bytes --]

On 16.05.19 09:50, Denis Plotnikov wrote:
> 
> 
> On 29.04.2019 1:32, Max Reitz wrote:
>> On 05.02.19 10:08, Denis Plotnikov wrote:
>>> The patch adds some preparation parts for incompatible compression type
>>> feature into QCOW2 header that indicates that *all* compressed clusters
>>> must be (de)compressed using a certain compression type.
>>>
>>> It is implied that the compression type is set on the image creation and
>>> can be changed only later by image convertion, thus the only compression
>>> algorithm is used for the image.
>>>
>>> The plan is to add support for ZSTD and then may be something more effective
>>> in the future.
>>>
>>> ZSDT compression algorithm consumes 3-5 times less CPU power with a
>>> comparable comression ratio with zlib. It would be wise to use it for
>>> data compression f.e. for backups.
>>>
>>> The default compression is ZLIB.
>>>
>>> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
>>> ---
>>>   block/qcow2.c | 25 +++++++++++++++++++++++++
>>>   block/qcow2.h | 26 ++++++++++++++++++++++----
>>>   2 files changed, 47 insertions(+), 4 deletions(-)
>>
>> Are there plans to pursue this further?
> Yes, I'm going to come up with the first version in a few weeks

OK.

>> [...]
>>
>>> diff --git a/block/qcow2.h b/block/qcow2.h
>>> index 32cce9eee2..fdde5bbefd 100644
>>> --- a/block/qcow2.h
>>> +++ b/block/qcow2.h
>>> @@ -112,6 +112,10 @@
>>>   #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>>>   #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>>>   
>>> +/* Compression types */
>>> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
>>> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1
>>
>> We probably want QAPI types anyway (qemu-img info should report the
>> compression type), so I think we could use them instead.
> I'm not sure that I understood the idea. Could you please explain what 
> is meant here? We don't need those constants and should use the 
> constants defined somewhere else (where)?

qemu-img info can report format-specific information.  I think the
compression type should be listed there as well, once there is more than
one.

Format-specific information is a QAPI type, namely
ImageInfoSpecificQCow2.  Therefore, everything it contains needs to be a
QAPI object, and this includes potential compression information.  We
thus need a QAPI enum like Qcow2CompressionType, and that would
automatically give us these values.

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature
  2019-05-16 10:40     ` Max Reitz
@ 2019-05-16 10:56       ` Denis Plotnikov
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Plotnikov @ 2019-05-16 10:56 UTC (permalink / raw)
  To: Max Reitz, kwolf; +Cc: qemu-devel, qemu-block, Denis Lunev



On 16.05.2019 13:40, Max Reitz wrote:
> On 16.05.19 09:50, Denis Plotnikov wrote:
>>
>>
>> On 29.04.2019 1:32, Max Reitz wrote:
>>> On 05.02.19 10:08, Denis Plotnikov wrote:
>>>> The patch adds some preparation parts for incompatible compression type
>>>> feature into QCOW2 header that indicates that *all* compressed clusters
>>>> must be (de)compressed using a certain compression type.
>>>>
>>>> It is implied that the compression type is set on the image creation and
>>>> can be changed only later by image convertion, thus the only compression
>>>> algorithm is used for the image.
>>>>
>>>> The plan is to add support for ZSTD and then may be something more effective
>>>> in the future.
>>>>
>>>> ZSDT compression algorithm consumes 3-5 times less CPU power with a
>>>> comparable comression ratio with zlib. It would be wise to use it for
>>>> data compression f.e. for backups.
>>>>
>>>> The default compression is ZLIB.
>>>>
>>>> Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
>>>> ---
>>>>    block/qcow2.c | 25 +++++++++++++++++++++++++
>>>>    block/qcow2.h | 26 ++++++++++++++++++++++----
>>>>    2 files changed, 47 insertions(+), 4 deletions(-)
>>>
>>> Are there plans to pursue this further?
>> Yes, I'm going to come up with the first version in a few weeks
> 
> OK.
> 
>>> [...]
>>>
>>>> diff --git a/block/qcow2.h b/block/qcow2.h
>>>> index 32cce9eee2..fdde5bbefd 100644
>>>> --- a/block/qcow2.h
>>>> +++ b/block/qcow2.h
>>>> @@ -112,6 +112,10 @@
>>>>    #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
>>>>    #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
>>>>    
>>>> +/* Compression types */
>>>> +#define QCOW2_COMPRESSION_TYPE_ZLIB    0
>>>> +#define QCOW2_COMPRESSION_TYPE_ZSTD    1
>>>
>>> We probably want QAPI types anyway (qemu-img info should report the
>>> compression type), so I think we could use them instead.
>> I'm not sure that I understood the idea. Could you please explain what
>> is meant here? We don't need those constants and should use the
>> constants defined somewhere else (where)?
> 
> qemu-img info can report format-specific information.  I think the
> compression type should be listed there as well, once there is more than
> one.
> 
> Format-specific information is a QAPI type, namely
> ImageInfoSpecificQCow2.  Therefore, everything it contains needs to be a
> QAPI object, and this includes potential compression information.  We
> thus need a QAPI enum like Qcow2CompressionType, and that would
> automatically give us these values.

Thanks for clarification. Will do that way.

Denis
> 
> Max
> 

-- 
Best,
Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-05-16 10:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-05  9:08 [Qemu-devel] [PATCH] [RFC] qcow2: add compression type feature Denis Plotnikov
2019-04-28 22:32 ` Max Reitz
2019-04-28 22:32   ` Max Reitz
2019-05-16  7:50   ` Denis Plotnikov
2019-05-16 10:40     ` Max Reitz
2019-05-16 10:56       ` Denis Plotnikov
2019-04-30  9:58 ` Stefano Garzarella
2019-04-30  9:58   ` Stefano Garzarella
2019-04-30 14:56 ` Eric Blake
2019-04-30 14:56   ` Eric Blake

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.