Before this change, buffers returned from virFDStreamRead() would
alternate in size (262120 and 24), because it only consumed the
bytes remaining from the current background thread message.
As the background thread reads 262144 bytes (256kB) of data in
each chunk, where the maximum size returned from virFDStreamRead()
to be transferred over the remote protocol is only 262120, 24 bytes
would be left in the buffer on each iteration. The next iteration
leaves 24 bytes, which used to be returned without considering
messages waiting in the queue.
Signed-off-by: Erik Huelsmann <[email protected]>
---
src/util/virfdstream.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c
index 26a1f00..4c974ba 100644
--- a/src/util/virfdstream.c
+++ b/src/util/virfdstream.c
@@ -905,7 +905,10 @@ static int virFDStreamRead(virStreamPtr st, char
*bytes, size_t nbytes)
if (fdst->thread) {
virFDStreamMsg *msg = NULL;
+ size_t got = 0;
+ size_t bsz = 0;
+ more:
while (!(msg = fdst->msg)) {
if (fdst->threadQuit || fdst->threadErr) {
if (nbytes) {
@@ -917,7 +920,7 @@ static int virFDStreamRead(virStreamPtr st, char
*bytes, size_t nbytes)
virReportSystemError(EBADF, "%s",
_("stream is not open"));
} else {
- ret = 0;
+ ret = got;
}
goto cleanup;
} else {
@@ -931,7 +934,7 @@ static int virFDStreamRead(virStreamPtr st, char
*bytes, size_t nbytes)
* return 0 immediately. */
if (msg->type == VIR_FDSTREAM_MSG_TYPE_HOLE &&
msg->stream.hole.len == 0) {
- ret = 0;
+ ret = got;
goto cleanup;
}
@@ -942,21 +945,26 @@ static int virFDStreamRead(virStreamPtr st, char
*bytes, size_t nbytes)
goto cleanup;
}
- if (nbytes > msg->stream.data.len - msg->stream.data.offset)
- nbytes = msg->stream.data.len - msg->stream.data.offset;
+ bsz = msg->stream.data.len - msg->stream.data.offset;
+ if (nbytes < bsz)
+ bsz = nbytes;
- memcpy(bytes,
+ memcpy(bytes + got,
msg->stream.data.buf + msg->stream.data.offset,
- nbytes);
+ bsz);
+ got += bsz;
+ nbytes -= bsz;
- msg->stream.data.offset += nbytes;
+ msg->stream.data.offset += bsz;
if (msg->stream.data.offset == msg->stream.data.len) {
virFDStreamMsgQueuePop(fdst, fdst->fd, "pipe");
virFDStreamMsgFree(msg);
}
- ret = nbytes;
-
+ ret = got;
+ if (nbytes > 0) {
+ goto more;
+ }
} else {
retry:
ret = read(fdst->fd, bytes, nbytes);
--
2.43.0