]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/extra/0038-kvm-nbd-read_sync-and-friends-return-0-on-success.patch
fix qemu 2.9 drive mirroring to nbd target
[pve-qemu.git] / debian / patches / extra / 0038-kvm-nbd-read_sync-and-friends-return-0-on-success.patch
CommitLineData
b45e13fe
AD
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Eric Blake <eblake@redhat.com>
3Date: Wed, 19 Jul 2017 18:02:00 +0200
4Subject: [PATCH] nbd: read_sync and friends: return 0 on success
5
6RH-Author: Eric Blake <eblake@redhat.com>
7Message-id: <20170719180202.23329-3-eblake@redhat.com>
8Patchwork-id: 75818
9O-Subject: [RHEV-7.4.z qemu-kvm-rhev PATCH 2/4] nbd: read_sync and friends: return 0 on success
10Bugzilla: 1467509
11RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
14
15From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
17functions read_sync, drop_sync, write_sync, and also
18nbd_negotiate_write, nbd_negotiate_read, nbd_negotiate_drop_sync
19returns number of processed bytes. But what this number can be,
20except requested number of bytes?
21
22Actually, underlying nbd_wr_syncv function returns a value >= 0 and
23!= requested_bytes only on eof on read operation. So, firstly, it is
24impossible on write (let's add an assert) and on read it actually
25means, that communication is broken (except nbd_receive_reply, see
26below).
27
28Most of callers operate like this:
29 if (func(..., size) != size) {
30 /* error path */
31 }
32, i.e.:
33 1. They are not interested in partial success
34 2. Extra duplications in code (especially bad are duplications of
35 magic numbers)
36 3. User doesn't see actual error message, as return code is lost.
37 (this patch doesn't fix this point, but it makes fixing easier)
38
39Several callers handles ret >= 0 and != requested-size separately, by
40just returning EINVAL in this case. This patch makes read_sync and
41friends return EINVAL in this case, so final behavior is the same.
42
43And only one caller - nbd_receive_reply() does something not so
44obvious. It returns EINVAL for ret > 0 and != requested-size, like
45previous group, but for ret == 0 it returns 0. The only caller of
46nbd_receive_reply() - nbd_read_reply_entry() handles ret == 0 in the
47same way as ret < 0, so for now it doesn't matter. However, in
48following commits error path handling will be improved and we'll need
49to distinguish success from fail in this case too. So, this patch adds
50separate helper for this case - read_sync_eof.
51
52Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
53Message-Id: <20170516094533.6160-3-vsementsov@virtuozzo.com>
54Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
55(cherry picked from commit f5d406fe86bb28da85824b6581e58980cc1a07f3)
56Signed-off-by: Eric Blake <eblake@redhat.com>
57Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
58---
59 nbd/client.c | 63 ++++++++++++++++------------------------
60 nbd/nbd-internal.h | 34 +++++++++++++++++++---
61 nbd/server.c | 84 +++++++++++++++++++++---------------------------------
62 3 files changed, 88 insertions(+), 93 deletions(-)
63
64diff --git a/nbd/client.c b/nbd/client.c
65index a58fb02..6b74a62 100644
66--- a/nbd/client.c
67+++ b/nbd/client.c
68@@ -86,9 +86,9 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
69
70 */
71
72-/* Discard length bytes from channel. Return -errno on failure, or
73- * the amount of bytes consumed. */
74-static ssize_t drop_sync(QIOChannel *ioc, size_t size)
75+/* Discard length bytes from channel. Return -errno on failure and 0 on
76+ * success*/
77+static int drop_sync(QIOChannel *ioc, size_t size)
78 {
79 ssize_t ret = 0;
80 char small[1024];
81@@ -96,14 +96,13 @@ static ssize_t drop_sync(QIOChannel *ioc, size_t size)
82
83 buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
84 while (size > 0) {
85- ssize_t count = read_sync(ioc, buffer, MIN(65536, size));
86+ ssize_t count = MIN(65536, size);
87+ ret = read_sync(ioc, buffer, MIN(65536, size));
88
89- if (count <= 0) {
90+ if (ret < 0) {
91 goto cleanup;
92 }
93- assert(count <= size);
94 size -= count;
95- ret += count;
96 }
97
98 cleanup:
99@@ -136,12 +135,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt,
100 stl_be_p(&req.option, opt);
101 stl_be_p(&req.length, len);
102
103- if (write_sync(ioc, &req, sizeof(req)) != sizeof(req)) {
104+ if (write_sync(ioc, &req, sizeof(req)) < 0) {
105 error_setg(errp, "Failed to send option request header");
106 return -1;
107 }
108
109- if (len && write_sync(ioc, (char *) data, len) != len) {
110+ if (len && write_sync(ioc, (char *) data, len) < 0) {
111 error_setg(errp, "Failed to send option request data");
112 return -1;
113 }
114@@ -170,7 +169,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt,
115 nbd_opt_reply *reply, Error **errp)
116 {
117 QEMU_BUILD_BUG_ON(sizeof(*reply) != 20);
118- if (read_sync(ioc, reply, sizeof(*reply)) != sizeof(*reply)) {
119+ if (read_sync(ioc, reply, sizeof(*reply)) < 0) {
120 error_setg(errp, "failed to read option reply");
121 nbd_send_opt_abort(ioc);
122 return -1;
123@@ -219,7 +218,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply,
124 goto cleanup;
125 }
126 msg = g_malloc(reply->length + 1);
127- if (read_sync(ioc, msg, reply->length) != reply->length) {
128+ if (read_sync(ioc, msg, reply->length) < 0) {
129 error_setg(errp, "failed to read option error message");
130 goto cleanup;
131 }
132@@ -321,7 +320,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
133 nbd_send_opt_abort(ioc);
134 return -1;
135 }
136- if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {
137+ if (read_sync(ioc, &namelen, sizeof(namelen)) < 0) {
138 error_setg(errp, "failed to read option name length");
139 nbd_send_opt_abort(ioc);
140 return -1;
141@@ -334,7 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
142 return -1;
143 }
144 if (namelen != strlen(want)) {
145- if (drop_sync(ioc, len) != len) {
146+ if (drop_sync(ioc, len) < 0) {
147 error_setg(errp, "failed to skip export name with wrong length");
148 nbd_send_opt_abort(ioc);
149 return -1;
150@@ -343,14 +342,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
151 }
152
153 assert(namelen < sizeof(name));
154- if (read_sync(ioc, name, namelen) != namelen) {
155+ if (read_sync(ioc, name, namelen) < 0) {
156 error_setg(errp, "failed to read export name");
157 nbd_send_opt_abort(ioc);
158 return -1;
159 }
160 name[namelen] = '\0';
161 len -= namelen;
162- if (drop_sync(ioc, len) != len) {
163+ if (drop_sync(ioc, len) < 0) {
164 error_setg(errp, "failed to read export description");
165 nbd_send_opt_abort(ioc);
166 return -1;
167@@ -477,7 +476,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
168 goto fail;
169 }
170
171- if (read_sync(ioc, buf, 8) != 8) {
172+ if (read_sync(ioc, buf, 8) < 0) {
173 error_setg(errp, "Failed to read data");
174 goto fail;
175 }
176@@ -503,7 +502,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
177 goto fail;
178 }
179
180- if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
181+ if (read_sync(ioc, &magic, sizeof(magic)) < 0) {
182 error_setg(errp, "Failed to read magic");
183 goto fail;
184 }
185@@ -515,8 +514,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
186 uint16_t globalflags;
187 bool fixedNewStyle = false;
188
189- if (read_sync(ioc, &globalflags, sizeof(globalflags)) !=
190- sizeof(globalflags)) {
191+ if (read_sync(ioc, &globalflags, sizeof(globalflags)) < 0) {
192 error_setg(errp, "Failed to read server flags");
193 goto fail;
194 }
195@@ -534,8 +532,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
196 }
197 /* client requested flags */
198 clientflags = cpu_to_be32(clientflags);
199- if (write_sync(ioc, &clientflags, sizeof(clientflags)) !=
200- sizeof(clientflags)) {
201+ if (write_sync(ioc, &clientflags, sizeof(clientflags)) < 0) {
202 error_setg(errp, "Failed to send clientflags field");
203 goto fail;
204 }
205@@ -573,13 +570,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
206 }
207
208 /* Read the response */
209- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
210+ if (read_sync(ioc, &s, sizeof(s)) < 0) {
211 error_setg(errp, "Failed to read export length");
212 goto fail;
213 }
214 *size = be64_to_cpu(s);
215
216- if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
217+ if (read_sync(ioc, flags, sizeof(*flags)) < 0) {
218 error_setg(errp, "Failed to read export flags");
219 goto fail;
220 }
221@@ -596,14 +593,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
222 goto fail;
223 }
224
225- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
226+ if (read_sync(ioc, &s, sizeof(s)) < 0) {
227 error_setg(errp, "Failed to read export length");
228 goto fail;
229 }
230 *size = be64_to_cpu(s);
231 TRACE("Size is %" PRIu64, *size);
232
233- if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) {
234+ if (read_sync(ioc, &oldflags, sizeof(oldflags)) < 0) {
235 error_setg(errp, "Failed to read export flags");
236 goto fail;
237 }
238@@ -619,7 +616,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
239 }
240
241 TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags);
242- if (zeroes && drop_sync(ioc, 124) != 124) {
243+ if (zeroes && drop_sync(ioc, 124) < 0) {
244 error_setg(errp, "Failed to read reserved block");
245 goto fail;
246 }
247@@ -744,7 +741,6 @@ int nbd_disconnect(int fd)
248 ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request)
249 {
250 uint8_t buf[NBD_REQUEST_SIZE];
251- ssize_t ret;
252
253 TRACE("Sending request to server: "
254 "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64
255@@ -759,16 +755,7 @@ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request)
256 stq_be_p(buf + 16, request->from);
257 stl_be_p(buf + 24, request->len);
258
259- ret = write_sync(ioc, buf, sizeof(buf));
260- if (ret < 0) {
261- return ret;
262- }
263-
264- if (ret != sizeof(buf)) {
265- LOG("writing to socket failed");
266- return -EINVAL;
267- }
268- return 0;
269+ return write_sync(ioc, buf, sizeof(buf));
270 }
271
272 ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply)
273@@ -777,7 +764,7 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply)
274 uint32_t magic;
275 ssize_t ret;
276
277- ret = read_sync(ioc, buf, sizeof(buf));
278+ ret = read_sync_eof(ioc, buf, sizeof(buf));
279 if (ret <= 0) {
280 return ret;
281 }
282diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
283index f43d990..e6bbc7c 100644
284--- a/nbd/nbd-internal.h
285+++ b/nbd/nbd-internal.h
286@@ -94,7 +94,13 @@
287 #define NBD_ENOSPC 28
288 #define NBD_ESHUTDOWN 108
289
290-static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size)
291+/* read_sync_eof
292+ * Tries to read @size bytes from @ioc. Returns number of bytes actually read.
293+ * May return a value >= 0 and < size only on EOF, i.e. when iteratively called
294+ * qio_channel_readv() returns 0. So, there are no needs to call read_sync_eof
295+ * iteratively.
296+ */
297+static inline ssize_t read_sync_eof(QIOChannel *ioc, void *buffer, size_t size)
298 {
299 struct iovec iov = { .iov_base = buffer, .iov_len = size };
300 /* Sockets are kept in blocking mode in the negotiation phase. After
301@@ -105,12 +111,32 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size)
302 return nbd_wr_syncv(ioc, &iov, 1, size, true);
303 }
304
305-static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer,
306- size_t size)
307+/* read_sync
308+ * Reads @size bytes from @ioc. Returns 0 on success.
309+ */
310+static inline int read_sync(QIOChannel *ioc, void *buffer, size_t size)
311+{
312+ ssize_t ret = read_sync_eof(ioc, buffer, size);
313+
314+ if (ret >= 0 && ret != size) {
315+ ret = -EINVAL;
316+ }
317+
318+ return ret < 0 ? ret : 0;
319+}
320+
321+/* write_sync
322+ * Writes @size bytes to @ioc. Returns 0 on success.
323+ */
324+static inline int write_sync(QIOChannel *ioc, const void *buffer, size_t size)
325 {
326 struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size };
327
328- return nbd_wr_syncv(ioc, &iov, 1, size, false);
329+ ssize_t ret = nbd_wr_syncv(ioc, &iov, 1, size, false);
330+
331+ assert(ret < 0 || ret == size);
332+
333+ return ret < 0 ? ret : 0;
334 }
335
336 struct NBDTLSHandshakeData {
337diff --git a/nbd/server.c b/nbd/server.c
338index a98bb21..b44cbe6 100644
339--- a/nbd/server.c
340+++ b/nbd/server.c
341@@ -112,7 +112,7 @@ static gboolean nbd_negotiate_continue(QIOChannel *ioc,
342 return TRUE;
343 }
344
345-static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)
346+static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)
347 {
348 ssize_t ret;
349 guint watch;
350@@ -130,8 +130,7 @@ static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)
351
352 }
353
354-static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer,
355- size_t size)
356+static int nbd_negotiate_write(QIOChannel *ioc, const void *buffer, size_t size)
357 {
358 ssize_t ret;
359 guint watch;
360@@ -148,24 +147,24 @@ static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer,
361 return ret;
362 }
363
364-static ssize_t nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size)
365+static int nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size)
366 {
367- ssize_t ret, dropped = size;
368+ ssize_t ret;
369 uint8_t *buffer = g_malloc(MIN(65536, size));
370
371 while (size > 0) {
372- ret = nbd_negotiate_read(ioc, buffer, MIN(65536, size));
373+ size_t count = MIN(65536, size);
374+ ret = nbd_negotiate_read(ioc, buffer, count);
375 if (ret < 0) {
376 g_free(buffer);
377 return ret;
378 }
379
380- assert(ret <= size);
381- size -= ret;
382+ size -= count;
383 }
384
385 g_free(buffer);
386- return dropped;
387+ return 0;
388 }
389
390 /* Basic flow for negotiation
391@@ -206,22 +205,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type,
392 type, opt, len);
393
394 magic = cpu_to_be64(NBD_REP_MAGIC);
395- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
396+ if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) < 0) {
397 LOG("write failed (rep magic)");
398 return -EINVAL;
399 }
400 opt = cpu_to_be32(opt);
401- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
402+ if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) < 0) {
403 LOG("write failed (rep opt)");
404 return -EINVAL;
405 }
406 type = cpu_to_be32(type);
407- if (nbd_negotiate_write(ioc, &type, sizeof(type)) != sizeof(type)) {
408+ if (nbd_negotiate_write(ioc, &type, sizeof(type)) < 0) {
409 LOG("write failed (rep type)");
410 return -EINVAL;
411 }
412 len = cpu_to_be32(len);
413- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) {
414+ if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) {
415 LOG("write failed (rep data length)");
416 return -EINVAL;
417 }
418@@ -256,7 +255,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type,
419 if (ret < 0) {
420 goto out;
421 }
422- if (nbd_negotiate_write(ioc, msg, len) != len) {
423+ if (nbd_negotiate_write(ioc, msg, len) < 0) {
424 LOG("write failed (error message)");
425 ret = -EIO;
426 } else {
427@@ -287,15 +286,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp)
428 }
429
430 len = cpu_to_be32(name_len);
431- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) {
432+ if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) {
433 LOG("write failed (name length)");
434 return -EINVAL;
435 }
436- if (nbd_negotiate_write(ioc, name, name_len) != name_len) {
437+ if (nbd_negotiate_write(ioc, name, name_len) < 0) {
438 LOG("write failed (name buffer)");
439 return -EINVAL;
440 }
441- if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) {
442+ if (nbd_negotiate_write(ioc, desc, desc_len) < 0) {
443 LOG("write failed (description buffer)");
444 return -EINVAL;
445 }
446@@ -309,7 +308,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length)
447 NBDExport *exp;
448
449 if (length) {
450- if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
451+ if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
452 return -EIO;
453 }
454 return nbd_negotiate_send_rep_err(client->ioc,
455@@ -340,7 +339,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length)
456 LOG("Bad length received");
457 goto fail;
458 }
459- if (nbd_negotiate_read(client->ioc, name, length) != length) {
460+ if (nbd_negotiate_read(client->ioc, name, length) < 0) {
461 LOG("read failed");
462 goto fail;
463 }
464@@ -373,7 +372,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
465 TRACE("Setting up TLS");
466 ioc = client->ioc;
467 if (length) {
468- if (nbd_negotiate_drop_sync(ioc, length) != length) {
469+ if (nbd_negotiate_drop_sync(ioc, length) < 0) {
470 return NULL;
471 }
472 nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS,
473@@ -437,8 +436,7 @@ static int nbd_negotiate_options(NBDClient *client)
474 ... Rest of request
475 */
476
477- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) !=
478- sizeof(flags)) {
479+ if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) < 0) {
480 LOG("read failed");
481 return -EIO;
482 }
483@@ -464,8 +462,7 @@ static int nbd_negotiate_options(NBDClient *client)
484 uint32_t clientflags, length;
485 uint64_t magic;
486
487- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) !=
488- sizeof(magic)) {
489+ if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) < 0) {
490 LOG("read failed");
491 return -EINVAL;
492 }
493@@ -476,14 +473,14 @@ static int nbd_negotiate_options(NBDClient *client)
494 }
495
496 if (nbd_negotiate_read(client->ioc, &clientflags,
497- sizeof(clientflags)) != sizeof(clientflags)) {
498+ sizeof(clientflags)) < 0)
499+ {
500 LOG("read failed");
501 return -EINVAL;
502 }
503 clientflags = be32_to_cpu(clientflags);
504
505- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) !=
506- sizeof(length)) {
507+ if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) < 0) {
508 LOG("read failed");
509 return -EINVAL;
510 }
511@@ -513,7 +510,7 @@ static int nbd_negotiate_options(NBDClient *client)
512 return -EINVAL;
513
514 default:
515- if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
516+ if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
517 return -EIO;
518 }
519 ret = nbd_negotiate_send_rep_err(client->ioc,
520@@ -551,7 +548,7 @@ static int nbd_negotiate_options(NBDClient *client)
521 return nbd_negotiate_handle_export_name(client, length);
522
523 case NBD_OPT_STARTTLS:
524- if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
525+ if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
526 return -EIO;
527 }
528 if (client->tlscreds) {
529@@ -570,7 +567,7 @@ static int nbd_negotiate_options(NBDClient *client)
530 }
531 break;
532 default:
533- if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
534+ if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
535 return -EIO;
536 }
537 ret = nbd_negotiate_send_rep_err(client->ioc,
538@@ -659,12 +656,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
539 TRACE("TLS cannot be enabled with oldstyle protocol");
540 goto fail;
541 }
542- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) != sizeof(buf)) {
543+ if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) < 0) {
544 LOG("write failed");
545 goto fail;
546 }
547 } else {
548- if (nbd_negotiate_write(client->ioc, buf, 18) != 18) {
549+ if (nbd_negotiate_write(client->ioc, buf, 18) < 0) {
550 LOG("write failed");
551 goto fail;
552 }
553@@ -679,7 +676,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
554 stq_be_p(buf + 18, client->exp->size);
555 stw_be_p(buf + 26, client->exp->nbdflags | myflags);
556 len = client->no_zeroes ? 10 : sizeof(buf) - 18;
557- if (nbd_negotiate_write(client->ioc, buf + 18, len) != len) {
558+ if (nbd_negotiate_write(client->ioc, buf + 18, len) < 0) {
559 LOG("write failed");
560 goto fail;
561 }
562@@ -702,11 +699,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request)
563 return ret;
564 }
565
566- if (ret != sizeof(buf)) {
567- LOG("read failed");
568- return -EINVAL;
569- }
570-
571 /* Request
572 [ 0 .. 3] magic (NBD_REQUEST_MAGIC)
573 [ 4 .. 5] flags (NBD_CMD_FLAG_FUA, ...)
574@@ -737,7 +729,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request)
575 static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply)
576 {
577 uint8_t buf[NBD_REPLY_SIZE];
578- ssize_t ret;
579
580 reply->error = system_errno_to_nbd_errno(reply->error);
581
582@@ -754,16 +745,7 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply)
583 stl_be_p(buf + 4, reply->error);
584 stq_be_p(buf + 8, reply->handle);
585
586- ret = write_sync(ioc, buf, sizeof(buf));
587- if (ret < 0) {
588- return ret;
589- }
590-
591- if (ret != sizeof(buf)) {
592- LOG("writing to socket failed");
593- return -EINVAL;
594- }
595- return 0;
596+ return write_sync(ioc, buf, sizeof(buf));
597 }
598
599 #define MAX_NBD_REQUESTS 16
600@@ -1067,7 +1049,7 @@ static ssize_t nbd_co_send_reply(NBDRequestData *req, NBDReply *reply,
601 rc = nbd_send_reply(client->ioc, reply);
602 if (rc >= 0) {
603 ret = write_sync(client->ioc, req->data, len);
604- if (ret != len) {
605+ if (ret < 0) {
606 rc = -EIO;
607 }
608 }
609@@ -1141,7 +1123,7 @@ static ssize_t nbd_co_receive_request(NBDRequestData *req,
610 if (request->type == NBD_CMD_WRITE) {
611 TRACE("Reading %" PRIu32 " byte(s)", request->len);
612
613- if (read_sync(client->ioc, req->data, request->len) != request->len) {
614+ if (read_sync(client->ioc, req->data, request->len) < 0) {
615 LOG("reading from socket failed");
616 rc = -EIO;
617 goto out;
618--
6191.8.3.1
620