mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: qcow: Add multi iovec read/write test
Exercise scatter/gather with multiple iovecs per operation, covering both the standard and direct_io paths. Write uses 3 iovecs with distinct patterns, read uses 3 iovecs with different sizes, then reassembles and compares. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
b62525f792
commit
7fd5e74f0e
@@ -1636,4 +1636,87 @@ mod unit_tests {
|
||||
"size should be unchanged after failed resize"
|
||||
);
|
||||
}
|
||||
|
||||
fn test_multi_iovec_read_write_impl(direct_io: bool) {
|
||||
// Exercise scatter/gather with multiple iovecs per operation.
|
||||
let (_temp, disk) = create_disk_with_data(100 * 1024 * 1024, &[], 0, true, direct_io);
|
||||
|
||||
// Write: 3 iovecs with distinct patterns
|
||||
let a = vec![0xAAu8; 16 * 1024];
|
||||
let b = vec![0xBBu8; 32 * 1024];
|
||||
let c = vec![0xCCu8; 16 * 1024];
|
||||
let iovecs_w = [
|
||||
libc::iovec {
|
||||
iov_base: a.as_ptr() as *mut libc::c_void,
|
||||
iov_len: a.len(),
|
||||
},
|
||||
libc::iovec {
|
||||
iov_base: b.as_ptr() as *mut libc::c_void,
|
||||
iov_len: b.len(),
|
||||
},
|
||||
libc::iovec {
|
||||
iov_base: c.as_ptr() as *mut libc::c_void,
|
||||
iov_len: c.len(),
|
||||
},
|
||||
];
|
||||
let total = a.len() + b.len() + c.len();
|
||||
|
||||
let mut aio = disk.new_async_io(1).unwrap();
|
||||
aio.write_vectored(0, &iovecs_w, 1).unwrap();
|
||||
let (ud, res) = aio.next_completed_request().unwrap();
|
||||
assert_eq!(ud, 1);
|
||||
assert_eq!(res as usize, total);
|
||||
aio.fsync(Some(2)).unwrap();
|
||||
drop(aio);
|
||||
|
||||
// Read back into 3 iovecs of different sizes
|
||||
let mut r1 = vec![0u8; 8 * 1024];
|
||||
let mut r2 = vec![0u8; 48 * 1024];
|
||||
let mut r3 = vec![0u8; 8 * 1024];
|
||||
let iovecs_r = [
|
||||
libc::iovec {
|
||||
iov_base: r1.as_mut_ptr() as *mut libc::c_void,
|
||||
iov_len: r1.len(),
|
||||
},
|
||||
libc::iovec {
|
||||
iov_base: r2.as_mut_ptr() as *mut libc::c_void,
|
||||
iov_len: r2.len(),
|
||||
},
|
||||
libc::iovec {
|
||||
iov_base: r3.as_mut_ptr() as *mut libc::c_void,
|
||||
iov_len: r3.len(),
|
||||
},
|
||||
];
|
||||
|
||||
let mut aio = disk.new_async_io(1).unwrap();
|
||||
aio.read_vectored(0, &iovecs_r, 10).unwrap();
|
||||
let (ud, res) = aio.next_completed_request().unwrap();
|
||||
assert_eq!(ud, 10);
|
||||
assert_eq!(res as usize, total);
|
||||
drop(aio);
|
||||
|
||||
// Reassemble the read buffers into a flat vec
|
||||
let mut got = Vec::with_capacity(total);
|
||||
got.extend_from_slice(&r1);
|
||||
got.extend_from_slice(&r2);
|
||||
got.extend_from_slice(&r3);
|
||||
|
||||
// Build expected from the write buffers
|
||||
let mut expected = Vec::with_capacity(total);
|
||||
expected.extend_from_slice(&a);
|
||||
expected.extend_from_slice(&b);
|
||||
expected.extend_from_slice(&c);
|
||||
|
||||
assert_eq!(got, expected, "Multi iovec read should match written data");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_iovec_read_write() {
|
||||
test_multi_iovec_read_write_impl(false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_iovec_read_write_direct_io() {
|
||||
test_multi_iovec_read_write_impl(true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user