mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: vhdx: Flatten internal and worker modules
Remove the internal and worker submodule layers from the VHDX format directory. The bat, header, io, and metadata parsers move up as direct children, internal/mod.rs becomes parser.rs, and the sync backend moves up as engine_sync.rs. The declaration only worker/mod.rs is dropped. The public types are surfaced at the vhdx module level, so callers use block::formats::vhdx instead of reaching into the internal module. Assisted-by: Claude:Opus-4.8 Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
6e0c39964a
commit
039b4e6013
@@ -14,17 +14,17 @@ use super::metadata::DiskSpec;
|
|||||||
use crate::aligned_file::AlignedFile;
|
use crate::aligned_file::AlignedFile;
|
||||||
|
|
||||||
// Payload BAT Entry States
|
// Payload BAT Entry States
|
||||||
pub const PAYLOAD_BLOCK_NOT_PRESENT: u64 = 0;
|
pub(super) const PAYLOAD_BLOCK_NOT_PRESENT: u64 = 0;
|
||||||
pub const PAYLOAD_BLOCK_UNDEFINED: u64 = 1;
|
pub(super) const PAYLOAD_BLOCK_UNDEFINED: u64 = 1;
|
||||||
pub const PAYLOAD_BLOCK_ZERO: u64 = 2;
|
pub(super) const PAYLOAD_BLOCK_ZERO: u64 = 2;
|
||||||
pub const PAYLOAD_BLOCK_UNMAPPED: u64 = 3;
|
pub(super) const PAYLOAD_BLOCK_UNMAPPED: u64 = 3;
|
||||||
pub const PAYLOAD_BLOCK_FULLY_PRESENT: u64 = 6;
|
pub(super) const PAYLOAD_BLOCK_FULLY_PRESENT: u64 = 6;
|
||||||
pub const PAYLOAD_BLOCK_PARTIALLY_PRESENT: u64 = 7;
|
pub(super) const PAYLOAD_BLOCK_PARTIALLY_PRESENT: u64 = 7;
|
||||||
|
|
||||||
// Mask for the BAT state
|
// Mask for the BAT state
|
||||||
pub const BAT_STATE_BIT_MASK: u64 = 0x07;
|
pub(super) const BAT_STATE_BIT_MASK: u64 = 0x07;
|
||||||
// Mask for the offset within the file in units of 1 MB
|
// Mask for the offset within the file in units of 1 MB
|
||||||
pub const BAT_FILE_OFF_MASK: u64 = 0xFFFFFFFFFFF00000;
|
pub(super) const BAT_FILE_OFF_MASK: u64 = 0xFFFFFFFFFFF00000;
|
||||||
|
|
||||||
#[sorted]
|
#[sorted]
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -39,14 +39,14 @@ pub enum VhdxBatError {
|
|||||||
WriteBat(#[source] io::Error),
|
WriteBat(#[source] io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, VhdxBatError>;
|
pub(super) type Result<T> = result::Result<T, VhdxBatError>;
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct BatEntry(pub u64);
|
pub(super) struct BatEntry(pub u64);
|
||||||
|
|
||||||
impl BatEntry {
|
impl BatEntry {
|
||||||
// Read all BAT entries presented on the disk and insert them to a vector
|
// Read all BAT entries presented on the disk and insert them to a vector
|
||||||
pub fn collect_bat_entries(
|
pub(super) fn collect_bat_entries(
|
||||||
f: &AlignedFile,
|
f: &AlignedFile,
|
||||||
disk_spec: &DiskSpec,
|
disk_spec: &DiskSpec,
|
||||||
bat_entry: &RegionTableEntry,
|
bat_entry: &RegionTableEntry,
|
||||||
@@ -79,7 +79,7 @@ impl BatEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Routine for writing BAT entries to the disk
|
// Routine for writing BAT entries to the disk
|
||||||
pub fn write_bat_entries(
|
pub(super) fn write_bat_entries(
|
||||||
f: &AlignedFile,
|
f: &AlignedFile,
|
||||||
bat_offset: u64,
|
bat_offset: u64,
|
||||||
bat_entries: &[BatEntry],
|
bat_entries: &[BatEntry],
|
||||||
@@ -11,9 +11,9 @@ use std::sync::{Arc, Mutex};
|
|||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult};
|
use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult};
|
||||||
use crate::formats::vhdx::internal::Vhdx;
|
use crate::formats::vhdx::Vhdx;
|
||||||
|
|
||||||
pub struct VhdxSync {
|
pub(super) struct VhdxSync {
|
||||||
vhdx_file: Arc<Mutex<Vhdx>>,
|
vhdx_file: Arc<Mutex<Vhdx>>,
|
||||||
eventfd: EventFd,
|
eventfd: EventFd,
|
||||||
completion_list: VecDeque<AsyncIoCompletion>,
|
completion_list: VecDeque<AsyncIoCompletion>,
|
||||||
@@ -21,7 +21,7 @@ pub struct VhdxSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VhdxSync {
|
impl VhdxSync {
|
||||||
pub fn new(vhdx_file: Arc<Mutex<Vhdx>>, size: u64) -> Self {
|
pub(super) fn new(vhdx_file: Arc<Mutex<Vhdx>>, size: u64) -> Self {
|
||||||
VhdxSync {
|
VhdxSync {
|
||||||
vhdx_file,
|
vhdx_file,
|
||||||
eventfd: EventFd::new(libc::EFD_NONBLOCK)
|
eventfd: EventFd::new(libc::EFD_NONBLOCK)
|
||||||
@@ -120,7 +120,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoOperation, OwnedIoBuffer};
|
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoOperation, OwnedIoBuffer};
|
||||||
use crate::formats::vhdx::internal::Vhdx;
|
use crate::formats::vhdx::Vhdx;
|
||||||
use crate::formats::vhdx::test_util::create_dynamic_vhdx;
|
use crate::formats::vhdx::test_util::create_dynamic_vhdx;
|
||||||
|
|
||||||
fn make_vhdx_sync(tf: &TempFile) -> (VhdxSync, u64) {
|
fn make_vhdx_sync(tf: &TempFile) -> (VhdxSync, u64) {
|
||||||
@@ -21,7 +21,7 @@ const REGION_SIGN: u32 = 0x6967_6572; // "regi"
|
|||||||
const FILE_START: u64 = 0; // The first element
|
const FILE_START: u64 = 0; // The first element
|
||||||
const HEADER_1_START: u64 = 64 * 1024; // Header 1 start in Bytes
|
const HEADER_1_START: u64 = 64 * 1024; // Header 1 start in Bytes
|
||||||
const HEADER_2_START: u64 = 128 * 1024; // Header 2 start in Bytes
|
const HEADER_2_START: u64 = 128 * 1024; // Header 2 start in Bytes
|
||||||
pub const REGION_TABLE_1_START: u64 = 192 * 1024; // Region 1 start in Bytes
|
pub(super) const REGION_TABLE_1_START: u64 = 192 * 1024; // Region 1 start in Bytes
|
||||||
const REGION_TABLE_2_START: u64 = 256 * 1024; // Region 2 start in Bytes
|
const REGION_TABLE_2_START: u64 = 256 * 1024; // Region 2 start in Bytes
|
||||||
|
|
||||||
const HEADER_SIZE: u64 = 4 * 1024; // Each header is 64 KiB, but only first 4 kiB contains info
|
const HEADER_SIZE: u64 = 4 * 1024; // Each header is 64 KiB, but only first 4 kiB contains info
|
||||||
@@ -84,16 +84,16 @@ pub enum VhdxHeaderError {
|
|||||||
WriteHeader(#[source] io::Error),
|
WriteHeader(#[source] io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, VhdxHeaderError>;
|
pub(super) type Result<T> = result::Result<T, VhdxHeaderError>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FileTypeIdentifier {
|
pub(super) struct FileTypeIdentifier {
|
||||||
pub _signature: u64,
|
pub _signature: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileTypeIdentifier {
|
impl FileTypeIdentifier {
|
||||||
/// Reads the File Type Identifier structure from a reference VHDx file
|
/// Reads the File Type Identifier structure from a reference VHDx file
|
||||||
pub fn new(f: &AlignedFile) -> Result<FileTypeIdentifier> {
|
pub(super) fn new(f: &AlignedFile) -> Result<FileTypeIdentifier> {
|
||||||
let mut buf = [0u8; size_of::<u64>()];
|
let mut buf = [0u8; size_of::<u64>()];
|
||||||
f.read_exact_at(&mut buf, FILE_START)
|
f.read_exact_at(&mut buf, FILE_START)
|
||||||
.map_err(VhdxHeaderError::ReadFileTypeIdentifier)?;
|
.map_err(VhdxHeaderError::ReadFileTypeIdentifier)?;
|
||||||
@@ -108,7 +108,7 @@ impl FileTypeIdentifier {
|
|||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Clone, Copy, Debug, FromBytes, Immutable, IntoBytes)]
|
#[derive(Clone, Copy, Debug, FromBytes, Immutable, IntoBytes)]
|
||||||
pub struct Header {
|
pub(super) struct Header {
|
||||||
pub signature: u32,
|
pub signature: u32,
|
||||||
pub checksum: u32,
|
pub checksum: u32,
|
||||||
pub sequence_number: u64,
|
pub sequence_number: u64,
|
||||||
@@ -123,7 +123,7 @@ pub struct Header {
|
|||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
/// Reads the Header structure from a reference VHDx file
|
/// Reads the Header structure from a reference VHDx file
|
||||||
pub fn new(f: &AlignedFile, start: u64) -> Result<Header> {
|
pub(super) fn new(f: &AlignedFile, start: u64) -> Result<Header> {
|
||||||
// Read the whole header into a buffer. We will need it for
|
// Read the whole header into a buffer. We will need it for
|
||||||
// calculating checksum.
|
// calculating checksum.
|
||||||
let mut buffer = [0; HEADER_SIZE as usize];
|
let mut buffer = [0; HEADER_SIZE as usize];
|
||||||
@@ -199,7 +199,7 @@ struct RegionTableHeader {
|
|||||||
|
|
||||||
impl RegionTableHeader {
|
impl RegionTableHeader {
|
||||||
/// Reads the Region Table Header structure from a reference VHDx file
|
/// Reads the Region Table Header structure from a reference VHDx file
|
||||||
pub fn new(f: &AlignedFile, start: u64) -> Result<RegionTableHeader> {
|
pub(crate) fn new(f: &AlignedFile, start: u64) -> Result<RegionTableHeader> {
|
||||||
// Read the whole header into a buffer. We will need it for calculating
|
// Read the whole header into a buffer. We will need it for calculating
|
||||||
// checksum.
|
// checksum.
|
||||||
let mut buffer = [0u8; REGION_SIZE as usize];
|
let mut buffer = [0u8; REGION_SIZE as usize];
|
||||||
@@ -234,7 +234,7 @@ fn ranges_overlap(a_start: u64, a_end: u64, b_start: u64, b_end: u64) -> bool {
|
|||||||
a_start < b_end && b_start < a_end
|
a_start < b_end && b_start < a_end
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RegionInfo {
|
pub(super) struct RegionInfo {
|
||||||
pub bat_entry: RegionTableEntry,
|
pub bat_entry: RegionTableEntry,
|
||||||
pub mdr_entry: RegionTableEntry,
|
pub mdr_entry: RegionTableEntry,
|
||||||
pub region_entries: BTreeMap<u64, u64>,
|
pub region_entries: BTreeMap<u64, u64>,
|
||||||
@@ -243,7 +243,7 @@ pub struct RegionInfo {
|
|||||||
impl RegionInfo {
|
impl RegionInfo {
|
||||||
/// Collect all entries in a BTreeMap from the Region Table and identifies
|
/// Collect all entries in a BTreeMap from the Region Table and identifies
|
||||||
/// BAT and metadata regions
|
/// BAT and metadata regions
|
||||||
pub fn new(f: &AlignedFile, region_start: u64, entry_count: u32) -> Result<RegionInfo> {
|
pub(super) fn new(f: &AlignedFile, region_start: u64, entry_count: u32) -> Result<RegionInfo> {
|
||||||
let mut bat_entry: Option<RegionTableEntry> = None;
|
let mut bat_entry: Option<RegionTableEntry> = None;
|
||||||
let mut mdr_entry: Option<RegionTableEntry> = None;
|
let mut mdr_entry: Option<RegionTableEntry> = None;
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ impl RegionInfo {
|
|||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Clone, Copy, Debug, FromBytes)]
|
#[derive(Clone, Copy, Debug, FromBytes)]
|
||||||
pub struct RegionTableEntry {
|
pub(super) struct RegionTableEntry {
|
||||||
guid: [u8; 16],
|
guid: [u8; 16],
|
||||||
pub file_offset: u64,
|
pub file_offset: u64,
|
||||||
pub length: u32,
|
pub length: u32,
|
||||||
@@ -335,7 +335,7 @@ enum HeaderNo {
|
|||||||
|
|
||||||
/// Contains the information from the header of a VHDx file
|
/// Contains the information from the header of a VHDx file
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct VhdxHeader {
|
pub(super) struct VhdxHeader {
|
||||||
_file_type_identifier: FileTypeIdentifier,
|
_file_type_identifier: FileTypeIdentifier,
|
||||||
header_1: Header,
|
header_1: Header,
|
||||||
header_2: Header,
|
header_2: Header,
|
||||||
@@ -345,7 +345,7 @@ pub struct VhdxHeader {
|
|||||||
|
|
||||||
impl VhdxHeader {
|
impl VhdxHeader {
|
||||||
/// Creates a VhdxHeader from a reference to a file
|
/// Creates a VhdxHeader from a reference to a file
|
||||||
pub fn new(f: &AlignedFile) -> Result<VhdxHeader> {
|
pub(super) fn new(f: &AlignedFile) -> Result<VhdxHeader> {
|
||||||
Ok(VhdxHeader {
|
Ok(VhdxHeader {
|
||||||
_file_type_identifier: FileTypeIdentifier::new(f)?,
|
_file_type_identifier: FileTypeIdentifier::new(f)?,
|
||||||
header_1: Header::new(f, HEADER_1_START)?,
|
header_1: Header::new(f, HEADER_1_START)?,
|
||||||
@@ -415,14 +415,14 @@ impl VhdxHeader {
|
|||||||
VhdxHeader::update_header(f, Ok(header_1), Ok(header_2), guid)
|
VhdxHeader::update_header(f, Ok(header_1), Ok(header_2), guid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, f: &AlignedFile) -> Result<()> {
|
pub(super) fn update(&mut self, f: &AlignedFile) -> Result<()> {
|
||||||
let headers = VhdxHeader::update_headers(f, Ok(self.header_1), Ok(self.header_2), 0)?;
|
let headers = VhdxHeader::update_headers(f, Ok(self.header_1), Ok(self.header_2), 0)?;
|
||||||
self.header_1 = headers.0;
|
self.header_1 = headers.0;
|
||||||
self.header_2 = headers.1;
|
self.header_2 = headers.1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn region_entry_count(&self) -> u32 {
|
pub(super) fn region_entry_count(&self) -> u32 {
|
||||||
self.region_table_1.entry_count
|
self.region_table_1.entry_count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ pub enum VhdxIoError {
|
|||||||
WriteBat(#[source] VhdxBatError),
|
WriteBat(#[source] VhdxBatError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, VhdxIoError>;
|
pub(super) type Result<T> = result::Result<T, VhdxIoError>;
|
||||||
|
|
||||||
macro_rules! align {
|
macro_rules! align {
|
||||||
($n:expr, $align:expr) => {{ $n.div_ceil($align) * $align }};
|
($n:expr, $align:expr) => {{ $n.div_ceil($align) * $align }};
|
||||||
@@ -51,7 +51,7 @@ struct Sector {
|
|||||||
impl Sector {
|
impl Sector {
|
||||||
/// Translate sector index and count of data in file to actual offsets and
|
/// Translate sector index and count of data in file to actual offsets and
|
||||||
/// BAT index.
|
/// BAT index.
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
disk_spec: &DiskSpec,
|
disk_spec: &DiskSpec,
|
||||||
bat: &[BatEntry],
|
bat: &[BatEntry],
|
||||||
sector_index: u64,
|
sector_index: u64,
|
||||||
@@ -86,7 +86,7 @@ impl Sector {
|
|||||||
|
|
||||||
/// VHDx IO read routine: requires relative sector index and count for the
|
/// VHDx IO read routine: requires relative sector index and count for the
|
||||||
/// requested data.
|
/// requested data.
|
||||||
pub fn read(
|
pub(super) fn read(
|
||||||
f: &AlignedFile,
|
f: &AlignedFile,
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
disk_spec: &DiskSpec,
|
disk_spec: &DiskSpec,
|
||||||
@@ -138,7 +138,7 @@ pub fn read(
|
|||||||
|
|
||||||
/// VHDx IO write routine: requires relative sector index and count for the
|
/// VHDx IO write routine: requires relative sector index and count for the
|
||||||
/// requested data.
|
/// requested data.
|
||||||
pub fn write(
|
pub(super) fn write(
|
||||||
f: &AlignedFile,
|
f: &AlignedFile,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
disk_spec: &mut DiskSpec,
|
disk_spec: &mut DiskSpec,
|
||||||
@@ -21,7 +21,7 @@ const METADATA_TABLE_MAX_SIZE: usize = METADATA_ENTRY_SIZE * (METADATA_MAX_ENTRI
|
|||||||
|
|
||||||
const METADATA_FLAGS_IS_REQUIRED: u32 = 0x04;
|
const METADATA_FLAGS_IS_REQUIRED: u32 = 0x04;
|
||||||
|
|
||||||
pub const BLOCK_SIZE_MIN: u32 = 1 << 20; // 1 MiB
|
pub(super) const BLOCK_SIZE_MIN: u32 = 1 << 20; // 1 MiB
|
||||||
const BLOCK_SIZE_MAX: u32 = 256 << 20; // 256 MiB
|
const BLOCK_SIZE_MAX: u32 = 256 << 20; // 256 MiB
|
||||||
const MAX_SECTORS_PER_BLOCK: u64 = 1 << 23;
|
const MAX_SECTORS_PER_BLOCK: u64 = 1 << 23;
|
||||||
|
|
||||||
@@ -93,10 +93,10 @@ pub enum VhdxMetadataError {
|
|||||||
UnsupportedFlag,
|
UnsupportedFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, VhdxMetadataError>;
|
pub(super) type Result<T> = result::Result<T, VhdxMetadataError>;
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct DiskSpec {
|
pub(super) struct DiskSpec {
|
||||||
pub disk_id: u128,
|
pub disk_id: u128,
|
||||||
pub image_size: u64,
|
pub image_size: u64,
|
||||||
pub block_size: u32,
|
pub block_size: u32,
|
||||||
@@ -112,7 +112,7 @@ pub struct DiskSpec {
|
|||||||
impl DiskSpec {
|
impl DiskSpec {
|
||||||
/// Parse all metadata from the provided file and store info in DiskSpec
|
/// Parse all metadata from the provided file and store info in DiskSpec
|
||||||
/// structure.
|
/// structure.
|
||||||
pub fn new(f: &AlignedFile, metadata_region: &RegionTableEntry) -> Result<DiskSpec> {
|
pub(super) fn new(f: &AlignedFile, metadata_region: &RegionTableEntry) -> Result<DiskSpec> {
|
||||||
let mut disk_spec = DiskSpec::default();
|
let mut disk_spec = DiskSpec::default();
|
||||||
let mut metadata_presence: u16 = 0;
|
let mut metadata_presence: u16 = 0;
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
@@ -270,7 +270,7 @@ struct MetadataTableHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MetadataTableHeader {
|
impl MetadataTableHeader {
|
||||||
pub fn new(buffer: &[u8]) -> Result<MetadataTableHeader> {
|
pub(crate) fn new(buffer: &[u8]) -> Result<MetadataTableHeader> {
|
||||||
let metadata_table_header = MetadataTableHeader::read_from_bytes(buffer).unwrap();
|
let metadata_table_header = MetadataTableHeader::read_from_bytes(buffer).unwrap();
|
||||||
|
|
||||||
if metadata_table_header.signature != METADATA_SIGN {
|
if metadata_table_header.signature != METADATA_SIGN {
|
||||||
@@ -291,7 +291,7 @@ impl MetadataTableHeader {
|
|||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Default, Debug, Clone, Copy, FromBytes)]
|
#[derive(Default, Debug, Clone, Copy, FromBytes)]
|
||||||
pub struct MetadataTableEntry {
|
pub(super) struct MetadataTableEntry {
|
||||||
item_id: [u8; 16],
|
item_id: [u8; 16],
|
||||||
offset: u32,
|
offset: u32,
|
||||||
length: u32,
|
length: u32,
|
||||||
@@ -9,19 +9,23 @@
|
|||||||
//! Provides [`VhdxDisk`], the `DiskFile` wrapper for dynamic VHDX
|
//! Provides [`VhdxDisk`], the `DiskFile` wrapper for dynamic VHDX
|
||||||
//! images.
|
//! images.
|
||||||
|
|
||||||
pub mod internal;
|
mod bat;
|
||||||
|
mod engine_sync;
|
||||||
|
mod header;
|
||||||
|
mod io;
|
||||||
|
mod metadata;
|
||||||
|
mod parser;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod test_util;
|
mod test_util;
|
||||||
pub(crate) mod worker;
|
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io::Error as IoError;
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub use internal::{Vhdx, VhdxError};
|
pub use parser::{Vhdx, VhdxError};
|
||||||
|
|
||||||
use self::worker::sync::VhdxSync;
|
use self::engine_sync::VhdxSync;
|
||||||
use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError};
|
use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError};
|
||||||
use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp};
|
use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp};
|
||||||
use crate::{Error, disk_file};
|
use crate::{Error, disk_file};
|
||||||
@@ -92,7 +96,7 @@ impl disk_file::Resizable for VhdxDisk {
|
|||||||
fn resize(&mut self, _size: u64) -> BlockResult<()> {
|
fn resize(&mut self, _size: u64) -> BlockResult<()> {
|
||||||
Err(BlockError::new(
|
Err(BlockError::new(
|
||||||
BlockErrorKind::UnsupportedFeature,
|
BlockErrorKind::UnsupportedFeature,
|
||||||
DiskFileError::ResizeError(io::Error::other("resize not supported for VHDX")),
|
DiskFileError::ResizeError(IoError::other("resize not supported for VHDX")),
|
||||||
)
|
)
|
||||||
.with_op(ErrorOp::Resize))
|
.with_op(ErrorOp::Resize))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,17 +13,12 @@ use std::result;
|
|||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use self::bat::{BatEntry, VhdxBatError};
|
use super::bat::{BatEntry, VhdxBatError};
|
||||||
use self::header::{RegionInfo, RegionTableEntry, VhdxHeader, VhdxHeaderError};
|
use super::header::{self, RegionInfo, RegionTableEntry, VhdxHeader, VhdxHeaderError};
|
||||||
use self::io::VhdxIoError;
|
use super::io::{self, VhdxIoError};
|
||||||
use self::metadata::{DiskSpec, VhdxMetadataError};
|
use super::metadata::{DiskSpec, VhdxMetadataError};
|
||||||
use crate::aligned_file::AlignedFile;
|
use crate::aligned_file::AlignedFile;
|
||||||
|
|
||||||
mod bat;
|
|
||||||
mod header;
|
|
||||||
mod io;
|
|
||||||
mod metadata;
|
|
||||||
|
|
||||||
#[sorted]
|
#[sorted]
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum VhdxError {
|
pub enum VhdxError {
|
||||||
@@ -43,7 +38,7 @@ pub enum VhdxError {
|
|||||||
WriteFailed(#[source] VhdxIoError),
|
WriteFailed(#[source] VhdxIoError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, VhdxError>;
|
pub(super) type Result<T> = result::Result<T, VhdxError>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Vhdx {
|
pub struct Vhdx {
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// Copyright 2026 The Cloud Hypervisor Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
//! Sync I/O worker for VHDX images.
|
|
||||||
|
|
||||||
pub(crate) mod sync;
|
|
||||||
Reference in New Issue
Block a user