Skip to content

Commit 8e74e7d

Browse files
Manciukicbchalios
authored andcommitted
fix(iovec): do not return error if some bytes were written
When reading from a volatile memory into a WriteVolatile we should let the caller know if we managed to transfer some bytes. Currently, if the write encounters any error after the first iovec an error is returned, but some bytes are written. This causes issues in the caller, because it thinks no bytes were written. In particular, this caused a bug in the vsock code on 6.17 guest kernels because these kernels started sending multiple iovecs. When sending 2 iovecs, it could happen that we'd get a WouldBlock error on the second, but the vsock code thought no bytes were transferre, leading to a spurious retransmission of the first iovec. Fixes: #5475 Signed-off-by: Riccardo Mancini <mancio@amazon.com>
1 parent a174746 commit 8e74e7d

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

src/vmm/src/devices/virtio/iovec.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,23 +192,25 @@ impl IoVecBuffer {
192192
slice = slice.subslice(0, len)?;
193193
}
194194

195-
let bytes_read = loop {
195+
match loop {
196196
match dst.write_volatile(&slice) {
197197
Err(VolatileMemoryError::IOError(err))
198-
if err.kind() == ErrorKind::Interrupted =>
199-
{
200-
continue;
201-
}
202-
Ok(bytes_read) => break bytes_read,
203-
Err(volatile_memory_error) => return Err(volatile_memory_error),
198+
if err.kind() == ErrorKind::Interrupted => {}
199+
result => break result,
204200
}
205-
};
206-
total_bytes_read += bytes_read;
201+
} {
202+
Ok(bytes_read) => {
203+
total_bytes_read += bytes_read;
207204

208-
if bytes_read < slice.len() {
209-
break;
205+
if bytes_read < slice.len() {
206+
break;
207+
}
208+
len -= bytes_read;
209+
}
210+
// exit successfully if we previously managed to write some bytes
211+
Err(_) if total_bytes_read > 0 => break,
212+
Err(err) => return Err(err),
210213
}
211-
len -= bytes_read;
212214
}
213215

214216
Ok(total_bytes_read)

0 commit comments

Comments
 (0)