mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-21 07:21:15 +00:00
Relying on the simplified version of the synchronous support for RAW disk files, the new fixed_vhd_sync module in the block_util crate introduces the synchronous support for fixed VHD disk files. With this patch, the fixed VHD support is complete as it is implemented in both synchronous and asynchronous versions. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
108 lines
2.7 KiB
Rust
108 lines
2.7 KiB
Rust
// Copyright © 2021 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::async_io::{
|
|
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
|
|
};
|
|
use crate::raw_sync::RawFileSync;
|
|
use crate::vhd::VhdFooter;
|
|
use std::fs::File;
|
|
use std::os::unix::io::{AsRawFd, RawFd};
|
|
use vmm_sys_util::eventfd::EventFd;
|
|
|
|
pub struct FixedVhdDiskSync {
|
|
file: File,
|
|
size: u64,
|
|
}
|
|
|
|
impl FixedVhdDiskSync {
|
|
pub fn new(mut file: File) -> std::io::Result<Self> {
|
|
let footer = VhdFooter::new(&mut file)?;
|
|
|
|
Ok(FixedVhdDiskSync {
|
|
file,
|
|
size: footer.current_size(),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl DiskFile for FixedVhdDiskSync {
|
|
fn size(&mut self) -> DiskFileResult<u64> {
|
|
Ok(self.size)
|
|
}
|
|
|
|
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
|
|
Ok(Box::new(
|
|
FixedVhdSync::new(self.file.as_raw_fd(), self.size)
|
|
.map_err(DiskFileError::NewAsyncIo)?,
|
|
) as Box<dyn AsyncIo>)
|
|
}
|
|
}
|
|
|
|
pub struct FixedVhdSync {
|
|
raw_file_sync: RawFileSync,
|
|
size: u64,
|
|
}
|
|
|
|
impl FixedVhdSync {
|
|
pub fn new(fd: RawFd, size: u64) -> std::io::Result<Self> {
|
|
Ok(FixedVhdSync {
|
|
raw_file_sync: RawFileSync::new(fd),
|
|
size,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl AsyncIo for FixedVhdSync {
|
|
fn notifier(&self) -> &EventFd {
|
|
self.raw_file_sync.notifier()
|
|
}
|
|
|
|
fn read_vectored(
|
|
&mut self,
|
|
offset: libc::off_t,
|
|
iovecs: Vec<libc::iovec>,
|
|
user_data: u64,
|
|
) -> AsyncIoResult<()> {
|
|
if offset as u64 >= self.size {
|
|
return Err(AsyncIoError::ReadVectored(std::io::Error::new(
|
|
std::io::ErrorKind::InvalidData,
|
|
format!(
|
|
"Invalid offset {}, can't be larger than file size {}",
|
|
offset, self.size
|
|
),
|
|
)));
|
|
}
|
|
|
|
self.raw_file_sync.read_vectored(offset, iovecs, user_data)
|
|
}
|
|
|
|
fn write_vectored(
|
|
&mut self,
|
|
offset: libc::off_t,
|
|
iovecs: Vec<libc::iovec>,
|
|
user_data: u64,
|
|
) -> AsyncIoResult<()> {
|
|
if offset as u64 >= self.size {
|
|
return Err(AsyncIoError::WriteVectored(std::io::Error::new(
|
|
std::io::ErrorKind::InvalidData,
|
|
format!(
|
|
"Invalid offset {}, can't be larger than file size {}",
|
|
offset, self.size
|
|
),
|
|
)));
|
|
}
|
|
|
|
self.raw_file_sync.write_vectored(offset, iovecs, user_data)
|
|
}
|
|
|
|
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
|
|
self.raw_file_sync.fsync(user_data)
|
|
}
|
|
|
|
fn complete(&mut self) -> Vec<(u64, i32)> {
|
|
self.raw_file_sync.complete()
|
|
}
|
|
}
|