aboutsummaryrefslogtreecommitdiff
path: root/nbd
diff options
context:
space:
mode:
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>2018-03-08 21:46:34 +0300
committerEric Blake <eblake@redhat.com>2018-03-13 15:38:55 -0500
commita0d7ce20a94ba66e1d9577429a62d133f1cd19cf (patch)
treeedd22e2e0c4e8952dd8b7e65f7461bdc9ba4d0c1 /nbd
parent37e02aebf88f8a12f02457de207b09b607c1e8a8 (diff)
downloadqemu-a0d7ce20a94ba66e1d9577429a62d133f1cd19cf.zip
qemu-a0d7ce20a94ba66e1d9577429a62d133f1cd19cf.tar.gz
qemu-a0d7ce20a94ba66e1d9577429a62d133f1cd19cf.tar.bz2
nbd/server: fix: check client->closing before sending reply
Since the unchanged code has just set client->recv_coroutine to NULL before calling nbd_client_receive_next_request(), we are spawning a new coroutine unconditionally, but the first thing that coroutine will do is check for client->closing, making it a no-op if we have already detected that the client is going away. Furthermore, for any error other than EIO (where we disconnect, which itself sets client->closing), if the client has already gone away, we'll probably encounter EIO later in the function and attempt disconnect at that point. Logically, as soon as we know the connection is closing, there is no need to try a likely-to-fail a response or spawn a no-op coroutine. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20180308184636.178534-4-vsementsov@virtuozzo.com> Reviewed-by: Eric Blake <eblake@redhat.com> [eblake: squash in further reordering: hoist check before spawning next coroutine, and document rationale in commit message] Signed-off-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'nbd')
-rw-r--r--nbd/server.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/nbd/server.c b/nbd/server.c
index 5f29206..b230ecb 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1543,14 +1543,6 @@ static coroutine_fn void nbd_trip(void *opaque)
req = nbd_request_get(client);
ret = nbd_co_receive_request(req, &request, &local_err);
client->recv_coroutine = NULL;
- nbd_client_receive_next_request(client);
- if (ret == -EIO) {
- goto disconnect;
- }
-
- if (ret < 0) {
- goto reply;
- }
if (client->closing) {
/*
@@ -1560,6 +1552,15 @@ static coroutine_fn void nbd_trip(void *opaque)
goto done;
}
+ nbd_client_receive_next_request(client);
+ if (ret == -EIO) {
+ goto disconnect;
+ }
+
+ if (ret < 0) {
+ goto reply;
+ }
+
switch (request.type) {
case NBD_CMD_READ:
/* XXX: NBD Protocol only documents use of FUA with WRITE */