All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, kwolf@redhat.com, mreitz@redhat.com, den@openvz.org
Subject: Re: [Qemu-devel] [PATCH 2/5] nbd/server: add nbd_opt_{read, drop} to track client->optlen
Date: Wed, 22 Nov 2017 11:08:35 -0600	[thread overview]
Message-ID: <a7572daf-a3dc-a6bf-ae60-a2e825bfc38d@redhat.com> (raw)
In-Reply-To: <20171122101958.17065-3-vsementsov@virtuozzo.com>

[-- Attachment #1: Type: text/plain, Size: 5322 bytes --]

On 11/22/2017 04:19 AM, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

The subject line says what and sort of implies why, but the commit
message body is rather sparse.

> ---
>  nbd/server.c | 34 ++++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)

Not a net win in lines of code, so a bit more justification may be helpful.

> 
> diff --git a/nbd/server.c b/nbd/server.c
> index bccc0274e7..c9445a89e9 100644
> --- a/nbd/server.c
> +++ b/nbd/server.c
> @@ -139,6 +139,19 @@ static void nbd_client_receive_next_request(NBDClient *client);
>  
>  */
>  
> +static inline int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
> +                               Error **errp)
> +{
> +    client->optlen -= size;
> +    return qio_channel_read_all(client->ioc, buffer, size, errp) < 0 ? -EIO : 0;

Should this code check that client->optlen >= size, and issue the
appropriate error message if not? That may centralize some of the error
checking repeated elsewhere.

> +}
> +
> +static inline int nbd_opt_drop(NBDClient *client, size_t size, Error **errp)
> +{
> +    client->optlen -= size;
> +    return nbd_drop(client->ioc, size, errp);

Same question on size validation.

> +}
> +
>  /* Send a reply header, including length, but no payload.
>   * Return -errno on error, 0 on success. */
>  static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
> @@ -299,7 +312,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client,
>          error_setg(errp, "Bad length received");
>          return -EINVAL;
>      }
> -    if (nbd_read(client->ioc, name, client->optlen, errp) < 0) {
> +    if (nbd_opt_read(client, name, client->optlen, errp) < 0) {
>          error_prepend(errp, "read failed: ");
>          return -EINVAL;

Here's an example caller that had a previous size validation.

>      }
> @@ -383,40 +396,36 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
>          msg = "overall request too short";
>          goto invalid;
>      }
> -    if (nbd_read(client->ioc, &namelen, sizeof(namelen), errp) < 0) {
> +    if (nbd_opt_read(client, &namelen, sizeof(namelen), errp) < 0) {
>          return -EIO;

And again, a size validation right before the call.

>      }
>      be32_to_cpus(&namelen);
> -    client->optlen -= sizeof(namelen);

Okay, part of the refactoring means you don't have to remember to track
remaining size separately from reading; that's a nice feature.  I
suspect it is also possible to assert that client->optlen is zero before
reading the next opt (I'm reviewing the patch in order, we'll see if I
come back here). [1]

>      if (namelen > client->optlen - sizeof(requests) ||
>          (client->optlen - namelen) % 2)
>      {
>          msg = "name length is incorrect";
>          goto invalid;
>      }
> -    if (nbd_read(client->ioc, name, namelen, errp) < 0) {
> +    if (nbd_opt_read(client, name, namelen, errp) < 0) {
>          return -EIO;
>      }

Another size check prior to the call (actually checking multiple
conditions)...

>      name[namelen] = '\0';
> -    client->optlen -= namelen;
>      trace_nbd_negotiate_handle_export_name_request(name);
>  
> -    if (nbd_read(client->ioc, &requests, sizeof(requests), errp) < 0) {
> +    if (nbd_opt_read(client, &requests, sizeof(requests), errp) < 0) {
>          return -EIO;

...and no direct size check before this call, because the earlier size
checks already covered it.  Arguably, the in-place size check error
messages may be slightly more precise, but any message at all about
unexpected sizing is appropriate (given that only broken clients should
be sending incorrect sizes) - so I'm still leaning towards a stronger
refactoring that puts the size check in the helper function.

> @@ -521,7 +530,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
>      return rc;
>  
>   invalid:
> -    if (nbd_drop(client->ioc, client->optlen, errp) < 0) {
> +    if (nbd_opt_drop(client, client->optlen, errp) < 0) {
>          return -EIO;
>      }
>      return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_INVALID,
> @@ -715,7 +724,7 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
>                  return -EINVAL;
>  
>              default:
> -                if (nbd_drop(client->ioc, length, errp) < 0) {
> +                if (nbd_opt_drop(client, length, errp) < 0) {

Isn't length == client->optlen here? If so, can we omit the length
parameter to nbd_opt_drop(), and instead have it defined as dropping to
the end of the current option?

> @@ -821,6 +830,7 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
>          if (ret < 0) {
>              return ret;
>          }
> +        assert(client->optlen == 0);

[1] Ah, you did add the assertion.

I'm going to propose a variant on this patch, to cover the points I made
above about ease-of-use (and to hopefully show a net win in lines of code).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

  reply	other threads:[~2017-11-22 17:08 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-22 10:19 [Qemu-devel] [PATCH 0/5] NBD server refactoring before BLOCK_STATUS Vladimir Sementsov-Ogievskiy
2017-11-22 10:19 ` [Qemu-devel] [PATCH 1/5] nbd/server: refactor negotiation functions parameters Vladimir Sementsov-Ogievskiy
2017-11-22 16:39   ` Eric Blake
2017-11-22 10:19 ` [Qemu-devel] [PATCH 2/5] nbd/server: add nbd_opt_{read, drop} to track client->optlen Vladimir Sementsov-Ogievskiy
2017-11-22 17:08   ` Eric Blake [this message]
2017-11-22 19:22   ` Eric Blake
2017-11-22 20:03   ` Eric Blake
2017-12-21  1:38     ` Eric Blake
2017-11-22 10:19 ` [Qemu-devel] [PATCH 3/5] nbd/server: add helper nbd_opt_invalid Vladimir Sementsov-Ogievskiy
2017-11-22 21:59   ` Eric Blake
2017-11-22 23:00   ` Eric Blake
2017-11-22 10:19 ` [Qemu-devel] [PATCH 4/5] nbd: rename nbd_option and nbd_opt_reply Vladimir Sementsov-Ogievskiy
2017-11-22 21:56   ` Eric Blake
2018-01-10 18:11     ` Eric Blake
2017-11-22 10:19 ` [Qemu-devel] [PATCH 5/5] nbd/server: structurize option reply sending Vladimir Sementsov-Ogievskiy
2017-11-22 22:02   ` Eric Blake
2018-01-10 18:14     ` Eric Blake
2017-11-22 11:07 ` [Qemu-devel] [PATCH 0/5] NBD server refactoring before BLOCK_STATUS no-reply
2017-11-22 11:54   ` [Qemu-devel] unrelated " Vladimir Sementsov-Ogievskiy

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=a7572daf-a3dc-a6bf-ae60-a2e825bfc38d@redhat.com \
    --to=eblake@redhat.com \
    --cc=den@openvz.org \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.