mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
nbd/server: fix sparse read
In case of io error in nbd_co_send_sparse_read we should not "goto reply:", as it was a fatal error and the common behavior is to disconnect in this case. We should not try to send the client an additional error reply, since we already hit a channel-io error on our previous attempt to send one. Fix this by handling block-status error in nbd_co_send_sparse_read, so nbd_co_send_sparse_read fails only on io error. Then just skip common "reply:" code path in nbd_trip. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20180308184636.178534-3-vsementsov@virtuozzo.com> [eblake: grammar tweaks] Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
60ace2bacf
commit
37e02aebf8
1 changed files with 14 additions and 3 deletions
17
nbd/server.c
17
nbd/server.c
|
@ -1366,6 +1366,10 @@ static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
|
||||||
return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
|
return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do a sparse read and send the structured reply to the client.
|
||||||
|
* Returns -errno if sending fails. bdrv_block_status_above() failure is
|
||||||
|
* reported to the client, at which point this function succeeds.
|
||||||
|
*/
|
||||||
static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
|
static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
|
||||||
uint64_t handle,
|
uint64_t handle,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
|
@ -1386,8 +1390,13 @@ static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
|
||||||
bool final;
|
bool final;
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
error_setg_errno(errp, -status, "unable to check for holes");
|
char *msg = g_strdup_printf("unable to check for holes: %s",
|
||||||
return status;
|
strerror(-status));
|
||||||
|
|
||||||
|
ret = nbd_co_send_structured_error(client, handle, -status, msg,
|
||||||
|
errp);
|
||||||
|
g_free(msg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
assert(pnum && pnum <= size - progress);
|
assert(pnum && pnum <= size - progress);
|
||||||
final = progress + pnum == size;
|
final = progress + pnum == size;
|
||||||
|
@ -1568,7 +1577,7 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||||
request.from, req->data, request.len,
|
request.from, req->data, request.len,
|
||||||
&local_err);
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto reply;
|
goto replied;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1665,6 +1674,8 @@ reply:
|
||||||
req->data, reply_data_len, &local_err);
|
req->data, reply_data_len, &local_err);
|
||||||
}
|
}
|
||||||
g_free(msg);
|
g_free(msg);
|
||||||
|
|
||||||
|
replied:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_prepend(&local_err, "Failed to send reply: ");
|
error_prepend(&local_err, "Failed to send reply: ");
|
||||||
goto disconnect;
|
goto disconnect;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue