From nobody Mon Feb 9 13:38:19 2026 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505327804589283.0438023321916; Wed, 13 Sep 2017 11:36:44 -0700 (PDT) Received: from localhost ([::1]:44087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsCWg-00068A-Hy for importer@patchew.org; Wed, 13 Sep 2017 14:36:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37949) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsCId-0001JG-4v for qemu-devel@nongnu.org; Wed, 13 Sep 2017 14:22:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsCIb-0006hg-UX for qemu-devel@nongnu.org; Wed, 13 Sep 2017 14:22:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47404) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsCIV-0006cd-7K; Wed, 13 Sep 2017 14:22:03 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 61CF7356D9; Wed, 13 Sep 2017 18:22:02 +0000 (UTC) Received: from localhost (ovpn-204-23.brq.redhat.com [10.40.204.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D05265D6AE; Wed, 13 Sep 2017 18:22:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 61CF7356D9 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=mreitz@redhat.com From: Max Reitz To: qemu-block@nongnu.org Date: Wed, 13 Sep 2017 20:19:09 +0200 Message-Id: <20170913181910.29688-18-mreitz@redhat.com> In-Reply-To: <20170913181910.29688-1-mreitz@redhat.com> References: <20170913181910.29688-1-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 13 Sep 2017 18:22:02 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 17/18] qemu-io: Add background write 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: Kevin Wolf , Fam Zheng , qemu-devel@nongnu.org, Max Reitz , Stefan Hajnoczi , John Snow 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" Add a new parameter -B to qemu-io's write command. When used, qemu-io will not wait for the result of the operation and instead execute it in the background. Signed-off-by: Max Reitz --- qemu-io-cmds.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++-= ---- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 2811a89099..c635a248f5 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -481,6 +481,62 @@ static int do_pwrite(BlockBackend *blk, char *buf, int= 64_t offset, typedef struct { BlockBackend *blk; int64_t offset; + int bytes; + char *buf; + int flags; +} CoBackgroundWrite; + +static void coroutine_fn co_background_pwrite_entry(void *opaque) +{ + CoBackgroundWrite *data =3D opaque; + QEMUIOVector qiov; + int ret; + + qemu_iovec_init(&qiov, 1); + qemu_iovec_add(&qiov, data->buf, data->bytes); + + ret =3D blk_co_pwritev(data->blk, data->offset, data->bytes, &qiov, + data->flags); + + qemu_iovec_destroy(&qiov); + g_free(data->buf); + + if (ret < 0) { + Error *err; + error_setg_errno(&err, -ret, "Background write failed"); + error_report_err(err); + } +} + +/* Takes ownership of @buf */ +static int do_background_pwrite(BlockBackend *blk, char *buf, int64_t offs= et, + int64_t bytes, int flags) +{ + Coroutine *co; + CoBackgroundWrite *data; + + if (bytes > INT_MAX) { + return -ERANGE; + } + + data =3D g_new(CoBackgroundWrite, 1); + *data =3D (CoBackgroundWrite){ + .blk =3D blk, + .offset =3D offset, + .bytes =3D bytes, + .buf =3D buf, + .flags =3D flags, + }; + + co =3D qemu_coroutine_create(co_background_pwrite_entry, data); + bdrv_coroutine_enter(blk_bs(blk), co); + + return bytes; +} + +typedef struct { + BlockBackend *blk; + int64_t offset; int64_t bytes; int64_t *total; int flags; @@ -931,6 +987,7 @@ static void write_help(void) " Writes into a segment of the currently open file, using a buffer\n" " filled with a set pattern (0xcdcdcdcd).\n" " -b, -- write to the VM state rather than the virtual disk\n" +" -B, -- just start a background write, do not wait for the result\n" " -c, -- write compressed data with blk_write_compressed\n" " -f, -- use Force Unit Access semantics\n" " -p, -- ignored for backwards compatibility\n" @@ -951,7 +1008,7 @@ static const cmdinfo_t write_cmd =3D { .perm =3D BLK_PERM_WRITE, .argmin =3D 2, .argmax =3D -1, - .args =3D "[-bcCfquz] [-P pattern] off len", + .args =3D "[-bBcCfquz] [-P pattern] off len", .oneline =3D "writes a number of bytes at a specified offset", .help =3D write_help, }; @@ -961,6 +1018,7 @@ static int write_f(BlockBackend *blk, int argc, char *= *argv) struct timeval t1, t2; bool Cflag =3D false, qflag =3D false, bflag =3D false; bool Pflag =3D false, zflag =3D false, cflag =3D false; + bool background =3D false; int flags =3D 0; int c, cnt; char *buf =3D NULL; @@ -970,11 +1028,14 @@ static int write_f(BlockBackend *blk, int argc, char= **argv) int64_t total =3D 0; int pattern =3D 0xcd; =20 - while ((c =3D getopt(argc, argv, "bcCfpP:quz")) !=3D -1) { + while ((c =3D getopt(argc, argv, "bBcCfpP:quz")) !=3D -1) { switch (c) { case 'b': bflag =3D true; break; + case 'B': + background =3D true; + break; case 'c': cflag =3D true; break; @@ -1032,6 +1093,11 @@ static int write_f(BlockBackend *blk, int argc, char= **argv) return 0; } =20 + if (background && (bflag || cflag || zflag)) { + printf("-B cannot be specified together with -b, -c, or -z\n"); + return 0; + } + offset =3D cvtnum(argv[optind]); if (offset < 0) { print_cvtnum_err(offset, argv[optind]); @@ -1074,6 +1140,8 @@ static int write_f(BlockBackend *blk, int argc, char = **argv) cnt =3D do_co_pwrite_zeroes(blk, offset, count, flags, &total); } else if (cflag) { cnt =3D do_write_compressed(blk, buf, offset, count, &total); + } else if (background) { + cnt =3D do_background_pwrite(blk, buf, offset, count, flags); } else { cnt =3D do_pwrite(blk, buf, offset, count, flags, &total); } @@ -1088,12 +1156,15 @@ static int write_f(BlockBackend *blk, int argc, cha= r **argv) goto out; } =20 - /* Finally, report back -- -C gives a parsable format */ - t2 =3D tsub(t2, t1); - print_report("wrote", &t2, offset, count, total, cnt, Cflag); + if (!background) { + /* Finally, report back -- -C gives a parsable format */ + t2 =3D tsub(t2, t1); + print_report("wrote", &t2, offset, count, total, cnt, Cflag); + } =20 out: - if (!zflag) { + /* do_background_pwrite() takes ownership of the buffer */ + if (!zflag && !background) { qemu_io_free(buf); } =20 --=20 2.13.5