// 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 { let footer = VhdFooter::new(&mut file)?; Ok(FixedVhdDiskSync { file, size: footer.current_size(), }) } } impl DiskFile for FixedVhdDiskSync { fn size(&mut self) -> DiskFileResult { Ok(self.size) } fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult> { Ok(Box::new( FixedVhdSync::new(self.file.as_raw_fd(), self.size) .map_err(DiskFileError::NewAsyncIo)?, ) as Box) } } pub struct FixedVhdSync { raw_file_sync: RawFileSync, size: u64, } impl FixedVhdSync { pub fn new(fd: RawFd, size: u64) -> std::io::Result { 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, 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, 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) -> AsyncIoResult<()> { self.raw_file_sync.fsync(user_data) } fn complete(&mut self) -> Vec<(u64, i32)> { self.raw_file_sync.complete() } }