block: Move VHD format files into formats/vhd/

Move VHD format implementation into a structured directory layout:

  fixed_vhd.rs       -> formats/vhd/internal/fixed.rs     (FixedVhd)
  fixed_vhd_disk.rs  -> formats/vhd/mod.rs                (VhdDisk)
  vhd.rs             -> formats/vhd/internal/footer.rs     (VhdFooter)
  fixed_vhd_sync.rs  -> formats/vhd/worker/sync.rs         (FixedVhdSync)
  fixed_vhd_async.rs -> formats/vhd/worker/async_uring.rs  (FixedVhdAsync)

Add #[allow(dead_code)] to VhdFooter struct and impl because the
module is now pub(crate) and the compiler can see that several
fields and getters are only exercised by unit tests. Re-export
formats::vhd as fixed_vhd_disk in lib.rs for backward
compatibility with external consumers.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-04-24 23:44:30 +02:00
committed by Rob Bradford
parent a11f551572
commit 1ca0c39b4d
10 changed files with 46 additions and 14 deletions

View File

@@ -20,8 +20,8 @@ use log::info;
use crate::block_io_uring_is_supported;
use crate::disk_file::AsyncFullDiskFile;
use crate::error::{BlockError, BlockErrorKind, BlockResult};
use crate::fixed_vhd_disk::VhdDisk;
use crate::formats::raw::{RawBackend, RawDisk};
use crate::formats::vhd::VhdDisk;
use crate::qcow_disk::QcowDisk;
use crate::vhdx_sync::VhdxDisk;
use crate::{

View File

@@ -8,3 +8,4 @@
//! format specific internals, and sync/async I/O workers.
pub mod raw;
pub mod vhd;

View File

@@ -6,8 +6,8 @@ use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write};
use std::os::unix::io::{AsRawFd, RawFd};
use super::footer::VhdFooter;
use crate::BlockBackend;
use crate::vhd::VhdFooter;
#[derive(Debug)]
pub struct FixedVhd {

View File

@@ -7,7 +7,11 @@ use std::io::{Seek, SeekFrom};
use crate::{DiskTopology, read_aligned_block_size};
// Production code uses: cookie, file_format_version, data_offset,
// current_size, disk_type. The remaining fields are parsed for VHD
// spec completeness and exercised only by unit tests.
#[derive(Clone, Copy)]
#[allow(dead_code)]
pub struct VhdFooter {
cookie: u64,
features: u32,
@@ -26,6 +30,7 @@ pub struct VhdFooter {
saved_state: u8,
}
#[allow(dead_code)]
impl VhdFooter {
pub fn new(file: &mut File) -> std::io::Result<VhdFooter> {
let blocksize = DiskTopology::probe(file)?.logical_block_size as usize;

View File

@@ -0,0 +1,11 @@
// Copyright 2026 The Cloud Hypervisor Authors. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//! VHD format parsing and data structures.
//!
//! Contains the footer parser and the low level fixed VHD
//! block backend.
pub(crate) mod fixed;
pub(crate) mod footer;

View File

@@ -4,17 +4,27 @@
//
// SPDX-License-Identifier: Apache-2.0
//! Fixed VHD disk image format.
//!
//! Provides [`VhdDisk`], the `DiskFile` wrapper for fixed size VHD
//! images.
pub(crate) mod internal;
pub(crate) mod worker;
use std::fs::File;
use std::io;
use std::os::unix::io::AsRawFd;
pub use internal::footer::is_fixed_vhd;
use self::internal::fixed::FixedVhd;
#[cfg(feature = "io_uring")]
use self::worker::async_uring::FixedVhdAsync;
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::fixed_vhd::FixedVhd;
#[cfg(feature = "io_uring")]
use crate::fixed_vhd_async::FixedVhdAsync;
use crate::fixed_vhd_sync::FixedVhdSync;
use crate::{BlockBackend, Error, disk_file};
#[derive(Debug)]

View File

@@ -0,0 +1,12 @@
// Copyright 2026 The Cloud Hypervisor Authors. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//! Sync/async I/O workers for fixed VHD images.
//!
//! Thin wrappers around the raw workers that clamp I/O to the
//! virtual disk size.
#[cfg(feature = "io_uring")]
pub(crate) mod async_uring;
pub(crate) mod sync;

View File

@@ -14,12 +14,6 @@ pub mod factory;
#[path = "io/mod.rs"]
mod io_impl;
pub use io_impl::{async_io, fcntl, request};
pub mod fixed_vhd;
#[cfg(feature = "io_uring")]
/// Enabled with the `"io_uring"` feature
pub mod fixed_vhd_async;
pub mod fixed_vhd_disk;
pub mod fixed_vhd_sync;
pub mod formats;
pub mod qcow;
#[cfg(feature = "io_uring")]
@@ -29,7 +23,6 @@ pub mod qcow_disk;
pub(crate) mod qcow_sync;
mod sparse;
pub use formats::raw as raw_disk;
pub mod vhd;
pub mod vhdx;
pub mod vhdx_sync;
@@ -521,7 +514,7 @@ pub fn detect_image_type(f: &mut File) -> BlockResult<ImageType> {
// Check 4 first bytes to get the header value and determine the image type
let image_type = if u32::from_be_bytes(block[0..4].try_into().unwrap()) == QCOW_MAGIC {
ImageType::Qcow2
} else if vhd::is_fixed_vhd(f)
} else if formats::vhd::is_fixed_vhd(f)
.map_err(|e| BlockError::new(BlockErrorKind::Io, e).with_op(ErrorOp::DetectImageType))?
{
ImageType::FixedVhd