Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1072875/?format=api
{ "id": 1072875, "url": "http://patchwork.ozlabs.org/api/patches/1072875/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20190401140903.19186-12-eblake@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20190401140903.19186-12-eblake@redhat.com>", "list_archive_url": null, "date": "2019-04-01T14:09:00", "name": "[PULL,11/14] nbd/client: Support qemu-img convert from unaligned size", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "3b590362bc8e630d3e6ac841950b66c9cf6feb5a", "submitter": { "id": 6591, "url": "http://patchwork.ozlabs.org/api/people/6591/?format=api", "name": "Eric Blake", "email": "eblake@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20190401140903.19186-12-eblake@redhat.com/mbox/", "series": [ { "id": 100345, "url": "http://patchwork.ozlabs.org/api/series/100345/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=100345", "date": "2019-04-01T14:08:49", "name": "[PULL,01/14] qemu-img: Report bdrv_block_status failures", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/100345/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1072875/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1072875/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=209.51.188.17; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=redhat.com" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 44Xvvt2Qvvz9sPv\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 2 Apr 2019 01:33:14 +1100 (AEDT)", "from localhost ([127.0.0.1]:39350 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1hAxzs-0007hA-8k\n\tfor incoming@patchwork.ozlabs.org; Mon, 01 Apr 2019 10:33:12 -0400", "from eggs.gnu.org ([209.51.188.92]:45978)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <eblake@redhat.com>) id 1hAxcp-00027E-RX\n\tfor qemu-devel@nongnu.org; Mon, 01 Apr 2019 10:09:25 -0400", "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <eblake@redhat.com>) id 1hAxco-0004vW-BY\n\tfor qemu-devel@nongnu.org; Mon, 01 Apr 2019 10:09:23 -0400", "from mx1.redhat.com ([209.132.183.28]:48538)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <eblake@redhat.com>)\n\tid 1hAxck-0004pb-59; Mon, 01 Apr 2019 10:09:18 -0400", "from smtp.corp.redhat.com\n\t(int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 6EBC630BA356;\n\tMon, 1 Apr 2019 14:09:17 +0000 (UTC)", "from blue.redhat.com (ovpn-116-75.phx2.redhat.com [10.3.116.75])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id CCE6327BC7;\n\tMon, 1 Apr 2019 14:09:16 +0000 (UTC)" ], "From": "Eric Blake <eblake@redhat.com>", "To": "qemu-devel@nongnu.org", "Date": "Mon, 1 Apr 2019 09:09:00 -0500", "Message-Id": "<20190401140903.19186-12-eblake@redhat.com>", "In-Reply-To": "<20190401140903.19186-1-eblake@redhat.com>", "References": "<20190401140903.19186-1-eblake@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 2.84 on 10.5.11.23", "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.49]);\n\tMon, 01 Apr 2019 14:09:17 +0000 (UTC)", "Content-Transfer-Encoding": "quoted-printable", "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]", "X-Received-From": "209.132.183.28", "Subject": "[Qemu-devel] [PULL 11/14] nbd/client: Support qemu-img convert from\n\tunaligned size", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.21", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "Kevin Wolf <kwolf@redhat.com>,\n\t\"Richard W . M . Jones\" <rjones@redhat.com>, \n\t\"open list:Network Block Dev...\" <qemu-block@nongnu.org>,\n\tMax Reitz <mreitz@redhat.com>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "If an NBD server advertises a size that is not a multiple of a sector,\nthe block layer rounds up that size, even though we set info.size to\nthe exact byte value sent by the server. The block layer then proceeds\nto let us read or query block status on the hole that it added past\nEOF, which the NBD server is unlikely to be happy with. Fortunately,\nqemu as a server never advertizes an unaligned size, so we generally\ndon't run into this problem; but the nbdkit server makes it easy to\ntest:\n\n$ printf %1000d 1 > f1\n$ ~/nbdkit/nbdkit -fv file f1 & pid=$!\n$ qemu-img convert -f raw nbd://localhost:10809 f2\n$ kill $pid\n$ qemu-img compare f1 f2\n\nPre-patch, the server attempts a 1024-byte read, which nbdkit\nrightfully rejects as going beyond its advertised 1000 byte size; the\nconversion fails and the output files differ (not even the first\nsector is copied, because qemu-img does not follow ddrescue's habit of\ntrying smaller reads to get as much information as possible in spite\nof errors). Post-patch, the client's attempts to read (and query block\nstatus, for new enough nbdkit) are properly truncated to the server's\nlength, with sane handling of the hole the block layer forced on\nus. Although f2 ends up as a larger file (1024 bytes instead of 1000),\nqemu-img compare shows the two images to have identical contents for\ndisplay to the guest.\n\nI didn't add iotests coverage since I didn't want to add a dependency\non nbdkit in iotests. I also did NOT patch write, trim, or write\nzeroes - these commands continue to fail (usually with ENOSPC, but\nwhatever the server chose), because we really can't write to the end\nof the file, and because 'qemu-img convert' is the most common case\nwhere we care about being tolerant (which is read-only). Perhaps we\ncould truncate the request if the client is writing zeros to the tail,\nbut that seems like more work, especially if the block layer is fixed\nin 4.1 to track byte-accurate sizing (in which case this patch would\nbe reverted as unnecessary).\n\nSigned-off-by: Eric Blake <eblake@redhat.com>\nMessage-Id: <20190329042750.14704-5-eblake@redhat.com>\nTested-by: Richard W.M. Jones <rjones@redhat.com>\n---\n block/nbd-client.c | 39 ++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 38 insertions(+), 1 deletion(-)", "diff": "diff --git a/block/nbd-client.c b/block/nbd-client.c\nindex 3edb508f668..409c2171bc3 100644\n--- a/block/nbd-client.c\n+++ b/block/nbd-client.c\n@@ -848,6 +848,25 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,\n if (!bytes) {\n return 0;\n }\n+ /*\n+ * Work around the fact that the block layer doesn't do\n+ * byte-accurate sizing yet - if the read exceeds the server's\n+ * advertised size because the block layer rounded size up, then\n+ * truncate the request to the server and tail-pad with zero.\n+ */\n+ if (offset >= client->info.size) {\n+ assert(bytes < BDRV_SECTOR_SIZE);\n+ qemu_iovec_memset(qiov, 0, 0, bytes);\n+ return 0;\n+ }\n+ if (offset + bytes > client->info.size) {\n+ uint64_t slop = offset + bytes - client->info.size;\n+\n+ assert(slop < BDRV_SECTOR_SIZE);\n+ qemu_iovec_memset(qiov, bytes - slop, 0, slop);\n+ request.len -= slop;\n+ }\n+\n ret = nbd_co_send_request(bs, &request, NULL);\n if (ret < 0) {\n return ret;\n@@ -966,7 +985,8 @@ int coroutine_fn nbd_client_co_block_status(BlockDriverState *bs,\n .from = offset,\n .len = MIN(MIN_NON_ZERO(QEMU_ALIGN_DOWN(INT_MAX,\n bs->bl.request_alignment),\n- client->info.max_block), bytes),\n+ client->info.max_block),\n+ MIN(bytes, client->info.size - offset)),\n .flags = NBD_CMD_FLAG_REQ_ONE,\n };\n\n@@ -977,6 +997,23 @@ int coroutine_fn nbd_client_co_block_status(BlockDriverState *bs,\n return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;\n }\n\n+ /*\n+ * Work around the fact that the block layer doesn't do\n+ * byte-accurate sizing yet - if the status request exceeds the\n+ * server's advertised size because the block layer rounded size\n+ * up, we truncated the request to the server (above), or are\n+ * called on just the hole.\n+ */\n+ if (offset >= client->info.size) {\n+ *pnum = bytes;\n+ assert(bytes < BDRV_SECTOR_SIZE);\n+ /* Intentionally don't report offset_valid for the hole */\n+ return BDRV_BLOCK_ZERO;\n+ }\n+\n+ if (client->info.min_block) {\n+ assert(QEMU_IS_ALIGNED(request.len, client->info.min_block));\n+ }\n ret = nbd_co_send_request(bs, &request, NULL);\n if (ret < 0) {\n return ret;\n", "prefixes": [ "PULL", "11/14" ] }