mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: qcow: Test reopen finds no stranded clusters
After churning a single L2 region with an fsync per write, close and reopen the image. parse_qcow rebuilds the free list from the on disk refcounts, so a reopen that recovers many clusters means the runtime allocator stranded them. Without the fix the reopen recovered every relocated cluster. Now it finds none. Assisted-by: Claude:Opus-4.8 Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
8acefad893
commit
2ea2209920
@@ -547,6 +547,41 @@ mod unit_tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reopening rebuilds the free list from the on-disk refcounts. With the
|
||||||
|
// clusters tracked at runtime, a reopen must not discover a pile of them.
|
||||||
|
#[test]
|
||||||
|
fn reopen_discovers_no_stranded_clusters() {
|
||||||
|
const CL: u64 = 65536;
|
||||||
|
let virtual_size = 512 * 1024 * 1024;
|
||||||
|
let (temp, disk) = create_disk_with_data(virtual_size, &[], 0, false, false);
|
||||||
|
let n: u64 = 400;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
let pattern = vec![(i as u8).wrapping_add(1); CL as usize];
|
||||||
|
async_write(&disk, i * CL, &pattern);
|
||||||
|
async_fsync(&disk);
|
||||||
|
}
|
||||||
|
let tracked_before = disk.metadata().free_list_len();
|
||||||
|
|
||||||
|
drop(disk);
|
||||||
|
temp.as_file().sync_all().unwrap();
|
||||||
|
let disk = QcowDisk::new(
|
||||||
|
temp.as_file().try_clone().unwrap(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let tracked_after = disk.metadata().free_list_len();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
tracked_after <= tracked_before + 8,
|
||||||
|
"reopen recovered {} clusters the allocator had stranded",
|
||||||
|
tracked_after.saturating_sub(tracked_before),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_qcow_sync_rejects_out_of_bounds_allocated_l2_entry_on_read() {
|
fn test_qcow_sync_rejects_out_of_bounds_allocated_l2_entry_on_read() {
|
||||||
let data = vec![0x5a; 4096];
|
let data = vec![0x5a; 4096];
|
||||||
|
|||||||
Reference in New Issue
Block a user