mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 11:25:20 +00:00
block_util: Simplify RAW synchronous implementation
Using directly preadv and pwritev, we can simply use a RawFd instead of a file, and we don't need to use the more complex implementation from the qcow crate. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
b2e5dbaecb
commit
c6854c5a97
@ -2,54 +2,49 @@
|
|||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||||
|
|
||||||
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileResult};
|
use crate::async_io::{
|
||||||
use crate::{disk_size, fsync_sync, read_vectored_sync, write_vectored_sync};
|
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
|
||||||
use qcow::RawFile;
|
};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::io::{Seek, SeekFrom};
|
||||||
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
pub struct RawFileDiskSync {
|
pub struct RawFileDiskSync {
|
||||||
raw_file: RawFile,
|
file: File,
|
||||||
semaphore: Arc<Mutex<()>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawFileDiskSync {
|
impl RawFileDiskSync {
|
||||||
pub fn new(file: File, direct_io: bool) -> Self {
|
pub fn new(file: File) -> Self {
|
||||||
RawFileDiskSync {
|
RawFileDiskSync { file }
|
||||||
raw_file: RawFile::new(file, direct_io),
|
|
||||||
semaphore: Arc::new(Mutex::new(())),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiskFile for RawFileDiskSync {
|
impl DiskFile for RawFileDiskSync {
|
||||||
fn size(&mut self) -> DiskFileResult<u64> {
|
fn size(&mut self) -> DiskFileResult<u64> {
|
||||||
disk_size(&mut self.raw_file, &mut self.semaphore)
|
Ok(self
|
||||||
|
.file
|
||||||
|
.seek(SeekFrom::End(0))
|
||||||
|
.map_err(DiskFileError::Size)? as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
|
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
|
||||||
Ok(Box::new(RawFileSync::new(
|
Ok(Box::new(RawFileSync::new(self.file.as_raw_fd())) as Box<dyn AsyncIo>)
|
||||||
self.raw_file.clone(),
|
|
||||||
self.semaphore.clone(),
|
|
||||||
)) as Box<dyn AsyncIo>)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RawFileSync {
|
pub struct RawFileSync {
|
||||||
raw_file: RawFile,
|
fd: RawFd,
|
||||||
eventfd: EventFd,
|
eventfd: EventFd,
|
||||||
completion_list: Vec<(u64, i32)>,
|
completion_list: Vec<(u64, i32)>,
|
||||||
semaphore: Arc<Mutex<()>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawFileSync {
|
impl RawFileSync {
|
||||||
pub fn new(raw_file: RawFile, semaphore: Arc<Mutex<()>>) -> Self {
|
pub fn new(fd: RawFd) -> Self {
|
||||||
RawFileSync {
|
RawFileSync {
|
||||||
raw_file,
|
fd,
|
||||||
eventfd: EventFd::new(libc::EFD_NONBLOCK).expect("Failed creating EventFd for RawFile"),
|
eventfd: EventFd::new(libc::EFD_NONBLOCK).expect("Failed creating EventFd for RawFile"),
|
||||||
completion_list: Vec::new(),
|
completion_list: Vec::new(),
|
||||||
semaphore,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,15 +60,22 @@ impl AsyncIo for RawFileSync {
|
|||||||
iovecs: Vec<libc::iovec>,
|
iovecs: Vec<libc::iovec>,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
) -> AsyncIoResult<()> {
|
) -> AsyncIoResult<()> {
|
||||||
read_vectored_sync(
|
let result = unsafe {
|
||||||
offset,
|
libc::preadv(
|
||||||
iovecs,
|
self.fd as libc::c_int,
|
||||||
user_data,
|
iovecs.as_ptr() as *const libc::iovec,
|
||||||
&mut self.raw_file,
|
iovecs.len() as libc::c_int,
|
||||||
&self.eventfd,
|
offset,
|
||||||
&mut self.completion_list,
|
)
|
||||||
&mut self.semaphore,
|
};
|
||||||
)
|
if result < 0 {
|
||||||
|
return Err(AsyncIoError::ReadVectored(std::io::Error::last_os_error()));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.completion_list.push((user_data, result as i32));
|
||||||
|
self.eventfd.write(1).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_vectored(
|
fn write_vectored(
|
||||||
@ -82,25 +84,36 @@ impl AsyncIo for RawFileSync {
|
|||||||
iovecs: Vec<libc::iovec>,
|
iovecs: Vec<libc::iovec>,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
) -> AsyncIoResult<()> {
|
) -> AsyncIoResult<()> {
|
||||||
write_vectored_sync(
|
let result = unsafe {
|
||||||
offset,
|
libc::pwritev(
|
||||||
iovecs,
|
self.fd as libc::c_int,
|
||||||
user_data,
|
iovecs.as_ptr() as *const libc::iovec,
|
||||||
&mut self.raw_file,
|
iovecs.len() as libc::c_int,
|
||||||
&self.eventfd,
|
offset,
|
||||||
&mut self.completion_list,
|
)
|
||||||
&mut self.semaphore,
|
};
|
||||||
)
|
if result < 0 {
|
||||||
|
return Err(AsyncIoError::WriteVectored(std::io::Error::last_os_error()));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.completion_list.push((user_data, result as i32));
|
||||||
|
self.eventfd.write(1).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
|
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
|
||||||
fsync_sync(
|
let result = unsafe { libc::fsync(self.fd as libc::c_int) };
|
||||||
user_data,
|
if result < 0 {
|
||||||
&mut self.raw_file,
|
return Err(AsyncIoError::Fsync(std::io::Error::last_os_error()));
|
||||||
&self.eventfd,
|
}
|
||||||
&mut self.completion_list,
|
|
||||||
&mut self.semaphore,
|
if let Some(user_data) = user_data {
|
||||||
)
|
self.completion_list.push((user_data, result as i32));
|
||||||
|
self.eventfd.write(1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complete(&mut self) -> Vec<(u64, i32)> {
|
fn complete(&mut self) -> Vec<(u64, i32)> {
|
||||||
|
@ -106,6 +106,8 @@ fn virtio_block_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
|
|||||||
allow_syscall(libc::SYS_openat),
|
allow_syscall(libc::SYS_openat),
|
||||||
allow_syscall(libc::SYS_prctl),
|
allow_syscall(libc::SYS_prctl),
|
||||||
allow_syscall(libc::SYS_pread64),
|
allow_syscall(libc::SYS_pread64),
|
||||||
|
allow_syscall(libc::SYS_preadv),
|
||||||
|
allow_syscall(libc::SYS_pwritev),
|
||||||
allow_syscall(libc::SYS_read),
|
allow_syscall(libc::SYS_read),
|
||||||
allow_syscall(libc::SYS_rt_sigprocmask),
|
allow_syscall(libc::SYS_rt_sigprocmask),
|
||||||
allow_syscall(libc::SYS_sched_getaffinity),
|
allow_syscall(libc::SYS_sched_getaffinity),
|
||||||
|
@ -1686,7 +1686,7 @@ impl DeviceManager {
|
|||||||
Box::new(RawFileDisk::new(file)) as Box<dyn DiskFile>
|
Box::new(RawFileDisk::new(file)) as Box<dyn DiskFile>
|
||||||
} else {
|
} else {
|
||||||
info!("Using synchronous RAW disk file");
|
info!("Using synchronous RAW disk file");
|
||||||
Box::new(RawFileDiskSync::new(file, disk_cfg.direct)) as Box<dyn DiskFile>
|
Box::new(RawFileDiskSync::new(file)) as Box<dyn DiskFile>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImageType::Qcow2 => {
|
ImageType::Qcow2 => {
|
||||||
|
@ -344,8 +344,10 @@ fn vmm_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
|
|||||||
allow_syscall(libc::SYS_pipe2),
|
allow_syscall(libc::SYS_pipe2),
|
||||||
allow_syscall(libc::SYS_prctl),
|
allow_syscall(libc::SYS_prctl),
|
||||||
allow_syscall(libc::SYS_pread64),
|
allow_syscall(libc::SYS_pread64),
|
||||||
|
allow_syscall(libc::SYS_preadv),
|
||||||
allow_syscall(libc::SYS_prlimit64),
|
allow_syscall(libc::SYS_prlimit64),
|
||||||
allow_syscall(libc::SYS_pwrite64),
|
allow_syscall(libc::SYS_pwrite64),
|
||||||
|
allow_syscall(libc::SYS_pwritev),
|
||||||
allow_syscall(libc::SYS_read),
|
allow_syscall(libc::SYS_read),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
allow_syscall(libc::SYS_readlink),
|
allow_syscall(libc::SYS_readlink),
|
||||||
|
Loading…
Reference in New Issue
Block a user