From patchwork Fri Apr 22 23:40:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 8916561 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E235DBF29F for ; Sat, 23 Apr 2016 00:01:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 001642020F for ; Sat, 23 Apr 2016 00:01:33 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C08F2201C7 for ; Sat, 23 Apr 2016 00:01:32 +0000 (UTC) Received: from localhost ([::1]:41997 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atl0u-0004YX-4R for patchwork-qemu-devel@patchwork.kernel.org; Fri, 22 Apr 2016 20:01:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atkht-0004R4-K4 for qemu-devel@nongnu.org; Fri, 22 Apr 2016 19:41:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1atkhr-0005hn-W9 for qemu-devel@nongnu.org; Fri, 22 Apr 2016 19:41:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58501) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atkhn-0005Xt-3o; Fri, 22 Apr 2016 19:41:47 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B329E3455AB; Fri, 22 Apr 2016 23:41:46 +0000 (UTC) Received: from red.redhat.com (ovpn-113-21.phx2.redhat.com [10.3.113.21]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u3MNfHXQ028475; Fri, 22 Apr 2016 19:41:45 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 22 Apr 2016 17:40:45 -0600 Message-Id: <1461368452-10389-38-git-send-email-eblake@redhat.com> In-Reply-To: <1461368452-10389-1-git-send-email-eblake@redhat.com> References: <1461368452-10389-1-git-send-email-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 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] [PATCH v3 37/44] nbd: Create struct for tracking export 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 , Paolo Bonzini , alex@alex.org.uk, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The NBD Protocol is introducing some additional information about exports, such as minimum request size and alignment, as well as an advertised maximum request size. It will be easier to feed this information back to the block layer if we gather all the information into a struct, rather than adding yet more pointer parameters during negotiation. Signed-off-by: Eric Blake --- block/nbd-client.h | 3 +-- include/block/nbd.h | 15 +++++++++++---- block/nbd-client.c | 10 ++++------ block/nbd.c | 2 +- nbd/client.c | 43 +++++++++++++++++++++++-------------------- qemu-nbd.c | 10 ++++------ 6 files changed, 44 insertions(+), 39 deletions(-) diff --git a/block/nbd-client.h b/block/nbd-client.h index 1243612..0867147 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -20,8 +20,7 @@ typedef struct NbdClientSession { QIOChannelSocket *sioc; /* The master data channel */ QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */ - uint16_t nbdflags; - off_t size; + NbdExportInfo info; CoMutex send_mutex; CoMutex free_sema; diff --git a/include/block/nbd.h b/include/block/nbd.h index 2fd1a67..3fa7996 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -117,17 +117,24 @@ enum { * aren't overflowing some other buffer. */ #define NBD_MAX_NAME_SIZE 256 +/* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */ +struct NbdExportInfo { + uint64_t size; + uint16_t flags; +}; +typedef struct NbdExportInfo NbdExportInfo; + ssize_t nbd_wr_syncv(QIOChannel *ioc, struct iovec *iov, size_t niov, size_t offset, size_t length, bool do_read); -int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, +int nbd_receive_negotiate(QIOChannel *ioc, const char *name, QCryptoTLSCreds *tlscreds, const char *hostname, - QIOChannel **outioc, - off_t *size, Error **errp); -int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size); + QIOChannel **outioc, NbdExportInfo *info, + Error **errp); +int nbd_init(int fd, QIOChannelSocket *sioc, NbdExportInfo *info); ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request); ssize_t nbd_receive_reply(QIOChannel *ioc, struct nbd_reply *reply); int nbd_client(int fd); diff --git a/block/nbd-client.c b/block/nbd-client.c index 285025d..f20219b 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -251,7 +251,7 @@ static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, struct nbd_reply reply; ssize_t ret; - if ((*flags & BDRV_REQ_FUA) && (client->nbdflags & NBD_FLAG_SEND_FUA)) { + if ((*flags & BDRV_REQ_FUA) && (client->info.flags & NBD_FLAG_SEND_FUA)) { *flags &= ~BDRV_REQ_FUA; request.flags |= NBD_CMD_FLAG_FUA; } @@ -316,7 +316,7 @@ int nbd_client_co_flush(BlockDriverState *bs) struct nbd_reply reply; ssize_t ret; - if (!(client->nbdflags & NBD_FLAG_SEND_FLUSH)) { + if (!(client->info.flags & NBD_FLAG_SEND_FLUSH)) { return 0; } @@ -342,7 +342,7 @@ int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, struct nbd_reply reply; ssize_t ret; - if (!(client->nbdflags & NBD_FLAG_SEND_TRIM)) { + if (!(client->info.flags & NBD_FLAG_SEND_TRIM)) { return 0; } request.from = sector_num * 512; @@ -403,10 +403,8 @@ int nbd_client_init(BlockDriverState *bs, qio_channel_set_blocking(QIO_CHANNEL(sioc), true, NULL); ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), export, - &client->nbdflags, tlscreds, hostname, - &client->ioc, - &client->size, errp); + &client->ioc, &client->info, errp); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); return ret; diff --git a/block/nbd.c b/block/nbd.c index f7ea3b3..34db83e 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -406,7 +406,7 @@ static int64_t nbd_getlength(BlockDriverState *bs) { BDRVNBDState *s = bs->opaque; - return s->client.size; + return s->client.info.size; } static void nbd_detach_aio_context(BlockDriverState *bs) diff --git a/nbd/client.c b/nbd/client.c index 4140d13..89fa2c3 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -413,13 +413,13 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, } -int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, +int nbd_receive_negotiate(QIOChannel *ioc, const char *name, QCryptoTLSCreds *tlscreds, const char *hostname, - QIOChannel **outioc, - off_t *size, Error **errp) + QIOChannel **outioc, NbdExportInfo *info, + Error **errp) { char buf[256]; - uint64_t magic, s; + uint64_t magic; int rc; bool zeroes = true; @@ -532,17 +532,19 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, } /* Read the response */ - if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { + if (read_sync(ioc, &info->size, sizeof(info->size)) != + sizeof(info->size)) { error_setg(errp, "Failed to read export length"); goto fail; } - *size = be64_to_cpu(s); + be64_to_cpus(&info->size); - if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) { + if (read_sync(ioc, &info->flags, sizeof(info->flags)) != + sizeof(info->flags)) { error_setg(errp, "Failed to read export flags"); goto fail; } - be16_to_cpus(flags); + be16_to_cpus(&info->flags); } else if (magic == NBD_CLIENT_MAGIC) { uint32_t oldflags; @@ -555,12 +557,12 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, goto fail; } - if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { + if (read_sync(ioc, &info->size, sizeof(info->size)) != + sizeof(info->size)) { error_setg(errp, "Failed to read export length"); goto fail; } - *size = be64_to_cpu(s); - TRACE("Size is %" PRIu64, *size); + be64_to_cpus(&info->size); if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) { error_setg(errp, "Failed to read export flags"); @@ -571,13 +573,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags); goto fail; } - *flags = oldflags; + info->flags = oldflags; } else { error_setg(errp, "Bad magic received"); goto fail; } - TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags); + TRACE("Size is %" PRIu64 ", export flags %" PRIx16, + info->size, info->flags); if (zeroes && drop_sync(ioc, 124) != 124) { error_setg(errp, "Failed to read reserved block"); goto fail; @@ -589,11 +592,11 @@ fail: } #ifdef __linux__ -int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size) +int nbd_init(int fd, QIOChannelSocket *sioc, NbdExportInfo *info) { - unsigned long sectors = size / BDRV_SECTOR_SIZE; - if (size / BDRV_SECTOR_SIZE != sectors) { - LOG("Export size %lld too large for 32-bit kernel", (long long) size); + unsigned long sectors = info->size / BDRV_SECTOR_SIZE; + if (info->size / BDRV_SECTOR_SIZE != sectors) { + LOG("Export size %" PRId64 " too large for 32-bit kernel", info->size); return -E2BIG; } @@ -625,9 +628,9 @@ int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size) return -serrno; } - if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) flags) < 0) { + if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) info->flags) < 0) { if (errno == ENOTTY) { - int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; + int read_only = (info->flags & NBD_FLAG_READ_ONLY) != 0; TRACE("Setting readonly attribute"); if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { @@ -685,7 +688,7 @@ int nbd_disconnect(int fd) } #else -int nbd_init(int fd, QIOChannelSocket *ioc, uint16_t flags, off_t size) +int nbd_init(int fd, QIOChannelSocket *ioc, NbdExportInfo *info) { return -ENOTSUP; } diff --git a/qemu-nbd.c b/qemu-nbd.c index 01eb7e4..a7cadcb 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -244,8 +244,7 @@ static void *show_parts(void *arg) static void *nbd_client_thread(void *arg) { char *device = arg; - off_t size; - uint16_t nbdflags; + NbdExportInfo info; QIOChannelSocket *sioc; int fd; int ret; @@ -260,9 +259,8 @@ static void *nbd_client_thread(void *arg) goto out; } - ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, &nbdflags, - NULL, NULL, NULL, - &size, &local_error); + ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, + NULL, NULL, NULL, &info, &local_error); if (ret < 0) { if (local_error) { error_report_err(local_error); @@ -277,7 +275,7 @@ static void *nbd_client_thread(void *arg) goto out_socket; } - ret = nbd_init(fd, sioc, nbdflags, size); + ret = nbd_init(fd, sioc, &info); if (ret < 0) { goto out_fd; }