From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: qemu-stable@nongnu.org, Eric Blake <eblake@redhat.com>,
Max Reitz <mreitz@redhat.com>
Subject: [Qemu-devel] [PATCH 40/79] blkdebug: Add pass-through write_zero and discard support
Date: Mon, 28 Aug 2017 19:14:15 -0500 [thread overview]
Message-ID: <1503965694-10794-41-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1503965694-10794-1-git-send-email-mdroth@linux.vnet.ibm.com>
From: Eric Blake <eblake@redhat.com>
In order to test the effects of artificial geometry constraints
on operations like write zero or discard, we first need blkdebug
to manage these actions. It also allows us to inject errors on
those operations, just like we can for read/write/flush.
We can also test the contract promised by the block layer; namely,
if a device has specified limits on alignment or maximum size,
then those limits must be obeyed (for now, the blkdebug driver
merely inherits limits from whatever it is wrapping, but the next
patch will further enhance it to allow specific limit overrides).
This patch intentionally refuses to service requests smaller than
the requested alignments; this is because an upcoming patch adds
a qemu-iotest to prove that the block layer is correctly handling
fragmentation, but the test only works if there is a way to tell
the difference at artificial alignment boundaries when blkdebug is
using a larger-than-default alignment. If we let the blkdebug
layer always defer to the underlying layer, which potentially has
a smaller granularity, the iotest will be thwarted.
Tested by setting up an NBD server with export 'foo', then invoking:
$ ./qemu-io
qemu-io> open -o driver=blkdebug blkdebug::nbd://localhost:10809/foo
qemu-io> d 0 15M
qemu-io> w -z 0 15M
Pre-patch, the server never sees the discard (it was silently
eaten by the block layer); post-patch it is passed across the
wire. Likewise, pre-patch the write is always passed with
NBD_WRITE (with 15M of zeroes on the wire), while post-patch
it can utilize NBD_WRITE_ZEROES (for less traffic).
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-7-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 63188c245013dbe383e8b031e665f813e2452ea5)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/blkdebug.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index c5d2edb..a3dc5f6 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -1,6 +1,7 @@
/*
* Block protocol for I/O error injection
*
+ * Copyright (C) 2016-2017 Red Hat, Inc.
* Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -382,6 +383,11 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}
+ bs->supported_write_flags = BDRV_REQ_FUA &
+ bs->file->bs->supported_write_flags;
+ bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
+ bs->file->bs->supported_zero_flags;
+
/* Set request alignment */
align = qemu_opt_get_size(opts, "align", 0);
if (align < INT_MAX && is_power_of_2(align)) {
@@ -494,6 +500,72 @@ static int blkdebug_co_flush(BlockDriverState *bs)
return bdrv_co_flush(bs->file->bs);
}
+static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
+ int64_t offset, int count,
+ BdrvRequestFlags flags)
+{
+ uint32_t align = MAX(bs->bl.request_alignment,
+ bs->bl.pwrite_zeroes_alignment);
+ int err;
+
+ /* Only pass through requests that are larger than requested
+ * preferred alignment (so that we test the fallback to writes on
+ * unaligned portions), and check that the block layer never hands
+ * us anything unaligned that crosses an alignment boundary. */
+ if (count < align) {
+ assert(QEMU_IS_ALIGNED(offset, align) ||
+ QEMU_IS_ALIGNED(offset + count, align) ||
+ DIV_ROUND_UP(offset, align) ==
+ DIV_ROUND_UP(offset + count, align));
+ return -ENOTSUP;
+ }
+ assert(QEMU_IS_ALIGNED(offset, align));
+ assert(QEMU_IS_ALIGNED(count, align));
+ if (bs->bl.max_pwrite_zeroes) {
+ assert(count <= bs->bl.max_pwrite_zeroes);
+ }
+
+ err = rule_check(bs, offset, count);
+ if (err) {
+ return err;
+ }
+
+ return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
+}
+
+static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
+ int64_t offset, int count)
+{
+ uint32_t align = bs->bl.pdiscard_alignment;
+ int err;
+
+ /* Only pass through requests that are larger than requested
+ * minimum alignment, and ensure that unaligned requests do not
+ * cross optimum discard boundaries. */
+ if (count < bs->bl.request_alignment) {
+ assert(QEMU_IS_ALIGNED(offset, align) ||
+ QEMU_IS_ALIGNED(offset + count, align) ||
+ DIV_ROUND_UP(offset, align) ==
+ DIV_ROUND_UP(offset + count, align));
+ return -ENOTSUP;
+ }
+ assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
+ assert(QEMU_IS_ALIGNED(count, bs->bl.request_alignment));
+ if (align && count >= align) {
+ assert(QEMU_IS_ALIGNED(offset, align));
+ assert(QEMU_IS_ALIGNED(count, align));
+ }
+ if (bs->bl.max_pdiscard) {
+ assert(count <= bs->bl.max_pdiscard);
+ }
+
+ err = rule_check(bs, offset, count);
+ if (err) {
+ return err;
+ }
+
+ return bdrv_co_pdiscard(bs->file->bs, offset, count);
+}
static void blkdebug_close(BlockDriverState *bs)
{
@@ -748,6 +820,8 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_co_preadv = blkdebug_co_preadv,
.bdrv_co_pwritev = blkdebug_co_pwritev,
.bdrv_co_flush_to_disk = blkdebug_co_flush,
+ .bdrv_co_pwrite_zeroes = blkdebug_co_pwrite_zeroes,
+ .bdrv_co_pdiscard = blkdebug_co_pdiscard,
.bdrv_debug_event = blkdebug_debug_event,
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
--
2.7.4
next prev parent reply other threads:[~2017-08-29 0:16 UTC|newest]
Thread overview: 93+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-29 0:13 [Qemu-devel] [PATCH 00/79] Patch Round-up for stable 2.9.1, freeze on 2017-09-04 Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 01/79] qga-win: Enable 'can-offline' field in 'guest-get-vcpus' reply Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 02/79] dirty-bitmap: Report BlockDirtyInfo.count in bytes, as documented Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 03/79] qemu-img/convert: Always set ret < 0 on error Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 04/79] qemu-img/convert: Use @opts for one thing only Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 05/79] qemu-img/convert: Move bs_n > 1 && -B check down Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 06/79] block: An empty filename counts as no filename Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 07/79] iotests/051: Add test for empty filename Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 08/79] migration: setup bi-directional I/O channel for exec: protocol Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 09/79] pci: deassert intx when pci device unrealize Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 10/79] block: Do not unref bs->file on error in BD's open Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 11/79] ACPI: don't call acpi_pcihp_device_plug_cb on xen Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 12/79] replication: Make --disable-replication compile again Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 13/79] 9pfs: local: fix unlink of alien files in mapped-file mode Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 14/79] coccinelle: Add script to remove useless QObject casts Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 15/79] qobject: Drop " Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 16/79] qobject: Add helper macros for common scalar insertions Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 17/79] s390x: Drop useless casts Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 18/79] qobject: Use simpler QDict/QList scalar insertion macros Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 19/79] block: Reuse bs as backing hd for drive-backup sync=none Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 20/79] hw/virtio: fix vhost user fails to startup when MQ Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 21/79] aio: add missing aio_notify() to aio_enable_external() Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 22/79] qemu-img: wait for convert coroutines to complete Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 23/79] block/vhdx: Make vhdx_create() always set errp Michael Roth
2017-08-29 0:13 ` [Qemu-devel] [PATCH 24/79] block: Add errp to b{lk, drv}_truncate() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 25/79] blockdev: use drained_begin/end for qmp_block_resize Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 26/79] target/xtensa: fix mapping direction in read/write simcalls Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 27/79] target/xtensa: fix return value of " Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 28/79] curl: strengthen assertion in curl_clean_state Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 29/79] curl: never invoke callbacks with s->mutex held Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 30/79] curl: avoid recursive locking of BDRVCURLState mutex Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 31/79] stream: fix crash in stream_start() when block_job_create() fails Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 32/79] vvfat: fix qemu-img map and qemu-img convert Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 33/79] virtio: allow broken device to notify guest Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 34/79] virtio-scsi: Unset hotplug handler when unrealize Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 35/79] e1000e: Fix ICR "Other" causes clear logic Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 36/79] s390x/css: catch section mismatch on load Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 37/79] virtio-net: fix wild pointer when remove virtio-net queues Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 38/79] blkdebug: Sanity check block layer guarantees Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 39/79] blkdebug: Refactor error injection Michael Roth
2017-08-29 0:14 ` Michael Roth [this message]
2017-08-29 0:14 ` [Qemu-devel] [PATCH 41/79] blkdebug: Simplify override logic Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 42/79] blkdebug: Add ability to override unmap geometries Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 43/79] tests: Add coverage for recent block geometry fixes Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 44/79] block: Simplify BDRV_BLOCK_RAW recursion Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 45/79] block: Guarantee that *file is set on bdrv_get_block_status() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 46/79] mirror: Drop permissions on s->target on completion Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 47/79] virtio-serial-bus: Unset hotplug handler when unrealize Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 48/79] linuxboot_dma: compile for i486 Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 49/79] tests: check-qom-proplist: add checks for cmdline-created objects Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 50/79] monitor: fix object_del for command-line-created objects Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 51/79] pc: Use "min-[x]level" on compat_props Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 52/79] target/ppc: pass const string to kvmppc_is_mem_backend_page_size_ok() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 53/79] target/ppc: fix memory leak in kvmppc_is_mem_backend_page_size_ok() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 54/79] spapr: add pre_plug function for memory Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 55/79] spapr: fix memory leak in spapr_memory_pre_plug() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 56/79] target/xtensa: handle unknown registers in gdbstub Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 57/79] commit: Fix use after free in completion Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 58/79] nbd: Fully initialize client in case of failed negotiation Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 59/79] nbd: Fix regression on resiliency to port scan Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 60/79] commit: Fix completion with extra reference Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 61/79] blkdebug: Catch bs->exact_filename overflow Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 62/79] blkverify: " Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 63/79] nbd: fix NBD over TLS Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 64/79] block: Do not strcmp() with NULL uri->scheme Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 65/79] 9pfs: local: remove: use correct path component Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 66/79] hid: Reset kbd modifiers on reset Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 67/79] spapr: fix migration to pseries machine < 2.8 Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 68/79] virtio-scsi: finalize IOMMU support Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 69/79] commit: Add NULL check for overlay_bs Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 70/79] spapr: fix memory leak in spapr_core_pre_plug() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 71/79] virtio-net: fix offload ctrl endian Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 72/79] input: limit kbd queue depth Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 73/79] input: Decrement queue count on kbd delay Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 74/79] qemu-iotests: Test automatic commit job cancel on hot unplug Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 75/79] block: Skip implicit nodes in query-block/blockstats Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 76/79] cpu: don't allow negative core id Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 77/79] hw/i386: allow SHPC for Q35 machine Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 78/79] block/nfs: fix mutex assertion in nfs_file_close() Michael Roth
2017-08-29 0:14 ` [Qemu-devel] [PATCH 79/79] 9pfs: local: fix fchmodat_nofollow() limitations Michael Roth
2017-08-29 0:47 ` [Qemu-devel] [PATCH 00/79] Patch Round-up for stable 2.9.1, freeze on 2017-09-04 Michael Roth
2017-08-29 2:18 ` Thomas Huth
2017-08-29 7:41 ` Cornelia Huck
2017-08-31 16:42 ` Michael Roth
2017-08-31 17:07 ` Peter Maydell
2017-08-31 18:09 ` Michael Roth
2017-08-29 14:04 ` Cole Robinson
2017-08-31 10:21 ` Peter Maydell
2017-08-31 18:00 ` Michael Roth
2017-09-01 23:22 ` Michael Roth
2017-08-31 18:19 ` [Qemu-devel] [Qemu-stable] " Peter Lieven
2017-09-01 19:03 ` Bruce Rogers
2017-09-04 17:33 ` [Qemu-devel] " Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1503965694-10794-41-git-send-email-mdroth@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=eblake@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).