mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: Use RawDisk in factory, remove old wrappers
Update open_raw to construct RawDisk instead of choosing between RawFileDisk, RawFileDiskSync and RawFileDiskAio. The backend decision is now made inside RawDisk::create_async_io. Remove the DiskFile wrapper structs from raw_sync.rs, raw_async.rs and raw_async_aio.rs. Only the AsyncIo worker structs remain in those files. Reduce their module visibility to pub(crate). Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
@@ -16,6 +16,8 @@ use std::{fmt, fs};
|
||||
|
||||
use log::info;
|
||||
|
||||
#[cfg(feature = "io_uring")]
|
||||
use crate::block_io_uring_is_supported;
|
||||
use crate::disk_file::AsyncFullDiskFile;
|
||||
use crate::error::{BlockError, BlockErrorKind, BlockResult};
|
||||
#[cfg(feature = "io_uring")]
|
||||
@@ -24,14 +26,11 @@ use crate::fixed_vhd_sync::FixedVhdDiskSync;
|
||||
#[cfg(feature = "io_uring")]
|
||||
use crate::qcow_async::QcowDiskAsync;
|
||||
use crate::qcow_sync::QcowDiskSync;
|
||||
use crate::raw_async_aio::RawFileDiskAio;
|
||||
use crate::raw_sync::RawFileDiskSync;
|
||||
use crate::raw_disk::{RawBackend, RawDisk};
|
||||
use crate::vhdx_sync::VhdxDiskSync;
|
||||
use crate::{
|
||||
ImageType, block_aio_is_supported, detect_image_type, open_disk_image, preallocate_disk,
|
||||
};
|
||||
#[cfg(feature = "io_uring")]
|
||||
use crate::{block_io_uring_is_supported, raw_async::RawFileDisk};
|
||||
|
||||
/// Options for opening a disk image via [`open_disk`].
|
||||
pub struct DiskOpenOptions<'a> {
|
||||
@@ -156,7 +155,7 @@ fn open_raw(
|
||||
if !options.disable_io_uring {
|
||||
if io_uring_supported() {
|
||||
info!("Opening RAW disk file with io_uring backend");
|
||||
return Ok(Box::new(RawFileDisk::new(file)));
|
||||
return Ok(Box::new(RawDisk::new(file, RawBackend::IoUring)));
|
||||
}
|
||||
info!("io_uring runtime probe failed for RAW, trying next backend");
|
||||
}
|
||||
@@ -164,13 +163,13 @@ fn open_raw(
|
||||
if !options.disable_aio {
|
||||
if aio_supported() {
|
||||
info!("Opening RAW disk file with AIO backend");
|
||||
return Ok(Box::new(RawFileDiskAio::new(file)));
|
||||
return Ok(Box::new(RawDisk::new(file, RawBackend::Aio)));
|
||||
}
|
||||
info!("AIO runtime probe failed for RAW, using synchronous backend");
|
||||
}
|
||||
|
||||
info!("Opening RAW disk file with synchronous backend");
|
||||
Ok(Box::new(RawFileDiskSync::new(file)))
|
||||
Ok(Box::new(RawDisk::new(file, RawBackend::Sync)))
|
||||
}
|
||||
|
||||
fn open_qcow2(
|
||||
|
||||
@@ -24,15 +24,12 @@ pub mod qcow_async;
|
||||
pub(crate) mod qcow_common;
|
||||
pub mod qcow_sync;
|
||||
#[cfg(feature = "io_uring")]
|
||||
/// Async primitives based on `io-uring`
|
||||
///
|
||||
/// Enabled with the `"io_uring"` feature
|
||||
pub mod raw_async;
|
||||
pub mod raw_async_aio;
|
||||
pub(crate) mod raw_async;
|
||||
pub(crate) mod raw_async_aio;
|
||||
#[cfg(test)]
|
||||
mod raw_async_io_tests;
|
||||
pub mod raw_disk;
|
||||
pub mod raw_sync;
|
||||
pub(crate) mod raw_sync;
|
||||
mod request;
|
||||
pub mod vhd;
|
||||
pub mod vhdx;
|
||||
|
||||
@@ -2,118 +2,16 @@
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{self, Error};
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
use std::io::Error;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
use io_uring::{IoUring, opcode, types};
|
||||
use libc::{FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, FALLOC_FL_ZERO_RANGE};
|
||||
use log::warn;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFileError};
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
||||
use crate::error::{BlockError, BlockErrorKind, BlockResult};
|
||||
use crate::{
|
||||
BatchRequest, DiskTopology, RequestType, SECTOR_SIZE, disk_file, probe_sparse_support,
|
||||
query_device_size,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawFileDisk {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl RawFileDisk {
|
||||
pub fn new(file: File) -> Self {
|
||||
RawFileDisk { file }
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskSize for RawFileDisk {
|
||||
fn logical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(logical_size, _)| logical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::PhysicalSize for RawFileDisk {
|
||||
fn physical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(_, physical_size)| physical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFd for RawFileDisk {
|
||||
fn fd(&self) -> BorrowedDiskFd<'_> {
|
||||
BorrowedDiskFd::new(self.file.as_raw_fd())
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Geometry for RawFileDisk {
|
||||
fn topology(&self) -> DiskTopology {
|
||||
DiskTopology::probe(&self.file).unwrap_or_else(|_| {
|
||||
warn!("Unable to get device topology. Using default topology");
|
||||
DiskTopology::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::SparseCapable for RawFileDisk {
|
||||
fn supports_sparse_operations(&self) -> bool {
|
||||
probe_sparse_support(&self.file)
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Resizable for RawFileDisk {
|
||||
fn resize(&mut self, size: u64) -> BlockResult<()> {
|
||||
let fd_metadata = self
|
||||
.file
|
||||
.metadata()
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::ResizeError(e)))?;
|
||||
|
||||
if fd_metadata.file_type().is_block_device() {
|
||||
// Block devices cannot be resized via ftruncate - they are resized
|
||||
// externally (LVM, losetup -c, etc.). Verify the size matches.
|
||||
let (actual_size, _) = query_device_size(&self.file)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::ResizeError(e)))?;
|
||||
if actual_size != size {
|
||||
return Err(BlockError::new(
|
||||
BlockErrorKind::Io,
|
||||
DiskFileError::ResizeError(io::Error::other(format!(
|
||||
"Block device size {actual_size} does not match requested size {size}"
|
||||
))),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
self.file
|
||||
.set_len(size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::ResizeError(e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFile for RawFileDisk {}
|
||||
|
||||
impl disk_file::AsyncDiskFile for RawFileDisk {
|
||||
fn try_clone(&self) -> BlockResult<Box<dyn disk_file::AsyncDiskFile>> {
|
||||
let file = self
|
||||
.file
|
||||
.try_clone()
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Clone(e)))?;
|
||||
Ok(Box::new(RawFileDisk { file }))
|
||||
}
|
||||
|
||||
fn create_async_io(&self, ring_depth: u32) -> BlockResult<Box<dyn AsyncIo>> {
|
||||
let mut raw = RawFileAsync::new(self.file.as_raw_fd(), ring_depth)?;
|
||||
raw.alignment =
|
||||
DiskTopology::probe(&self.file).map_or(SECTOR_SIZE, |t| t.logical_block_size);
|
||||
Ok(Box::new(raw) as Box<dyn AsyncIo>)
|
||||
}
|
||||
}
|
||||
use crate::{BatchRequest, RequestType, SECTOR_SIZE};
|
||||
|
||||
pub struct RawFileAsync {
|
||||
fd: RawFd,
|
||||
|
||||
@@ -6,92 +6,15 @@
|
||||
//
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
use libc::{FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, FALLOC_FL_ZERO_RANGE};
|
||||
use log::warn;
|
||||
use vmm_sys_util::aio;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFileError};
|
||||
use crate::SECTOR_SIZE;
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
||||
use crate::error::{BlockError, BlockErrorKind, BlockResult};
|
||||
use crate::{DiskTopology, SECTOR_SIZE, disk_file, probe_sparse_support, query_device_size};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawFileDiskAio {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl RawFileDiskAio {
|
||||
pub fn new(file: File) -> Self {
|
||||
RawFileDiskAio { file }
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskSize for RawFileDiskAio {
|
||||
fn logical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(logical_size, _)| logical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::PhysicalSize for RawFileDiskAio {
|
||||
fn physical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(_, physical_size)| physical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFd for RawFileDiskAio {
|
||||
fn fd(&self) -> BorrowedDiskFd<'_> {
|
||||
BorrowedDiskFd::new(self.file.as_raw_fd())
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Geometry for RawFileDiskAio {
|
||||
fn topology(&self) -> DiskTopology {
|
||||
DiskTopology::probe(&self.file).unwrap_or_else(|_| {
|
||||
warn!("Unable to get device topology. Using default topology");
|
||||
DiskTopology::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::SparseCapable for RawFileDiskAio {
|
||||
fn supports_sparse_operations(&self) -> bool {
|
||||
probe_sparse_support(&self.file)
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Resizable for RawFileDiskAio {
|
||||
fn resize(&mut self, size: u64) -> BlockResult<()> {
|
||||
self.file
|
||||
.set_len(size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::ResizeError(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFile for RawFileDiskAio {}
|
||||
|
||||
impl disk_file::AsyncDiskFile for RawFileDiskAio {
|
||||
fn try_clone(&self) -> BlockResult<Box<dyn disk_file::AsyncDiskFile>> {
|
||||
let file = self
|
||||
.file
|
||||
.try_clone()
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Clone(e)))?;
|
||||
Ok(Box::new(RawFileDiskAio { file }))
|
||||
}
|
||||
|
||||
fn create_async_io(&self, ring_depth: u32) -> BlockResult<Box<dyn AsyncIo>> {
|
||||
let mut raw = RawFileAsyncAio::new(self.file.as_raw_fd(), ring_depth)?;
|
||||
raw.alignment =
|
||||
DiskTopology::probe(&self.file).map_or(SECTOR_SIZE, |t| t.logical_block_size);
|
||||
Ok(Box::new(raw) as Box<dyn AsyncIo>)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RawFileAsyncAio {
|
||||
fd: RawFd,
|
||||
|
||||
@@ -3,91 +3,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
use libc::{FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, FALLOC_FL_ZERO_RANGE};
|
||||
use log::warn;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFileError};
|
||||
use crate::error::{BlockError, BlockErrorKind, BlockResult};
|
||||
use crate::{DiskTopology, SECTOR_SIZE, disk_file, probe_sparse_support, query_device_size};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawFileDiskSync {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl RawFileDiskSync {
|
||||
pub fn new(file: File) -> Self {
|
||||
RawFileDiskSync { file }
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskSize for RawFileDiskSync {
|
||||
fn logical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(logical_size, _)| logical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::PhysicalSize for RawFileDiskSync {
|
||||
fn physical_size(&self) -> BlockResult<u64> {
|
||||
query_device_size(&self.file)
|
||||
.map(|(_, physical_size)| physical_size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Size(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFd for RawFileDiskSync {
|
||||
fn fd(&self) -> BorrowedDiskFd<'_> {
|
||||
BorrowedDiskFd::new(self.file.as_raw_fd())
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Geometry for RawFileDiskSync {
|
||||
fn topology(&self) -> DiskTopology {
|
||||
DiskTopology::probe(&self.file).unwrap_or_else(|_| {
|
||||
warn!("Unable to get device topology. Using default topology");
|
||||
DiskTopology::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::SparseCapable for RawFileDiskSync {
|
||||
fn supports_sparse_operations(&self) -> bool {
|
||||
probe_sparse_support(&self.file)
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::Resizable for RawFileDiskSync {
|
||||
fn resize(&mut self, size: u64) -> BlockResult<()> {
|
||||
self.file
|
||||
.set_len(size)
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::ResizeError(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl disk_file::DiskFile for RawFileDiskSync {}
|
||||
|
||||
impl disk_file::AsyncDiskFile for RawFileDiskSync {
|
||||
fn try_clone(&self) -> BlockResult<Box<dyn disk_file::AsyncDiskFile>> {
|
||||
let file = self
|
||||
.file
|
||||
.try_clone()
|
||||
.map_err(|e| BlockError::new(BlockErrorKind::Io, DiskFileError::Clone(e)))?;
|
||||
Ok(Box::new(RawFileDiskSync { file }))
|
||||
}
|
||||
|
||||
fn create_async_io(&self, _ring_depth: u32) -> BlockResult<Box<dyn AsyncIo>> {
|
||||
let mut raw = RawFileSync::new(self.file.as_raw_fd());
|
||||
raw.alignment =
|
||||
DiskTopology::probe(&self.file).map_or(SECTOR_SIZE, |t| t.logical_block_size);
|
||||
Ok(Box::new(raw) as Box<dyn AsyncIo>)
|
||||
}
|
||||
}
|
||||
use crate::SECTOR_SIZE;
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
||||
|
||||
pub struct RawFileSync {
|
||||
fd: RawFd,
|
||||
|
||||
Reference in New Issue
Block a user