Re: [Qemu-block] [PATCH v3 9/9] qcow2: do encryption in threads

2019-01-18 Thread Alberto Garcia
On Tue 08 Jan 2019 06:06:55 PM CET, Vladimir Sementsov-Ogievskiy wrote:
> Do encryption/decryption in threads, like it is already done for
> compression. This improves asynchronous encrypted io.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy 

Reviewed-by: Alberto Garcia 

Berto



[Qemu-block] [PATCH v3 9/9] qcow2: do encryption in threads

2019-01-08 Thread Vladimir Sementsov-Ogievskiy
Do encryption/decryption in threads, like it is already done for
compression. This improves asynchronous encrypted io.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/qcow2.h |  8 ++
 block/qcow2-cluster.c |  7 ++---
 block/qcow2-threads.c | 65 +--
 block/qcow2.c | 22 +--
 4 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 9c2f6749ba..7e75f20373 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -257,6 +257,8 @@ typedef struct Qcow2BitmapHeaderExt {
 uint64_t bitmap_directory_offset;
 } QEMU_PACKED Qcow2BitmapHeaderExt;
 
+#define QCOW2_MAX_THREADS 4
+
 typedef struct BDRVQcow2State {
 int cluster_bits;
 int cluster_size;
@@ -701,5 +703,11 @@ qcow2_co_compress(BlockDriverState *bs, void *dest, size_t 
dest_size,
 ssize_t coroutine_fn
 qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
 const void *src, size_t src_size);
+int coroutine_fn
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len);
+int coroutine_fn
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len);
 
 #endif
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 7815772116..55dd4144de 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -467,13 +467,12 @@ static bool coroutine_fn 
do_perform_cow_encrypt(BlockDriverState *bs,
 {
 if (bytes && bs->encrypted) {
 BDRVQcow2State *s = bs->opaque;
-int64_t offset = (s->crypt_physical_offset ?
-  (cluster_offset + offset_in_cluster) :
-  (src_cluster_offset + offset_in_cluster));
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
 assert(s->crypto);
-if (qcrypto_block_encrypt(s->crypto, offset, buffer, bytes, NULL) < 0) 
{
+if (qcow2_co_encrypt(bs, cluster_offset,
+ src_cluster_offset + offset_in_cluster,
+ buffer, bytes) < 0) {
 return false;
 }
 }
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index e3066075da..0e20723a4b 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -30,8 +30,7 @@
 
 #include "qcow2.h"
 #include "block/thread-pool.h"
-
-#define QCOW2_MAX_THREADS 4
+#include "crypto.h"
 
 static int coroutine_fn
 qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg)
@@ -205,3 +204,65 @@ qcow2_co_decompress(BlockDriverState *bs, void *dest, 
size_t dest_size,
 return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
 qcow2_decompress);
 }
+
+
+/*
+ * Cryptography
+ */
+
+/*
+ * Qcow2EncDecFunc: common prototype of qcrypto_block_encrypt() and
+ * qcrypto_block_decrypt() functions.
+ */
+typedef int (*Qcow2EncDecFunc)(QCryptoBlock *block, uint64_t offset,
+   uint8_t *buf, size_t len, Error **errp);
+
+typedef struct Qcow2EncDecData {
+QCryptoBlock *block;
+uint64_t offset;
+uint8_t *buf;
+size_t len;
+
+Qcow2EncDecFunc func;
+} Qcow2EncDecData;
+
+static int qcow2_encdec_pool_func(void *opaque)
+{
+Qcow2EncDecData *data = opaque;
+
+return data->func(data->block, data->offset, data->buf, data->len, NULL);
+}
+
+static int coroutine_fn
+qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
+  uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc func)
+{
+BDRVQcow2State *s = bs->opaque;
+Qcow2EncDecData arg = {
+.block = s->crypto,
+.offset = s->crypt_physical_offset ?
+  file_cluster_offset + offset_into_cluster(s, offset) :
+  offset,
+.buf = buf,
+.len = len,
+.func = func,
+};
+
+return qcow2_co_process(bs, qcow2_encdec_pool_func, );
+}
+
+int coroutine_fn
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len)
+{
+return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+ qcrypto_block_encrypt);
+}
+
+int coroutine_fn
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len)
+{
+return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+ qcrypto_block_decrypt);
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index 76d3715350..f94e5960f2 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -296,7 +296,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, 
uint64_t start_offset,
 }
 s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",