diff --git a/block/src/factory.rs b/block/src/factory.rs index 6d1de3664..d029952b7 100644 --- a/block/src/factory.rs +++ b/block/src/factory.rs @@ -127,7 +127,7 @@ fn open_fixed_vhd( if io_uring_supported() { info!("Opening fixed VHD disk file with io_uring backend"); return Ok(Box::new( - VhdDisk::new(file, true).map_err(|e| e.with_path(options.path))?, + VhdDisk::new(file, true, options.direct).map_err(|e| e.with_path(options.path))?, )); } info!("io_uring runtime probe failed for fixed VHD, using synchronous backend"); @@ -135,7 +135,7 @@ fn open_fixed_vhd( info!("Opening fixed VHD disk file with synchronous backend"); Ok(Box::new( - VhdDisk::new(file, false).map_err(|e| e.with_path(options.path))?, + VhdDisk::new(file, false, options.direct).map_err(|e| e.with_path(options.path))?, )) } diff --git a/block/src/formats/vhd/mod.rs b/block/src/formats/vhd/mod.rs index 71a42f451..d817f6c87 100644 --- a/block/src/formats/vhd/mod.rs +++ b/block/src/formats/vhd/mod.rs @@ -17,6 +17,7 @@ use std::io; use std::os::unix::io::AsRawFd; pub use internal::footer::is_fixed_vhd; +use log::warn; use self::internal::fixed::FixedVhd; #[cfg(feature = "io_uring")] @@ -25,16 +26,17 @@ use self::worker::sync::FixedVhdSync; use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError}; use crate::disk_file::DiskSize; use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp}; -use crate::{AlignedFile, BlockBackend, Error, disk_file}; +use crate::{AlignedFile, BlockBackend, DiskTopology, Error, disk_file}; #[derive(Debug)] pub struct VhdDisk { inner: FixedVhd, use_io_uring: bool, + direct: bool, } impl VhdDisk { - pub fn new(file: File, use_io_uring: bool) -> BlockResult { + pub fn new(file: File, use_io_uring: bool, direct: bool) -> BlockResult { #[cfg(not(feature = "io_uring"))] if use_io_uring { return Err(BlockError::new( @@ -48,6 +50,7 @@ impl VhdDisk { Ok(Self { inner: FixedVhd::new(file).map_err(|e| BlockError::from(e).with_op(ErrorOp::Open))?, use_io_uring, + direct, }) } } @@ -77,7 +80,14 @@ impl disk_file::DiskFd for VhdDisk { } } -impl disk_file::Geometry for VhdDisk {} +impl disk_file::Geometry for VhdDisk { + fn topology(&self) -> DiskTopology { + DiskTopology::probe(self.inner.file()).unwrap_or_else(|_| { + warn!("Unable to get device topology. Using default topology"); + DiskTopology::default() + }) + } +} impl disk_file::SparseCapable for VhdDisk {} @@ -98,6 +108,7 @@ impl disk_file::AsyncDiskFile for VhdDisk { Ok(Box::new(VhdDisk { inner: self.inner.clone(), use_io_uring: self.use_io_uring, + direct: self.direct, })) } @@ -106,7 +117,7 @@ impl disk_file::AsyncDiskFile for VhdDisk { let file = self.inner.file().try_clone().map_err(|e| { BlockError::new(BlockErrorKind::Io, DiskFileError::NewAsyncIo(e)).with_op(ErrorOp::Open) })?; - let raw_file = AlignedFile::new(file, false); + let raw_file = AlignedFile::new(file, self.direct); if self.use_io_uring { #[cfg(feature = "io_uring")] @@ -167,7 +178,7 @@ mod unit_tests { #[test] fn new_sync_returns_correct_size() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, false).unwrap(); + let disk = VhdDisk::new(file, false, false).unwrap(); assert_eq!(disk.logical_size().unwrap(), 0x1122_3344); } @@ -183,7 +194,7 @@ mod unit_tests { #[test] fn sync_backend_disables_batch_requests() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, false).unwrap(); + let disk = VhdDisk::new(file, false, false).unwrap(); assert_async_io(&disk, false); } @@ -191,7 +202,7 @@ mod unit_tests { #[test] fn io_uring_backend_enables_batch_requests() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, true).unwrap(); + let disk = VhdDisk::new(file, true, false).unwrap(); assert_async_io(&disk, true); } @@ -287,7 +298,7 @@ mod unit_tests { #[test] fn try_clone_preserves_sync_dispatch() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, false).unwrap(); + let disk = VhdDisk::new(file, false, false).unwrap(); let cloned = disk.try_clone().unwrap(); assert_async_io_from_dyn(cloned.as_ref(), false); } @@ -296,7 +307,7 @@ mod unit_tests { #[test] fn try_clone_preserves_io_uring_dispatch() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, true).unwrap(); + let disk = VhdDisk::new(file, true, false).unwrap(); let cloned = disk.try_clone().unwrap(); assert_async_io_from_dyn(cloned.as_ref(), true); } @@ -304,14 +315,14 @@ mod unit_tests { #[test] fn resize_returns_error() { let file = make_vhd_file(); - let mut disk = VhdDisk::new(file, false).unwrap(); + let mut disk = VhdDisk::new(file, false, false).unwrap(); assert!(disk.resize(0x2000_0000).is_err()); } #[test] fn physical_size_includes_footer() { let file = make_vhd_file(); - let disk = VhdDisk::new(file, false).unwrap(); + let disk = VhdDisk::new(file, false, false).unwrap(); // Data region (0x1122_3344) + VHD footer (0x200). assert_eq!(disk.physical_size().unwrap(), 0x1122_3344 + 0x200); }