mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: qcow: Add pread_alloc and decompress_cluster helpers
Add two reusable helpers for the compressed cluster read path: - pread_alloc(fd, offset, len) allocates a buffer and fills it with pread_exact, returning the owned Vec. - decompress_cluster(compressed, cluster_size, decoder) allocates the output buffer, decodes via the Decoder trait, and validates that the decoder produced exactly cluster_size bytes. These will be used by QcowSync, QcowAsync, Qcow2Backing, and the legacy QcowFile. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
78a05ab0c1
commit
d9b188c1be
@@ -5,7 +5,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
pub(crate) mod backing;
|
||||
mod decoder;
|
||||
pub(crate) mod decoder;
|
||||
mod header;
|
||||
pub(crate) mod metadata;
|
||||
pub(crate) mod qcow_raw_file;
|
||||
|
||||
@@ -14,6 +14,8 @@ use std::cmp::min;
|
||||
use std::os::fd::RawFd;
|
||||
use std::{io, ptr, slice};
|
||||
|
||||
use crate::qcow::decoder::Decoder;
|
||||
|
||||
// -- Position independent I/O helpers --
|
||||
//
|
||||
// Duplicated file descriptors share the kernel file description and thus the
|
||||
@@ -44,6 +46,33 @@ pub fn pread_exact(fd: RawFd, buf: &mut [u8], offset: u64) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocate a buffer and pread exactly `len` bytes at `offset`.
|
||||
pub fn pread_alloc(fd: RawFd, offset: u64, len: usize) -> io::Result<Vec<u8>> {
|
||||
let mut buf = vec![0u8; len];
|
||||
pread_exact(fd, &mut buf, offset)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// Decompress a full QCOW2 cluster from compressed data.
|
||||
///
|
||||
/// Returns a `cluster_size` byte buffer with the decompressed cluster
|
||||
/// content. Fails if the decoder does not produce exactly `cluster_size`
|
||||
/// bytes.
|
||||
pub fn decompress_cluster(
|
||||
compressed: &[u8],
|
||||
cluster_size: usize,
|
||||
decoder: &dyn Decoder,
|
||||
) -> io::Result<Vec<u8>> {
|
||||
let mut decompressed = vec![0u8; cluster_size];
|
||||
let n = decoder
|
||||
.decode(compressed, &mut decompressed)
|
||||
.map_err(|_| io::Error::from_raw_os_error(libc::EIO))?;
|
||||
if n != cluster_size {
|
||||
return Err(io::Error::from_raw_os_error(libc::EIO));
|
||||
}
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
/// Write all bytes to fd at offset, looping on short writes.
|
||||
pub fn pwrite_all(fd: RawFd, buf: &[u8], offset: u64) -> io::Result<()> {
|
||||
let mut total = 0usize;
|
||||
|
||||
Reference in New Issue
Block a user