virtio-devices: block: Support multiple data descriptors

The Windows virtio block driver puts multiple data descriptors between
the header and the status footer. To handle this when parsing iterate
over the descriptor chain until the end is reached accumulating the
address and length pairs in a vector. For execution iterate over the
vector and make sequential reads from the disk for each data descriptor.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Rob Bradford
2020-09-14 14:02:04 +01:00
committed by Sebastien Boeuf
parent 5f6432830c
commit c03dbe8cc7
3 changed files with 96 additions and 83 deletions

View File

@@ -122,11 +122,15 @@ impl<T: DiskFile> BlockEpollHandler<T> {
len = l;
match request.request_type {
RequestType::In => {
read_bytes += Wrapping(request.data_len as u64);
for (_, data_len) in &request.data_descriptors {
read_bytes += Wrapping(*data_len as u64);
}
read_ops += Wrapping(1);
}
RequestType::Out => {
write_bytes += Wrapping(request.data_len as u64);
for (_, data_len) in &request.data_descriptors {
write_bytes += Wrapping(*data_len as u64);
}
write_ops += Wrapping(1);
}
_ => {}

View File

@@ -171,14 +171,18 @@ impl BlockIoUringEpollHandler {
let (status, len) = if result >= 0 {
match request.request_type {
RequestType::In => {
read_bytes += Wrapping(request.data_len as u64);
for (_, data_len) in &request.data_descriptors {
read_bytes += Wrapping(*data_len as u64);
}
read_ops += Wrapping(1);
}
RequestType::Out => {
if !request.writeback {
unsafe { libc::fsync(self.disk_image_fd) };
}
write_bytes += Wrapping(request.data_len as u64);
for (_, data_len) in &request.data_descriptors {
write_bytes += Wrapping(*data_len as u64);
}
write_ops += Wrapping(1);
}
_ => {}