aboutsummaryrefslogtreecommitdiff
path: root/block/nbd-client.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2019-02-18 14:56:01 +0100
committerKevin Wolf <kwolf@redhat.com>2019-02-25 15:03:19 +0100
commitd3bd5b90890f6715bcee38e00745112157dfbe59 (patch)
tree3f712b4e248b6902231e755db75cb49ef80e41a5 /block/nbd-client.c
parenta7b78fc944b20b953d68426b7db2c81fc6a5b5af (diff)
nbd: Use low-level QIOChannel API in nbd_read_eof()
Instead of using the convenience wrapper qio_channel_read_all_eof(), use the lower level QIOChannel API. This means duplicating some code, but we'll need this because this coroutine yield is special: We want it to be interruptible so that nbd_client_attach_aio_context() can correctly reenter the coroutine. This moves the bdrv_dec/inc_in_flight() pair into nbd_read_eof(), so that connection_co will always sit in this exact qio_channel_yield() call when bdrv_drain() returns. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'block/nbd-client.c')
-rw-r--r--block/nbd-client.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 5ce4aa9520..60f38f0320 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -84,15 +84,9 @@ static coroutine_fn void nbd_connection_entry(void *opaque)
*
* Therefore we keep an additional in_flight reference all the time and
* only drop it temporarily here.
- *
- * FIXME This is not safe because the QIOChannel could wake up the
- * coroutine for a second time; it is not prepared for coroutine
- * resumption from external code.
*/
- bdrv_dec_in_flight(s->bs);
assert(s->reply.handle == 0);
- ret = nbd_receive_reply(s->ioc, &s->reply, &local_err);
- bdrv_inc_in_flight(s->bs);
+ ret = nbd_receive_reply(s->bs, s->ioc, &s->reply, &local_err);
if (local_err) {
trace_nbd_read_reply_entry_fail(ret, error_get_pretty(local_err));