disk: android_sparse: fix into_inner bug

If a guest cycled the virtio-blk on and off (e.g. activate, reset,
activate), then android-sparse files would start to be treated like raw
files.

BUG=b:266440668,b:219595052

Change-Id: I9ca00668ba7a7c820a177309edf320426feba81a
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4195519
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Auto-Submit: Frederick Mayle <fmayle@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Frederick Mayle 2023-01-25 19:36:18 -08:00 committed by crosvm LUCI
parent 0594273d26
commit 32321cfa54

View file

@ -352,7 +352,11 @@ impl FileAllocate for AsyncAndroidSparse {
#[async_trait(?Send)]
impl AsyncDisk for AsyncAndroidSparse {
fn into_inner(self: Box<Self>) -> Box<dyn DiskFile> {
Box::new(self.inner.into_source())
Box::new(AndroidSparse {
file: self.inner.into_source(),
total_size: self.total_size,
chunks: self.chunks,
})
}
async fn fsync(&self) -> DiskResult<()> {
@ -899,4 +903,25 @@ mod tests {
})
.unwrap();
}
// Convert to sync and back again. There was once a bug where `into_inner` converted the
// AndroidSparse into a raw file.
//
// Skip on windows because `into_source` isn't supported.
#[cfg(not(windows))]
#[test]
fn async_roundtrip_read_dontcare() {
let ex = Executor::new().unwrap();
ex.run_until(async {
let chunks = vec![ChunkWithSize {
chunk: Chunk::DontCare,
expanded_size: 100,
}];
let image = test_async_image(chunks, &ex).unwrap();
let image = image.into_inner().to_async_disk(&ex).unwrap();
let buf = read_exact_at(&*image, 0, 100).await;
assert!(buf.iter().all(|x| *x == 0));
})
.unwrap();
}
}