From nobody Fri Apr 11 23:12:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530630113021176.08363550700062; Tue, 3 Jul 2018 08:01:53 -0700 (PDT) Received: from localhost ([::1]:40927 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMoM-0001jj-Ny for importer@patchew.org; Tue, 03 Jul 2018 11:01:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52662) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMm7-0008UW-Aq for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faMm6-00053i-LN for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:27 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34432 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faMm1-00051h-HP; Tue, 03 Jul 2018 10:59:21 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0DE1DFCB; Tue, 3 Jul 2018 14:59:20 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id F11CF1117629; Tue, 3 Jul 2018 14:59:19 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 16:59:11 +0200 Message-Id: <20180703145915.32607-2-kwolf@redhat.com> In-Reply-To: <20180703145915.32607-1-kwolf@redhat.com> References: <20180703145915.32607-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 14:59:20 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 14:59:20 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 1/5] qemu-img: allow compressed not-in-order writes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy No reason to forbid them, and they are needed to improve performance with compress-threads in further patches. Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Kevin Wolf --- qemu-img.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index e1a506f7f6..7651d8172c 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2141,11 +2141,6 @@ static int img_convert(int argc, char **argv) goto fail_getopt; } =20 - if (!s.wr_in_order && s.compressed) { - error_report("Out of order write and compress are mutually exclusi= ve"); - goto fail_getopt; - } - if (tgt_image_opts && !skip_create) { error_report("--target-image-opts requires use of -n flag"); goto fail_getopt; --=20 2.13.6 From nobody Fri Apr 11 23:12:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530630625791493.96534874311965; Tue, 3 Jul 2018 08:10:25 -0700 (PDT) Received: from localhost ([::1]:40976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMwj-0008H6-10 for importer@patchew.org; Tue, 03 Jul 2018 11:10:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52781) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMmG-0000Gn-Fn for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faMmC-00056S-UL for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:36 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:37120 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faMm2-000522-Cl; Tue, 03 Jul 2018 10:59:22 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CC9CE87A87; Tue, 3 Jul 2018 14:59:21 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 08EDC1117629; Tue, 3 Jul 2018 14:59:20 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 16:59:12 +0200 Message-Id: <20180703145915.32607-3-kwolf@redhat.com> In-Reply-To: <20180703145915.32607-1-kwolf@redhat.com> References: <20180703145915.32607-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:21 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:21 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 2/5] qcow2: refactor data compression X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Make a separate function for compression to be parallelized later. - use .avail_out field instead of .next_out to calculate size of compressed data. It looks more natural and it allows to keep dest to be void pointer - set avail_out to be at least one byte less than input, to be sure avoid inefficient compression earlier Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Kevin Wolf --- block/qcow2.c | 76 ++++++++++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 2f9e58e0c4..67f4fb7c71 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -23,11 +23,14 @@ */ =20 #include "qemu/osdep.h" + +#define ZLIB_CONST +#include + #include "block/block_int.h" #include "block/qdict.h" #include "sysemu/block-backend.h" #include "qemu/module.h" -#include #include "qcow2.h" #include "qemu/error-report.h" #include "qapi/error.h" @@ -3650,6 +3653,46 @@ fail: return ret; } =20 +/* + * qcow2_compress() + * + * @dest - destination buffer, at least of @size-1 bytes + * @src - source buffer, @size bytes + * + * Returns: compressed size on success + * -1 if compression is inefficient + * -2 on any other error + */ +static ssize_t qcow2_compress(void *dest, const void *src, size_t size) +{ + ssize_t ret; + z_stream strm; + + /* best compression, small window, no zlib header */ + memset(&strm, 0, sizeof(strm)); + ret =3D deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, + -12, 9, Z_DEFAULT_STRATEGY); + if (ret !=3D 0) { + return -2; + } + + strm.avail_in =3D size; + strm.next_in =3D src; + strm.avail_out =3D size - 1; + strm.next_out =3D dest; + + ret =3D deflate(&strm, Z_FINISH); + if (ret =3D=3D Z_STREAM_END) { + ret =3D size - 1 - strm.avail_out; + } else { + ret =3D (ret =3D=3D Z_OK ? -1 : -2); + } + + deflateEnd(&strm); + + return ret; +} + /* XXX: put compressed sectors first, then all the cluster aligned tables to avoid losing bytes in alignment */ static coroutine_fn int @@ -3659,8 +3702,8 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uin= t64_t offset, BDRVQcow2State *s =3D bs->opaque; QEMUIOVector hd_qiov; struct iovec iov; - z_stream strm; - int ret, out_len; + int ret; + size_t out_len; uint8_t *buf, *out_buf; int64_t cluster_offset; =20 @@ -3694,32 +3737,11 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, u= int64_t offset, =20 out_buf =3D g_malloc(s->cluster_size); =20 - /* best compression, small window, no zlib header */ - memset(&strm, 0, sizeof(strm)); - ret =3D deflateInit2(&strm, Z_DEFAULT_COMPRESSION, - Z_DEFLATED, -12, - 9, Z_DEFAULT_STRATEGY); - if (ret !=3D 0) { + out_len =3D qcow2_compress(out_buf, buf, s->cluster_size); + if (out_len =3D=3D -2) { ret =3D -EINVAL; goto fail; - } - - strm.avail_in =3D s->cluster_size; - strm.next_in =3D (uint8_t *)buf; - strm.avail_out =3D s->cluster_size; - strm.next_out =3D out_buf; - - ret =3D deflate(&strm, Z_FINISH); - if (ret !=3D Z_STREAM_END && ret !=3D Z_OK) { - deflateEnd(&strm); - ret =3D -EINVAL; - goto fail; - } - out_len =3D strm.next_out - out_buf; - - deflateEnd(&strm); - - if (ret !=3D Z_STREAM_END || out_len >=3D s->cluster_size) { + } else if (out_len =3D=3D -1) { /* could not compress: write normal cluster */ ret =3D qcow2_co_pwritev(bs, offset, bytes, qiov, 0); if (ret < 0) { --=20 2.13.6 From nobody Fri Apr 11 23:12:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530630257580704.2830422887392; Tue, 3 Jul 2018 08:04:17 -0700 (PDT) Received: from localhost ([::1]:40939 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMqm-0003dg-U0 for importer@patchew.org; Tue, 03 Jul 2018 11:04:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52689) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMm8-0008Vt-Qq for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faMm7-00054A-Ha for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:28 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:37124 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faMm3-00052O-Cc; Tue, 03 Jul 2018 10:59:23 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D7D6587A87; Tue, 3 Jul 2018 14:59:22 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 144CF1117629; Tue, 3 Jul 2018 14:59:21 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 16:59:13 +0200 Message-Id: <20180703145915.32607-4-kwolf@redhat.com> In-Reply-To: <20180703145915.32607-1-kwolf@redhat.com> References: <20180703145915.32607-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:22 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:22 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 3/5] qcow2: add compress threads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Do data compression in separate threads. This significantly improve performance for qemu-img convert with -W (allow async writes) and -c (compressed) options. Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Kevin Wolf --- block/qcow2.h | 3 +++ block/qcow2.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/block/qcow2.h b/block/qcow2.h index 1c9c0d3631..d6aca687d6 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -326,6 +326,9 @@ typedef struct BDRVQcow2State { * override) */ char *image_backing_file; char *image_backing_format; + + CoQueue compress_wait_queue; + int nb_compress_threads; } BDRVQcow2State; =20 typedef struct Qcow2COWRegion { diff --git a/block/qcow2.c b/block/qcow2.c index 67f4fb7c71..327685a2f9 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -44,6 +44,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" #include "crypto.h" +#include "block/thread-pool.h" =20 /* Differences with QCOW: @@ -1544,6 +1545,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverStat= e *bs, QDict *options, qcow2_check_refcounts(bs, &result, 0); } #endif + + qemu_co_queue_init(&s->compress_wait_queue); + return ret; =20 fail: @@ -3693,6 +3697,62 @@ static ssize_t qcow2_compress(void *dest, const void= *src, size_t size) return ret; } =20 +#define MAX_COMPRESS_THREADS 4 + +typedef struct Qcow2CompressData { + void *dest; + const void *src; + size_t size; + ssize_t ret; +} Qcow2CompressData; + +static int qcow2_compress_pool_func(void *opaque) +{ + Qcow2CompressData *data =3D opaque; + + data->ret =3D qcow2_compress(data->dest, data->src, data->size); + + return 0; +} + +static void qcow2_compress_complete(void *opaque, int ret) +{ + qemu_coroutine_enter(opaque); +} + +/* See qcow2_compress definition for parameters description */ +static ssize_t qcow2_co_compress(BlockDriverState *bs, + void *dest, const void *src, size_t size) +{ + BDRVQcow2State *s =3D bs->opaque; + BlockAIOCB *acb; + ThreadPool *pool =3D aio_get_thread_pool(bdrv_get_aio_context(bs)); + Qcow2CompressData arg =3D { + .dest =3D dest, + .src =3D src, + .size =3D size, + }; + + while (s->nb_compress_threads >=3D MAX_COMPRESS_THREADS) { + qemu_co_queue_wait(&s->compress_wait_queue, NULL); + } + + s->nb_compress_threads++; + acb =3D thread_pool_submit_aio(pool, qcow2_compress_pool_func, &arg, + qcow2_compress_complete, + qemu_coroutine_self()); + + if (!acb) { + s->nb_compress_threads--; + return -EINVAL; + } + qemu_coroutine_yield(); + s->nb_compress_threads--; + qemu_co_queue_next(&s->compress_wait_queue); + + return arg.ret; +} + /* XXX: put compressed sectors first, then all the cluster aligned tables to avoid losing bytes in alignment */ static coroutine_fn int @@ -3737,7 +3797,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uin= t64_t offset, =20 out_buf =3D g_malloc(s->cluster_size); =20 - out_len =3D qcow2_compress(out_buf, buf, s->cluster_size); + out_len =3D qcow2_co_compress(bs, out_buf, buf, s->cluster_size); if (out_len =3D=3D -2) { ret =3D -EINVAL; goto fail; --=20 2.13.6 From nobody Fri Apr 11 23:12:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530630104070357.7058004808415; Tue, 3 Jul 2018 08:01:44 -0700 (PDT) Received: from localhost ([::1]:40925 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMo6-0001aP-Ki for importer@patchew.org; Tue, 03 Jul 2018 11:01:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMm7-0008V2-Mk for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faMm6-00053t-P3 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:27 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34642 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faMm4-00052n-FB; Tue, 03 Jul 2018 10:59:24 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E41A54074448; Tue, 3 Jul 2018 14:59:23 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F8AE1117629; Tue, 3 Jul 2018 14:59:22 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 16:59:14 +0200 Message-Id: <20180703145915.32607-5-kwolf@redhat.com> In-Reply-To: <20180703145915.32607-1-kwolf@redhat.com> References: <20180703145915.32607-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Tue, 03 Jul 2018 14:59:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Tue, 03 Jul 2018 14:59:23 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 4/5] block: Move two block permission constants to the relevant enum X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ari Sundholm This allows using the two constants outside of block.c, which will happen in a subsequent patch. Signed-off-by: Ari Sundholm Signed-off-by: Kevin Wolf --- include/block/block.h | 7 +++++++ block.c | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index e5c7759a0c..bc76b1e59f 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -225,6 +225,13 @@ enum { BLK_PERM_GRAPH_MOD =3D 0x10, =20 BLK_PERM_ALL =3D 0x1f, + + DEFAULT_PERM_PASSTHROUGH =3D BLK_PERM_CONSISTENT_READ + | BLK_PERM_WRITE + | BLK_PERM_WRITE_UNCHANGED + | BLK_PERM_RESIZE, + + DEFAULT_PERM_UNCHANGED =3D BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROU= GH, }; =20 char *bdrv_perm_names(uint64_t perm); diff --git a/block.c b/block.c index 70a46fdd84..961ec97d26 100644 --- a/block.c +++ b/block.c @@ -1948,12 +1948,6 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t p= erm, uint64_t shared, return 0; } =20 -#define DEFAULT_PERM_PASSTHROUGH (BLK_PERM_CONSISTENT_READ \ - | BLK_PERM_WRITE \ - | BLK_PERM_WRITE_UNCHANGED \ - | BLK_PERM_RESIZE) -#define DEFAULT_PERM_UNCHANGED (BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH) - void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, BlockReopenQueue *reopen_queue, --=20 2.13.6 From nobody Fri Apr 11 23:12:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530630447761592.6616100596415; Tue, 3 Jul 2018 08:07:27 -0700 (PDT) Received: from localhost ([::1]:40956 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMte-0005fN-4k for importer@patchew.org; Tue, 03 Jul 2018 11:07:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52745) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faMmC-0000Cz-HO for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faMmA-00055d-IB for qemu-devel@nongnu.org; Tue, 03 Jul 2018 10:59:32 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:37128 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faMm5-000538-Jn; Tue, 03 Jul 2018 10:59:25 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1BC3387A87; Tue, 3 Jul 2018 14:59:25 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B5701117629; Tue, 3 Jul 2018 14:59:24 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 16:59:15 +0200 Message-Id: <20180703145915.32607-6-kwolf@redhat.com> In-Reply-To: <20180703145915.32607-1-kwolf@redhat.com> References: <20180703145915.32607-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:25 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Tue, 03 Jul 2018 14:59:25 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 5/5] block: Add blklogwrites X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Aapo Vienamo Implements a block device write logging system, similar to Linux kernel device mapper dm-log-writes. The write operations that are performed on a block device are logged to a file or another block device. The write log format is identical to the dm-log-writes format. Currently, log markers are not supported. This functionality can be used for crash consistency and fs consistency testing. By implementing it in qemu, tests utilizing write logs can be be used to test non-Linux drivers and older kernels. The driver accepts an optional parameter to set the sector size used for logging. This makes the driver require all requests to be aligned to this sector size and also makes offsets and sizes of writes in the log metadata to be expressed in terms of this value (the log format has a granularity of one sector for offsets and sizes). This allows accurate logging of writes to guest block devices that have unusual sector sizes. The implementation is based on the blkverify and blkdebug block drivers. Signed-off-by: Aapo Vienamo Signed-off-by: Ari Sundholm Signed-off-by: Kevin Wolf --- qapi/block-core.json | 33 ++++- block/blklogwrites.c | 392 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ MAINTAINERS | 6 + block/Makefile.objs | 1 + 4 files changed, 426 insertions(+), 6 deletions(-) create mode 100644 block/blklogwrites.c diff --git a/qapi/block-core.json b/qapi/block-core.json index 90e554ed0f..a9eab8cab8 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2533,16 +2533,17 @@ # @throttle: Since 2.11 # @nvme: Since 2.12 # @copy-on-read: Since 3.0 +# @blklogwrites: Since 3.0 # # Since: 2.9 ## { 'enum': 'BlockdevDriver', - 'data': [ 'blkdebug', 'blkverify', 'bochs', 'cloop', 'copy-on-read', - 'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom', - 'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs', - 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', 'qcow2', '= qed', - 'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh', - 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] } + 'data': [ 'blkdebug', 'blklogwrites', 'blkverify', 'bochs', 'cloop', + 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster', + 'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks', + 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qco= w', + 'qcow2', 'qed', 'quorum', 'raw', 'rbd', 'replication', 'sheepd= og', + 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxh= s' ] } =20 ## # @BlockdevOptionsFile: @@ -3045,6 +3046,25 @@ '*set-state': ['BlkdebugSetStateOptions'] } } =20 ## +# @BlockdevOptionsBlklogwrites: +# +# Driver specific block device options for blklogwrites. +# +# @file: block device +# +# @log: block device used to log writes to @file +# +# @log-sector-size: sector size used in logging writes to @file, determines +# granularity of offsets and sizes of writes (default: 5= 12) +# +# Since: 3.0 +## +{ 'struct': 'BlockdevOptionsBlklogwrites', + 'data': { 'file': 'BlockdevRef', + 'log': 'BlockdevRef', + '*log-sector-size': 'uint32' } } + +## # @BlockdevOptionsBlkverify: # # Driver specific block device options for blkverify. @@ -3563,6 +3583,7 @@ 'discriminator': 'driver', 'data': { 'blkdebug': 'BlockdevOptionsBlkdebug', + 'blklogwrites':'BlockdevOptionsBlklogwrites', 'blkverify': 'BlockdevOptionsBlkverify', 'bochs': 'BlockdevOptionsGenericFormat', 'cloop': 'BlockdevOptionsGenericFormat', diff --git a/block/blklogwrites.c b/block/blklogwrites.c new file mode 100644 index 0000000000..0748b56d72 --- /dev/null +++ b/block/blklogwrites.c @@ -0,0 +1,392 @@ +/* + * Write logging blk driver based on blkverify and blkdebug. + * + * Copyright (c) 2017 Tuomas Tynkkynen + * Copyright (c) 2018 Aapo Vienamo + * Copyright (c) 2018 Ari Sundholm + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/sockets.h" /* for EINPROGRESS on Windows */ +#include "block/block_int.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" +#include "qemu/cutils.h" +#include "qemu/option.h" + +/* Disk format stuff - taken from Linux drivers/md/dm-log-writes.c */ + +#define LOG_FLUSH_FLAG (1 << 0) +#define LOG_FUA_FLAG (1 << 1) +#define LOG_DISCARD_FLAG (1 << 2) +#define LOG_MARK_FLAG (1 << 3) + +#define WRITE_LOG_VERSION 1ULL +#define WRITE_LOG_MAGIC 0x6a736677736872ULL + +/* All fields are little-endian. */ +struct log_write_super { + uint64_t magic; + uint64_t version; + uint64_t nr_entries; + uint32_t sectorsize; +} QEMU_PACKED; + +struct log_write_entry { + uint64_t sector; + uint64_t nr_sectors; + uint64_t flags; + uint64_t data_len; +} QEMU_PACKED; + +/* End of disk format structures. */ + +typedef struct { + BdrvChild *log_file; + uint32_t sectorsize; + uint32_t sectorbits; + uint64_t cur_log_sector; + uint64_t nr_entries; +} BDRVBlkLogWritesState; + +static inline uint32_t blk_log_writes_log2(uint32_t value) +{ + assert(value > 0); + return 31 - clz32(value); +} + +static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int f= lags, + Error **errp) +{ + BDRVBlkLogWritesState *s =3D bs->opaque; + Error *local_err =3D NULL; + int ret; + int64_t log_sector_size =3D BDRV_SECTOR_SIZE; + + /* Open the file */ + bs->file =3D bdrv_open_child(NULL, options, "file", bs, &child_file, f= alse, + &local_err); + if (local_err) { + ret =3D -EINVAL; + error_propagate(errp, local_err); + goto fail; + } + + if (qdict_haskey(options, "log-sector-size")) { + log_sector_size =3D qdict_get_int(options, "log-sector-size"); + qdict_del(options, "log-sector-size"); + } + + if (log_sector_size < 0 || log_sector_size >=3D (1ull << 32) || + !is_power_of_2(log_sector_size)) + { + ret =3D -EINVAL; + error_setg(errp, "Invalid log sector size %"PRId64, log_sector_siz= e); + goto fail; + } + + s->sectorsize =3D log_sector_size; + s->sectorbits =3D blk_log_writes_log2(log_sector_size); + s->cur_log_sector =3D 1; + s->nr_entries =3D 0; + + /* Open the log file */ + s->log_file =3D bdrv_open_child(NULL, options, "log", bs, &child_file,= false, + &local_err); + if (local_err) { + ret =3D -EINVAL; + error_propagate(errp, local_err); + goto fail; + } + + ret =3D 0; +fail: + if (ret < 0) { + bdrv_unref_child(bs, bs->file); + bs->file =3D NULL; + } + return ret; +} + +static void blk_log_writes_close(BlockDriverState *bs) +{ + BDRVBlkLogWritesState *s =3D bs->opaque; + + bdrv_unref_child(bs, s->log_file); + s->log_file =3D NULL; +} + +static int64_t blk_log_writes_getlength(BlockDriverState *bs) +{ + return bdrv_getlength(bs->file->bs); +} + +static void blk_log_writes_refresh_filename(BlockDriverState *bs, + QDict *options) +{ + BDRVBlkLogWritesState *s =3D bs->opaque; + + /* bs->file->bs has already been refreshed */ + bdrv_refresh_filename(s->log_file->bs); + + if (bs->file->bs->full_open_options + && s->log_file->bs->full_open_options) + { + QDict *opts =3D qdict_new(); + qdict_put_str(opts, "driver", "blklogwrites"); + + qobject_ref(bs->file->bs->full_open_options); + qdict_put_obj(opts, "file", QOBJECT(bs->file->bs->full_open_option= s)); + qobject_ref(s->log_file->bs->full_open_options); + qdict_put_obj(opts, "log", + QOBJECT(s->log_file->bs->full_open_options)); + + bs->full_open_options =3D opts; + } +} + +static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c, + const BdrvChildRole *role, + BlockReopenQueue *ro_q, + uint64_t perm, uint64_t shrd, + uint64_t *nperm, uint64_t *nshrd) +{ + if (!c) { + *nperm =3D perm & DEFAULT_PERM_PASSTHROUGH; + *nshrd =3D (shrd & DEFAULT_PERM_PASSTHROUGH) | DEFAULT_PERM_UNCHAN= GED; + return; + } + + if (!strcmp(c->name, "log")) { + bdrv_format_default_perms(bs, c, role, ro_q, perm, shrd, nperm, ns= hrd); + } else { + bdrv_filter_default_perms(bs, c, role, ro_q, perm, shrd, nperm, ns= hrd); + } +} + +static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **er= rp) +{ + BDRVBlkLogWritesState *s =3D bs->opaque; + bs->bl.request_alignment =3D s->sectorsize; +} + +static int coroutine_fn +blk_log_writes_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t b= ytes, + QEMUIOVector *qiov, int flags) +{ + return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); +} + +typedef struct BlkLogWritesFileReq { + BlockDriverState *bs; + uint64_t offset; + uint64_t bytes; + int file_flags; + QEMUIOVector *qiov; + int (*func)(struct BlkLogWritesFileReq *r); + int file_ret; +} BlkLogWritesFileReq; + +typedef struct { + BlockDriverState *bs; + QEMUIOVector *qiov; + struct log_write_entry entry; + uint64_t zero_size; + int log_ret; +} BlkLogWritesLogReq; + +static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) +{ + BDRVBlkLogWritesState *s =3D lr->bs->opaque; + uint64_t cur_log_offset =3D s->cur_log_sector << s->sectorbits; + + s->nr_entries++; + s->cur_log_sector +=3D + ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits; + + lr->log_ret =3D bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov-= >size, + lr->qiov, 0); + + /* Logging for the "write zeroes" operation */ + if (lr->log_ret =3D=3D 0 && lr->zero_size) { + cur_log_offset =3D s->cur_log_sector << s->sectorbits; + s->cur_log_sector +=3D + ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits; + + lr->log_ret =3D bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset, + lr->zero_size, 0); + } + + /* Update super block on flush */ + if (lr->log_ret =3D=3D 0 && lr->entry.flags & LOG_FLUSH_FLAG) { + struct log_write_super super =3D { + .magic =3D cpu_to_le64(WRITE_LOG_MAGIC), + .version =3D cpu_to_le64(WRITE_LOG_VERSION), + .nr_entries =3D cpu_to_le64(s->nr_entries), + .sectorsize =3D cpu_to_le32(s->sectorsize), + }; + void *zeroes =3D g_malloc0(s->sectorsize - sizeof(super)); + QEMUIOVector qiov; + + qemu_iovec_init(&qiov, 2); + qemu_iovec_add(&qiov, &super, sizeof(super)); + qemu_iovec_add(&qiov, zeroes, s->sectorsize - sizeof(super)); + + lr->log_ret =3D + bdrv_co_pwritev(s->log_file, 0, s->sectorsize, &qiov, 0); + if (lr->log_ret =3D=3D 0) { + lr->log_ret =3D bdrv_co_flush(s->log_file->bs); + } + qemu_iovec_destroy(&qiov); + g_free(zeroes); + } +} + +static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr) +{ + fr->file_ret =3D fr->func(fr); +} + +static int coroutine_fn +blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t byte= s, + QEMUIOVector *qiov, int flags, + int (*file_func)(BlkLogWritesFileReq *r), + uint64_t entry_flags, bool is_zero_write) +{ + QEMUIOVector log_qiov; + size_t niov =3D qiov ? qiov->niov : 0; + BDRVBlkLogWritesState *s =3D bs->opaque; + BlkLogWritesFileReq fr =3D { + .bs =3D bs, + .offset =3D offset, + .bytes =3D bytes, + .file_flags =3D flags, + .qiov =3D qiov, + .func =3D file_func, + }; + BlkLogWritesLogReq lr =3D { + .bs =3D bs, + .qiov =3D &log_qiov, + .entry =3D { + .sector =3D cpu_to_le64(offset >> s->sectorbits), + .nr_sectors =3D cpu_to_le64(bytes >> s->sectorbits), + .flags =3D cpu_to_le64(entry_flags), + .data_len =3D 0, + }, + .zero_size =3D is_zero_write ? bytes : 0, + }; + void *zeroes =3D g_malloc0(s->sectorsize - sizeof(lr.entry)); + + assert((1 << s->sectorbits) =3D=3D s->sectorsize); + assert(bs->bl.request_alignment =3D=3D s->sectorsize); + assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)); + assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment)); + + qemu_iovec_init(&log_qiov, niov + 2); + qemu_iovec_add(&log_qiov, &lr.entry, sizeof(lr.entry)); + qemu_iovec_add(&log_qiov, zeroes, s->sectorsize - sizeof(lr.entry)); + if (qiov) { + qemu_iovec_concat(&log_qiov, qiov, 0, qiov->size); + } + + blk_log_writes_co_do_file(&fr); + blk_log_writes_co_do_log(&lr); + + qemu_iovec_destroy(&log_qiov); + g_free(zeroes); + + if (lr.log_ret < 0) { + return lr.log_ret; + } + + return fr.file_ret; +} + +static int coroutine_fn +blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr) +{ + return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes, + fr->qiov, fr->file_flags); +} + +static int coroutine_fn +blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr) +{ + return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes, + fr->file_flags); +} + +static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileRe= q *fr) +{ + return bdrv_co_flush(fr->bs->file->bs); +} + +static int coroutine_fn +blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr) +{ + return bdrv_co_pdiscard(fr->bs->file->bs, fr->offset, fr->bytes); +} + +static int coroutine_fn +blk_log_writes_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t = bytes, + QEMUIOVector *qiov, int flags) +{ + return blk_log_writes_co_log(bs, offset, bytes, qiov, flags, + blk_log_writes_co_do_file_pwritev, 0, fal= se); +} + +static int coroutine_fn +blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int = bytes, + BdrvRequestFlags flags) +{ + return blk_log_writes_co_log(bs, offset, bytes, NULL, flags, + blk_log_writes_co_do_file_pwrite_zeroes, = 0, + true); +} + +static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *= bs) +{ + return blk_log_writes_co_log(bs, 0, 0, NULL, 0, + blk_log_writes_co_do_file_flush, + LOG_FLUSH_FLAG, false); +} + +static int coroutine_fn +blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int count) +{ + return blk_log_writes_co_log(bs, offset, count, NULL, 0, + blk_log_writes_co_do_file_pdiscard, + LOG_DISCARD_FLAG, false); +} + +static BlockDriver bdrv_blk_log_writes =3D { + .format_name =3D "blklogwrites", + .instance_size =3D sizeof(BDRVBlkLogWritesState), + + .bdrv_open =3D blk_log_writes_open, + .bdrv_close =3D blk_log_writes_close, + .bdrv_getlength =3D blk_log_writes_getlength, + .bdrv_refresh_filename =3D blk_log_writes_refresh_filename, + .bdrv_child_perm =3D blk_log_writes_child_perm, + .bdrv_refresh_limits =3D blk_log_writes_refresh_limits, + + .bdrv_co_preadv =3D blk_log_writes_co_preadv, + .bdrv_co_pwritev =3D blk_log_writes_co_pwritev, + .bdrv_co_pwrite_zeroes =3D blk_log_writes_co_pwrite_zeroes, + .bdrv_co_flush_to_disk =3D blk_log_writes_co_flush_to_disk, + .bdrv_co_pdiscard =3D blk_log_writes_co_pdiscard, + .bdrv_co_block_status =3D bdrv_co_block_status_from_file, + + .is_filter =3D true, +}; + +static void bdrv_blk_log_writes_init(void) +{ + bdrv_register(&bdrv_blk_log_writes); +} + +block_init(bdrv_blk_log_writes_init); diff --git a/MAINTAINERS b/MAINTAINERS index 42a1892d6a..5af89e7af3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2051,6 +2051,12 @@ S: Supported F: block/quorum.c L: qemu-block@nongnu.org =20 +blklogwrites +M: Ari Sundholm +L: qemu-block@nongnu.org +S: Supported +F: block/blklogwrites.c + blkverify M: Stefan Hajnoczi L: qemu-block@nongnu.org diff --git a/block/Makefile.objs b/block/Makefile.objs index 899bfb5e2c..c8337bf186 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -5,6 +5,7 @@ block-obj-y +=3D qed-check.o block-obj-y +=3D vhdx.o vhdx-endian.o vhdx-log.o block-obj-y +=3D quorum.o block-obj-y +=3D parallels.o blkdebug.o blkverify.o blkreplay.o +block-obj-y +=3D blklogwrites.o block-obj-y +=3D block-backend.o snapshot.o qapi.o block-obj-$(CONFIG_WIN32) +=3D file-win32.o win32-aio.o block-obj-$(CONFIG_POSIX) +=3D file-posix.o --=20 2.13.6