From patchwork Tue May 1 21:13:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 907226 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=208.118.235.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40bDgw2kd3z9s27 for ; Wed, 2 May 2018 07:14:52 +1000 (AEST) Received: from localhost ([::1]:46202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcbp-0006za-Rs for incoming@patchwork.ozlabs.org; Tue, 01 May 2018 17:14:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46213) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcav-0006m2-VC for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDcau-0001Zx-Re for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:53 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:36450 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 1fDcaq-0001Ws-MH; Tue, 01 May 2018 17:13:48 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 51993830B845; Tue, 1 May 2018 21:13:48 +0000 (UTC) Received: from red.redhat.com (ovpn-123-248.rdu2.redhat.com [10.10.123.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id AC0F3214138C; Tue, 1 May 2018 21:13:47 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 1 May 2018 16:13:33 -0500 Message-Id: <20180501211336.986372-2-eblake@redhat.com> In-Reply-To: <20180501211336.986372-1-eblake@redhat.com> References: <20180501211336.986372-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 01 May 2018 21:13:48 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 01 May 2018 21:13:48 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'eblake@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] [PATCH 1/4] nbd: Prepare for additional block sizing info 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 , vsementsov@virtuozzo.com, qemu-block@nongnu.org, Max Reitz , Paolo Bonzini , edgar.kaziakhmedov@virtuozzo.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The NBD spec is clarifying [1] that a server may want to advertise different limits for READ/WRITE (in our case, 32M) than for TRIM/ZERO (in our case, nearly 4G). Add the constants and name lookups for new NBD_INFO_ fields used during handshake to convey this additional information. Note that the NBD spec already requires servers to ignore unknown requests from the client, and for clients to ignore unknown gratuitous responses sent from the server. [1] https://lists.debian.org/nbd/2018/03/msg00048.html Signed-off-by: Eric Blake Reviewed-by:  Vladimir Sementsov-Ogievskiy --- The given URL for the NBD spec was v3; it will change to be a v4 version of that patch in part to point back to this qemu commit as a proof of implementation. --- include/block/nbd.h | 4 +++- nbd/common.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index fcdcd545023..cbf51628f78 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Red Hat, Inc. + * Copyright (C) 2016-2018 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori * * Network Block Device @@ -180,6 +180,8 @@ typedef struct NBDExtent { #define NBD_INFO_NAME 1 #define NBD_INFO_DESCRIPTION 2 #define NBD_INFO_BLOCK_SIZE 3 +#define NBD_INFO_TRIM_SIZE 4 +#define NBD_INFO_ZERO_SIZE 5 /* Request flags, sent from client to server during transmission phase */ #define NBD_CMD_FLAG_FUA (1 << 0) /* 'force unit access' during write */ diff --git a/nbd/common.c b/nbd/common.c index 8c95c1d606e..840c91d5ca4 100644 --- a/nbd/common.c +++ b/nbd/common.c @@ -129,6 +129,10 @@ const char *nbd_info_lookup(uint16_t info) return "description"; case NBD_INFO_BLOCK_SIZE: return "block size"; + case NBD_INFO_TRIM_SIZE: + return "trim size"; + case NBD_INFO_ZERO_SIZE: + return "zero size"; default: return ""; } From patchwork Tue May 1 21:13:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 907228 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=208.118.235.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40bDl0511Tz9s21 for ; Wed, 2 May 2018 07:17:32 +1000 (AEST) Received: from localhost ([::1]:46222 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDceQ-0000un-49 for incoming@patchwork.ozlabs.org; Tue, 01 May 2018 17:17:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46210) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcav-0006lx-PY for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDcau-0001Zr-RZ for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:53 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:42962 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 1fDcar-0001XH-Ai; Tue, 01 May 2018 17:13:49 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 03E1B4075A9D; Tue, 1 May 2018 21:13:49 +0000 (UTC) Received: from red.redhat.com (ovpn-123-248.rdu2.redhat.com [10.10.123.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id 759C9214138C; Tue, 1 May 2018 21:13:48 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 1 May 2018 16:13:34 -0500 Message-Id: <20180501211336.986372-3-eblake@redhat.com> In-Reply-To: <20180501211336.986372-1-eblake@redhat.com> References: <20180501211336.986372-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 01 May 2018 21:13:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 01 May 2018 21:13:49 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'eblake@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] [PATCH 2/4] nbd/client: Refactor in preparation for more limits 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: Paolo Bonzini , vsementsov@virtuozzo.com, edgar.kaziakhmedov@virtuozzo.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The next patch will ask the server for more items of NBD_INFO. However, the server is free to respond with INFO items in a different order than what we request, so performing any sanity checks about constraints that occur between multiple INFO items must be done after all items have been received. Make it easier to see that such checks are last by sinking the final processing after the while loop, rather than embedded in the NBD_REP_ACK processing that occurs textually within the loop before other INFO processing. Signed-off-by: Eric Blake Reviewed-by:  Vladimir Sementsov-Ogievskiy --- nbd/client.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 232ff4f46da..0abb195b856 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Red Hat, Inc. + * Copyright (C) 2016-2018 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori * * Network Block Device Client Side @@ -365,17 +365,12 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, if (reply.type == NBD_REP_ACK) { /* Server is done sending info and moved into transmission - phase, but make sure it sent flags */ + phase */ if (len) { error_setg(errp, "server sent invalid NBD_REP_ACK"); return -1; } - if (!info->flags) { - error_setg(errp, "broken server omitted NBD_INFO_EXPORT"); - return -1; - } - trace_nbd_opt_go_success(); - return 1; + break; } if (reply.type != NBD_REP_INFO) { error_setg(errp, "unexpected reply type %" PRIu32 @@ -482,6 +477,14 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, break; } } + + /* Sanity check that server's responses make sense */ + if (!info->flags) { + error_setg(errp, "broken server omitted NBD_INFO_EXPORT"); + return -1; + } + trace_nbd_opt_go_success(); + return 1; } /* Return -1 on failure, 0 if wantname is an available export. */ From patchwork Tue May 1 21:13:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 907229 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=208.118.235.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40bDns5QFfz9s21 for ; Wed, 2 May 2018 07:20:01 +1000 (AEST) Received: from localhost ([::1]:46232 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcgp-0002gh-9w for incoming@patchwork.ozlabs.org; Tue, 01 May 2018 17:19:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcax-0006nD-7P for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDcav-0001aV-NA for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:55 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:42356 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 1fDcas-0001Xi-4T; Tue, 01 May 2018 17:13:50 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C71F87CBBA; Tue, 1 May 2018 21:13:49 +0000 (UTC) Received: from red.redhat.com (ovpn-123-248.rdu2.redhat.com [10.10.123.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B112214138C; Tue, 1 May 2018 21:13:49 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 1 May 2018 16:13:35 -0500 Message-Id: <20180501211336.986372-4-eblake@redhat.com> In-Reply-To: <20180501211336.986372-1-eblake@redhat.com> References: <20180501211336.986372-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 01 May 2018 21:13:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 01 May 2018 21:13:49 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'eblake@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] [PATCH 3/4] nbd/client: Support requests of additional block sizing info 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 , vsementsov@virtuozzo.com, qemu-block@nongnu.org, Max Reitz , Paolo Bonzini , edgar.kaziakhmedov@virtuozzo.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The NBD spec is clarifying [1] that a server may want to advertise different limits for READ/WRITE (in our case, 32M) than for TRIM/ZERO (in our case, nearly 4G). Implement the client side support for these alternate limits, by always requesting the new information (a compliant server must ignore the request if it is unknown), and by validating anything reported by the server before populating the block layer limits. [1] https://lists.debian.org/nbd/2018/03/msg00048.html Signed-off-by: Eric Blake --- The given URL for the NBD spec was v3; it will change to be a v4 version of that patch in part to point back to this qemu commit as a proof of implementation. --- include/block/nbd.h | 4 ++ block/nbd.c | 15 ++++++- nbd/client.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-- nbd/trace-events | 2 + 4 files changed, 131 insertions(+), 6 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index cbf51628f78..90ddef32bb3 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -270,6 +270,10 @@ struct NBDExportInfo { uint32_t min_block; uint32_t opt_block; uint32_t max_block; + uint32_t min_trim; + uint32_t max_trim; + uint32_t min_zero; + uint32_t max_zero; uint32_t meta_base_allocation_id; }; diff --git a/block/nbd.c b/block/nbd.c index 1e2b3ba2d3b..823d10b251d 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -478,8 +478,19 @@ static void nbd_refresh_limits(BlockDriverState *bs, Error **errp) uint32_t max = MIN_NON_ZERO(NBD_MAX_BUFFER_SIZE, s->info.max_block); bs->bl.request_alignment = min ? min : BDRV_SECTOR_SIZE; - bs->bl.max_pdiscard = max; - bs->bl.max_pwrite_zeroes = max; + if (s->info.max_trim) { + bs->bl.max_pdiscard = MIN(s->info.max_trim, BDRV_REQUEST_MAX_BYTES); + } else { + bs->bl.max_pdiscard = max; + } + bs->bl.pdiscard_alignment = s->info.min_trim; + if (s->info.max_zero) { + bs->bl.max_pwrite_zeroes = MIN(s->info.max_zero, + BDRV_REQUEST_MAX_BYTES); + } else { + bs->bl.max_pwrite_zeroes = max; + } + bs->bl.pwrite_zeroes_alignment = s->info.min_zero; bs->bl.max_transfer = max; if (s->info.opt_block && diff --git a/nbd/client.c b/nbd/client.c index 0abb195b856..f1364747ba1 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -337,16 +337,18 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, info->flags = 0; trace_nbd_opt_go_start(wantname); - buf = g_malloc(4 + len + 2 + 2 * info->request_sizes + 1); + buf = g_malloc(4 + len + 2 + 3 * 2 * info->request_sizes + 1); stl_be_p(buf, len); memcpy(buf + 4, wantname, len); - /* At most one request, everything else up to server */ - stw_be_p(buf + 4 + len, info->request_sizes); + /* Either 0 or 3 requests, everything else up to server */ + stw_be_p(buf + 4 + len, 3 * info->request_sizes); if (info->request_sizes) { stw_be_p(buf + 4 + len + 2, NBD_INFO_BLOCK_SIZE); + stw_be_p(buf + 4 + len + 2 + 2, NBD_INFO_TRIM_SIZE); + stw_be_p(buf + 4 + len + 2 + 2 + 2, NBD_INFO_ZERO_SIZE); } error = nbd_send_option_request(ioc, NBD_OPT_GO, - 4 + len + 2 + 2 * info->request_sizes, + 4 + len + 2 + 3 * 2 * info->request_sizes, buf, errp); g_free(buf); if (error < 0) { @@ -467,6 +469,72 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, info->max_block); break; + case NBD_INFO_TRIM_SIZE: + if (len != sizeof(info->min_trim) * 2) { + error_setg(errp, "remaining trim info len %" PRIu32 + " is unexpected size", len); + nbd_send_opt_abort(ioc); + return -1; + } + if (nbd_read(ioc, &info->min_trim, sizeof(info->min_trim), + errp) < 0) { + error_prepend(errp, "failed to read info minimum trim size: "); + nbd_send_opt_abort(ioc); + return -1; + } + be32_to_cpus(&info->min_trim); + if (nbd_read(ioc, &info->max_trim, sizeof(info->max_trim), + errp) < 0) { + error_prepend(errp, + "failed to read info maximum trim size: "); + nbd_send_opt_abort(ioc); + return -1; + } + be32_to_cpus(&info->max_trim); + if (!info->min_trim || !info->max_trim || + (info->max_trim != UINT32_MAX && + !QEMU_IS_ALIGNED(info->max_trim, info->min_trim))) { + error_setg(errp, "server trim sizes %" PRIu32 "/%" PRIu32 + " are not valid", info->min_trim, info->max_trim); + nbd_send_opt_abort(ioc); + return -1; + } + trace_nbd_opt_go_info_trim_size(info->min_trim, info->max_trim); + break; + + case NBD_INFO_ZERO_SIZE: + if (len != sizeof(info->min_zero) * 2) { + error_setg(errp, "remaining zero info len %" PRIu32 + " is unexpected size", len); + nbd_send_opt_abort(ioc); + return -1; + } + if (nbd_read(ioc, &info->min_zero, sizeof(info->min_zero), + errp) < 0) { + error_prepend(errp, "failed to read info minimum zero size: "); + nbd_send_opt_abort(ioc); + return -1; + } + be32_to_cpus(&info->min_zero); + if (nbd_read(ioc, &info->max_zero, sizeof(info->max_zero), + errp) < 0) { + error_prepend(errp, + "failed to read info maximum zero size: "); + nbd_send_opt_abort(ioc); + return -1; + } + be32_to_cpus(&info->max_zero); + if (!info->min_zero || !info->max_zero || + (info->max_zero != UINT32_MAX && + !QEMU_IS_ALIGNED(info->max_zero, info->min_zero))) { + error_setg(errp, "server zero sizes %" PRIu32 "/%" PRIu32 + " are not valid", info->min_zero, info->max_zero); + nbd_send_opt_abort(ioc); + return -1; + } + trace_nbd_opt_go_info_zero_size(info->min_zero, info->max_zero); + break; + default: trace_nbd_opt_go_info_unknown(type, nbd_info_lookup(type)); if (nbd_drop(ioc, len, errp) < 0) { @@ -483,6 +551,46 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, error_setg(errp, "broken server omitted NBD_INFO_EXPORT"); return -1; } + if (info->min_trim) { + if (!info->min_block) { + error_setg(errp, "broken server sent INFO_TRIM_SIZE without" + " INFO_BLOCK_SIZE"); + return -1; + } + if (info->min_trim < info->opt_block) { + error_setg(errp, "broken server sent INFO_TRIM_SIZE with" + " minimum trim %" PRIu32 " less than preferred block %" + PRIu32, info->min_trim, info->opt_block); + return -1; + } + if (info->max_trim < info->max_block) { + error_setg(errp, "broken server sent INFO_TRIM_SIZE with" + " maximum trim %" PRIu32 " less than maximum block %" + PRIu32, info->max_trim, info->max_block); + return -1; + } + info->max_trim = QEMU_ALIGN_DOWN(info->max_trim, info->min_block); + } + if (info->min_zero) { + if (!info->min_block) { + error_setg(errp, "broken server sent INFO_ZERO_SIZE without" + " INFO_BLOCK_SIZE"); + return -1; + } + if (info->min_zero < info->opt_block) { + error_setg(errp, "broken server sent INFO_ZERO_SIZE with" + " minimum zero %" PRIu32 " less than preferred block %" + PRIu32, info->min_zero, info->opt_block); + return -1; + } + if (info->max_zero < info->max_block) { + error_setg(errp, "broken server sent INFO_ZERO_SIZE with" + " maximum zero %" PRIu32 " less than maximum block %" + PRIu32, info->max_zero, info->max_block); + return -1; + } + info->max_zero = QEMU_ALIGN_DOWN(info->max_zero, info->min_block); + } trace_nbd_opt_go_success(); return 1; } diff --git a/nbd/trace-events b/nbd/trace-events index dee081e7758..ddb9d0a2b3e 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -6,6 +6,8 @@ nbd_opt_go_start(const char *name) "Attempting NBD_OPT_GO for export '%s'" nbd_opt_go_success(void) "Export is good to go" nbd_opt_go_info_unknown(int info, const char *name) "Ignoring unknown info %d (%s)" nbd_opt_go_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 +nbd_opt_go_info_trim_size(uint32_t minimum, uint32_t maximum) "Trim sizes are 0x%" PRIx32 ", 0x%" PRIx32 +nbd_opt_go_info_zero_size(uint32_t minimum, uint32_t maximum) "Zero sizes are 0x%" PRIx32 ", 0x%" PRIx32 nbd_receive_query_exports_start(const char *wantname) "Querying export list for '%s'" nbd_receive_query_exports_success(const char *wantname) "Found desired export name '%s'" nbd_receive_starttls_new_client(void) "Setting up TLS" From patchwork Tue May 1 21:13:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 907225 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=208.118.235.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40bDgr1JdYz9s21 for ; Wed, 2 May 2018 07:14:48 +1000 (AEST) Received: from localhost ([::1]:46198 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcbl-0006v0-GO for incoming@patchwork.ozlabs.org; Tue, 01 May 2018 17:14:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46232) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDcax-0006n0-0x for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDcav-0001ae-T5 for qemu-devel@nongnu.org; Tue, 01 May 2018 17:13:55 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:42360 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 1fDcat-0001Yi-14; Tue, 01 May 2018 17:13:51 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B04C784257; Tue, 1 May 2018 21:13:50 +0000 (UTC) Received: from red.redhat.com (ovpn-123-248.rdu2.redhat.com [10.10.123.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id 38D06214138C; Tue, 1 May 2018 21:13:49 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 1 May 2018 16:13:36 -0500 Message-Id: <20180501211336.986372-5-eblake@redhat.com> In-Reply-To: <20180501211336.986372-1-eblake@redhat.com> References: <20180501211336.986372-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 01 May 2018 21:13:50 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 01 May 2018 21:13:50 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'eblake@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] [PATCH 4/4] nbd/server: Support requests of additional block sizing info 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: Paolo Bonzini , vsementsov@virtuozzo.com, edgar.kaziakhmedov@virtuozzo.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The NBD spec is clarifying [1] that a server may want to advertise different limits for READ/WRITE (in our case, 32M) than for TRIM/ZERO (in our case, nearly 4G). Implement the server side support for these alternate limits, by always advertising the new information (a compliant client must ignore a gratuitous advertisement if it is unknown). [1] https://lists.debian.org/nbd/2018/03/msg00048.html Signed-off-by: Eric Blake --- The given URL for the NBD spec was v3; it will change to be a v4 version of that patch in part to point back to this qemu commit as a proof of implementation. --- nbd/server.c | 30 ++++++++++++++++++++++++++++++ nbd/trace-events | 2 ++ 2 files changed, 32 insertions(+) diff --git a/nbd/server.c b/nbd/server.c index 9e1f2271784..39502b58446 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -617,6 +617,36 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags, return rc; } + /* Send NBD_INFO_TRIM_SIZE always. */ + /* minimum - Hard-code to 4096 for now, matching preferred block. + * TODO: consult blk_bs(blk)->bl.pdiscard_alignment? */ + sizes[0] = 4096; + /* maximum - < 2G (then block layer fragments to bl.max_pdiscard). */ + sizes[1] = QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, sizes[0]); + trace_nbd_negotiate_handle_info_trim_size(sizes[0], sizes[1]); + cpu_to_be32s(&sizes[0]); + cpu_to_be32s(&sizes[1]); + rc = nbd_negotiate_send_info(client, NBD_INFO_TRIM_SIZE, + 2 * sizeof(sizes[0]), sizes, errp); + if (rc < 0) { + return rc; + } + + /* Send NBD_INFO_ZERO_SIZE always. */ + /* minimum - Hard-code to 4096 for now, matching preferred block. + * TODO: consult blk_bs(blk)->bl.pwrite_zeroes_alignment? */ + sizes[0] = 4096; + /* maximum - < 2G (then block layer fragments to bl.max_pwrite_zeroes). */ + sizes[1] = QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, sizes[0]); + trace_nbd_negotiate_handle_info_zero_size(sizes[0], sizes[1]); + cpu_to_be32s(&sizes[0]); + cpu_to_be32s(&sizes[1]); + rc = nbd_negotiate_send_info(client, NBD_INFO_ZERO_SIZE, + 2 * sizeof(sizes[0]), sizes, errp); + if (rc < 0) { + return rc; + } + /* Send NBD_INFO_EXPORT always */ trace_nbd_negotiate_new_style_size_flags(exp->size, exp->nbdflags | myflags); diff --git a/nbd/trace-events b/nbd/trace-events index ddb9d0a2b3e..d8849c43b21 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -46,6 +46,8 @@ nbd_negotiate_send_info(int info, const char *name, uint32_t length) "Sending NB nbd_negotiate_handle_info_requests(int requests) "Client requested %d items of info" nbd_negotiate_handle_info_request(int request, const char *name) "Client requested info %d (%s)" nbd_negotiate_handle_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t maximum) "advertising minimum 0x%" PRIx32 ", preferred 0x%" PRIx32 ", maximum 0x%" PRIx32 +nbd_negotiate_handle_info_trim_size(uint32_t minimum, uint32_t maximum) "advertising minimum 0x%" PRIx32 ", maximum 0x%" PRIx32 +nbd_negotiate_handle_info_zero_size(uint32_t minimum, uint32_t maximum) "advertising minimum 0x%" PRIx32 ", maximum 0x%" PRIx32 nbd_negotiate_handle_starttls(void) "Setting up TLS" nbd_negotiate_handle_starttls_handshake(void) "Starting TLS handshake" nbd_negotiate_meta_context(const char *optname, const char *export, uint32_t queries) "Client requested %s for export %s, with %" PRIu32 " queries"