From patchwork Wed Jan 18 14:59:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 136654 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E5634B6F62 for ; Thu, 19 Jan 2012 03:06:47 +1100 (EST) Received: from localhost ([::1]:51702 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RnX0R-0005Sn-3J for incoming@patchwork.ozlabs.org; Wed, 18 Jan 2012 10:00:55 -0500 Received: from eggs.gnu.org ([140.186.70.92]:44487) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RnWzo-0003sM-6w for qemu-devel@nongnu.org; Wed, 18 Jan 2012 10:00:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RnWzi-0002Qk-Dt for qemu-devel@nongnu.org; Wed, 18 Jan 2012 10:00:16 -0500 Received: from e06smtp16.uk.ibm.com ([195.75.94.112]:48288) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RnWzi-0002Qf-3h for qemu-devel@nongnu.org; Wed, 18 Jan 2012 10:00:10 -0500 Received: from /spool/local by e06smtp16.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 18 Jan 2012 15:00:08 -0000 Received: from d06nrmr1307.portsmouth.uk.ibm.com ([9.149.38.129]) by e06smtp16.uk.ibm.com ([192.168.101.146]) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 18 Jan 2012 15:00:07 -0000 Received: from d06av08.portsmouth.uk.ibm.com (d06av08.portsmouth.uk.ibm.com [9.149.37.249]) by d06nrmr1307.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q0IF061O2494470 for ; Wed, 18 Jan 2012 15:00:06 GMT Received: from d06av08.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q0IF06OG012031 for ; Wed, 18 Jan 2012 15:00:06 GMT Received: from localhost (sig-9-145-203-19.de.ibm.com [9.145.203.19]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q0IF05IS012010; Wed, 18 Jan 2012 15:00:06 GMT From: Stefan Hajnoczi To: Date: Wed, 18 Jan 2012 14:59:52 +0000 Message-Id: <1326898793-20331-7-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.8.3 In-Reply-To: <1326898793-20331-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1326898793-20331-1-git-send-email-stefanha@linux.vnet.ibm.com> x-cbid: 12011815-3548-0000-0000-000000C309CB X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.112 Cc: Kevin Wolf , Stefan Hajnoczi Subject: [Qemu-devel] [PATCH v4 6/6] qemu-io: add write -z option for bdrv_co_write_zeroes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Extend the qemu-io write command with the -z option to call bdrv_co_write_zeroes(). Exposing the zero write interface from qemu-io allows us to write tests that exercise this new block layer interface. Signed-off-by: Stefan Hajnoczi --- qemu-io.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 69 insertions(+), 8 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index 7c446b6..c02a702 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -218,6 +218,51 @@ static int do_pwrite(char *buf, int64_t offset, int count, int *total) return 1; } +typedef struct { + int64_t offset; + int count; + int *total; + int ret; + bool done; +} CoWriteZeroes; + +static void coroutine_fn co_write_zeroes_entry(void *opaque) +{ + CoWriteZeroes *data = opaque; + + data->ret = bdrv_co_write_zeroes(bs, data->offset / BDRV_SECTOR_SIZE, + data->count / BDRV_SECTOR_SIZE); + data->done = true; + if (data->ret < 0) { + *data->total = data->ret; + return; + } + + *data->total = data->count; +} + +static int do_co_write_zeroes(int64_t offset, int count, int *total) +{ + Coroutine *co; + CoWriteZeroes data = { + .offset = offset, + .count = count, + .total = total, + .done = false, + }; + + co = qemu_coroutine_create(co_write_zeroes_entry); + qemu_coroutine_enter(co, &data); + while (!data.done) { + qemu_aio_wait(); + } + if (data.ret < 0) { + return data.ret; + } else { + return 1; + } +} + static int do_load_vmstate(char *buf, int64_t offset, int count, int *total) { *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count); @@ -643,6 +688,7 @@ static void write_help(void) " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" " -q, -- quiet mode, do not show I/O statistics\n" +" -z, -- write zeroes using bdrv_co_write_zeroes\n" "\n"); } @@ -654,7 +700,7 @@ static const cmdinfo_t write_cmd = { .cfunc = write_f, .argmin = 2, .argmax = -1, - .args = "[-abCpq] [-P pattern ] off len", + .args = "[-bCpqz] [-P pattern ] off len", .oneline = "writes a number of bytes at a specified offset", .help = write_help, }; @@ -662,16 +708,16 @@ static const cmdinfo_t write_cmd = { static int write_f(int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, bflag = 0; + int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0; int c, cnt; - char *buf; + char *buf = NULL; int64_t offset; int count; /* Some compilers get confused and warn if this is not initialized. */ int total = 0; int pattern = 0xcd; - while ((c = getopt(argc, argv, "bCpP:q")) != EOF) { + while ((c = getopt(argc, argv, "bCpP:qz")) != EOF) { switch (c) { case 'b': bflag = 1; @@ -683,6 +729,7 @@ static int write_f(int argc, char **argv) pflag = 1; break; case 'P': + Pflag = 1; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; @@ -691,6 +738,9 @@ static int write_f(int argc, char **argv) case 'q': qflag = 1; break; + case 'z': + zflag = 1; + break; default: return command_usage(&write_cmd); } @@ -700,8 +750,13 @@ static int write_f(int argc, char **argv) return command_usage(&write_cmd); } - if (bflag && pflag) { - printf("-b and -p cannot be specified at the same time\n"); + if (bflag + pflag + zflag > 1) { + printf("-b, -p, or -z cannot be specified at the same time\n"); + return 0; + } + + if (zflag && Pflag) { + printf("-z and -P cannot be specified at the same time\n"); return 0; } @@ -732,13 +787,17 @@ static int write_f(int argc, char **argv) } } - buf = qemu_io_alloc(count, pattern); + if (!zflag) { + buf = qemu_io_alloc(count, pattern); + } gettimeofday(&t1, NULL); if (pflag) { cnt = do_pwrite(buf, offset, count, &total); } else if (bflag) { cnt = do_save_vmstate(buf, offset, count, &total); + } else if (zflag) { + cnt = do_co_write_zeroes(offset, count, &total); } else { cnt = do_write(buf, offset, count, &total); } @@ -758,7 +817,9 @@ static int write_f(int argc, char **argv) print_report("wrote", &t2, offset, count, total, cnt, Cflag); out: - qemu_io_free(buf); + if (!zflag) { + qemu_io_free(buf); + } return 0; }