block: Move QCOW2 format files into formats/qcow/

Move QCOW2 format implementation into a structured directory layout:

  qcow/              -> formats/qcow/internal/  (filenames unchanged)
  qcow_disk.rs       -> formats/qcow/mod.rs               (QcowDisk)
  qcow_sync.rs       -> formats/qcow/worker/sync.rs       (QcowSync)
  qcow_async.rs      -> formats/qcow/worker/async_uring.rs (QcowAsync)
  qcow_common.rs     -> formats/qcow/common.rs

All internal cross references continue to resolve through
re-exports in lib.rs: formats::qcow::internal as qcow,
formats::qcow as qcow_disk, and
formats::qcow::common as qcow_common.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-04-25 14:43:56 +02:00
committed by Rob Bradford
parent b595f1dbc3
commit 25afb8898c
19 changed files with 71 additions and 53 deletions

View File

@@ -20,10 +20,10 @@ use log::info;
use crate::block_io_uring_is_supported;
use crate::disk_file::AsyncFullDiskFile;
use crate::error::{BlockError, BlockErrorKind, BlockResult};
use crate::formats::qcow::QcowDisk;
use crate::formats::raw::{RawBackend, RawDisk};
use crate::formats::vhd::VhdDisk;
use crate::formats::vhdx::VhdxDisk;
use crate::qcow_disk::QcowDisk;
use crate::{
ImageType, block_aio_is_supported, detect_image_type, open_disk_image, preallocate_disk,
};

View File

@@ -7,6 +7,7 @@
//! Each format lives in its own submodule with a `DiskFile` wrapper,
//! format specific internals, and sync/async I/O workers.
pub mod qcow;
pub mod raw;
pub mod vhd;
pub mod vhdx;

View File

@@ -14,7 +14,9 @@ use std::alloc::{Layout, alloc_zeroed, dealloc};
use std::os::fd::RawFd;
use std::{io, slice};
use crate::qcow::decoder::Decoder;
#[cfg(test)]
use super::internal;
use super::internal::decoder::Decoder;
// -- Position independent I/O helpers --
//
@@ -201,8 +203,8 @@ pub(crate) mod unit_tests {
use flate2::write::DeflateEncoder;
use vmm_sys_util::tempfile::TempFile;
use super::internal::decoder::ZlibDecoder;
use super::{decompress_cluster, pread_alloc};
use crate::qcow::decoder::ZlibDecoder;
const COMPRESSED_FLAG: u64 = 1 << 62;
const CLUSTER_USED_FLAG: u64 = 1 << 63;

View File

@@ -10,11 +10,11 @@ use std::io;
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd};
use std::sync::Arc;
use super::decoder::Decoder;
use super::metadata::{BackingRead, ClusterReadMapping, QcowMetadata};
use super::{BackingFile, BackingKind, Error as QcowError};
use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp};
use crate::qcow::decoder::Decoder;
use crate::qcow::metadata::{BackingRead, ClusterReadMapping, QcowMetadata};
use crate::qcow::{BackingFile, BackingKind, Error as QcowError};
use crate::qcow_common::{decompress_cluster, pread_alloc, pread_exact};
use crate::formats::qcow::common::{decompress_cluster, pread_alloc, pread_exact};
/// Raw backing file using pread64 on a duplicated fd.
pub(crate) struct RawBacking {

View File

@@ -40,6 +40,9 @@ use header::{
use libc::{EINVAL, EIO, ENOSPC};
use log::{error, warn};
use metadata::ClusterReadMapping;
use qcow_raw_file::{BeUint, QcowRawFile};
pub use raw_file::RawFile;
use refcount::RefCount;
use remain::sorted;
use thiserror::Error;
pub(crate) use util::MAX_NESTING_DEPTH;
@@ -49,17 +52,14 @@ use util::{
l2_entry_is_zero, l2_entry_make_std, l2_entry_make_zero, l2_entry_make_zero_plain,
l2_entry_std_cluster_addr,
};
use vec_cache::{CacheMap, Cacheable, VecCache};
use vmm_sys_util::file_traits::{FileSetLen, FileSync};
use vmm_sys_util::seek_hole::SeekHole;
use vmm_sys_util::write_zeroes::{PunchHole, WriteZeroesAt};
use super::common::decompress_cluster;
use crate::BlockBackend;
use crate::error::{BlockError, BlockErrorKind, BlockResult};
use crate::qcow::qcow_raw_file::{BeUint, QcowRawFile};
pub use crate::qcow::raw_file::RawFile;
use crate::qcow::refcount::RefCount;
use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
use crate::qcow_common::decompress_cluster;
#[sorted]
#[derive(Debug, Error)]
@@ -2426,7 +2426,7 @@ mod unit_tests {
use super::util::{COMPRESSED_FLAG, ZERO_FLAG};
use super::*;
use crate::qcow_common::unit_tests::compress_allocated_clusters;
use crate::formats::qcow::common::unit_tests::compress_allocated_clusters;
fn valid_header_v3() -> Vec<u8> {
vec![

View File

@@ -9,8 +9,8 @@ use std::io;
use libc::EINVAL;
use thiserror::Error;
use crate::qcow::qcow_raw_file::QcowRawFile;
use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
use super::qcow_raw_file::QcowRawFile;
use super::vec_cache::{CacheMap, Cacheable, VecCache};
#[derive(Debug, Error)]
pub enum Error {

View File

@@ -2,21 +2,30 @@
//
// SPDX-License-Identifier: Apache-2.0
//! QCOW2 disk image format.
//!
//! Provides [`QcowDisk`], the `DiskFile` wrapper for QCOW2 images
//! with backing file and compression support.
pub(crate) mod common;
pub mod internal;
pub mod worker;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use std::{fmt, io};
use self::internal::backing::shared_backing_from;
use self::internal::metadata::{BackingRead, QcowMetadata};
use self::internal::qcow_raw_file::QcowRawFile;
use self::internal::{MAX_NESTING_DEPTH, RawFile, parse_qcow};
#[cfg(feature = "io_uring")]
use self::worker::async_uring::QcowAsync;
use self::worker::sync::QcowSync;
use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError};
use crate::disk_file;
use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp};
use crate::qcow::backing::shared_backing_from;
use crate::qcow::metadata::{BackingRead, QcowMetadata};
use crate::qcow::qcow_raw_file::QcowRawFile;
use crate::qcow::{MAX_NESTING_DEPTH, RawFile, parse_qcow};
#[cfg(feature = "io_uring")]
use crate::qcow_async::QcowAsync;
use crate::qcow_sync::QcowSync;
/// Unified DiskFile wrapper for QCOW2 disk images.
///
@@ -191,10 +200,10 @@ impl disk_file::AsyncDiskFile for QcowDisk {
mod unit_tests {
use vmm_sys_util::tempfile::TempFile;
use self::internal::{QcowFile, RawFile};
use super::*;
use crate::async_io::AsyncIo;
use crate::disk_file::{AsyncDiskFile, DiskSize, PhysicalSize};
use crate::qcow::{QcowFile, RawFile};
const TEST_SIZE: u64 = 0x5566_7788;

View File

@@ -16,19 +16,19 @@ use std::sync::Arc;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::write_zeroes::{PunchHole, WriteZeroesAt};
use super::common::{
AlignedBuf, aligned_pread, aligned_pwrite, decompress_cluster, pread_alloc, pread_exact,
pwrite_all,
};
use super::internal::decoder::Decoder;
use super::internal::metadata::{
BackingRead, ClusterReadMapping, ClusterWriteMapping, DeallocAction, QcowMetadata,
};
use super::internal::qcow_raw_file::QcowRawFile;
use crate::SECTOR_SIZE;
use crate::async_io::{
AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult, UringDataIo,
};
use crate::qcow::decoder::Decoder;
use crate::qcow::metadata::{
BackingRead, ClusterReadMapping, ClusterWriteMapping, DeallocAction, QcowMetadata,
};
use crate::qcow::qcow_raw_file::QcowRawFile;
use crate::qcow_common::{
AlignedBuf, aligned_pread, aligned_pwrite, decompress_cluster, pread_alloc, pread_exact,
pwrite_all,
};
/// Per queue QCOW2 I/O worker using io_uring.
///
@@ -534,9 +534,9 @@ mod unit_tests {
use crate::SECTOR_SIZE;
use crate::async_io::{AsyncIoCompletion, AsyncIoOperation, GuestMemoryTarget, OwnedIoBuffer};
use crate::disk_file::AsyncDiskFile;
use crate::qcow::{BackingFileConfig, ImageType, QcowFile, RawFile};
use crate::qcow_common::unit_tests::compress_allocated_clusters;
use crate::qcow_disk::QcowDisk;
use crate::formats::qcow::QcowDisk;
use crate::formats::qcow::common::unit_tests::compress_allocated_clusters;
use crate::formats::qcow::internal::{BackingFileConfig, ImageType, QcowFile, RawFile};
fn create_disk_with_data(
file_size: u64,

View File

@@ -0,0 +1,9 @@
// Copyright 2026 The Cloud Hypervisor Authors. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
#[cfg(feature = "io_uring")]
pub(crate) mod async_uring;
pub(crate) mod sync;
pub(crate) use super::{common, internal};

View File

@@ -12,16 +12,16 @@ use std::sync::Arc;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::write_zeroes::{PunchHole, WriteZeroesAt};
use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult};
use crate::qcow::decoder::Decoder;
use crate::qcow::metadata::{
BackingRead, ClusterReadMapping, ClusterWriteMapping, DeallocAction, QcowMetadata,
};
use crate::qcow::qcow_raw_file::QcowRawFile;
use crate::qcow_common::{
use super::common::{
AlignedBuf, aligned_pread, aligned_pwrite, decompress_cluster, pread_alloc, pread_exact,
pwrite_all,
};
use super::internal::decoder::Decoder;
use super::internal::metadata::{
BackingRead, ClusterReadMapping, ClusterWriteMapping, DeallocAction, QcowMetadata,
};
use super::internal::qcow_raw_file::QcowRawFile;
use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult};
pub struct QcowSync {
metadata: Arc<QcowMetadata>,
@@ -351,11 +351,11 @@ mod unit_tests {
use crate::async_io::{AsyncIoCompletion, OwnedIoBuffer};
use crate::disk_file::{AsyncDiskFile, DiskSize, Resizable};
use crate::error::BlockErrorKind;
use crate::qcow::{
use crate::formats::qcow::QcowDisk;
use crate::formats::qcow::common::unit_tests::compress_allocated_clusters;
use crate::formats::qcow::internal::{
BackingFileConfig, Error as QcowError, ImageType, QcowFile, QcowHeader, RawFile,
};
use crate::qcow_common::unit_tests::compress_allocated_clusters;
use crate::qcow_disk::QcowDisk;
const TEST_L1_L2_ADDR_MASK: u64 = 0x00ff_ffff_ffff_fe00;
const TEST_HEADER_L1_TABLE_OFFSET: u64 = 40;
@@ -893,7 +893,9 @@ mod unit_tests {
.to_string_lossy()
.into_owned();
match err.downcast_ref::<QcowError>() {
Some(QcowError::BackingFileIo(path, _)) => assert_eq!(path, &expected_path),
Some(QcowError::BackingFileIo(path, _)) => {
assert_eq!(path.as_str(), expected_path.as_str());
}
other => panic!("unexpected error: {other:?}"),
}
}

View File

@@ -15,12 +15,6 @@ pub mod factory;
mod io_impl;
pub use io_impl::{async_io, fcntl, request};
pub mod formats;
pub mod qcow;
#[cfg(feature = "io_uring")]
pub(crate) mod qcow_async;
pub(crate) mod qcow_common;
pub mod qcow_disk;
pub(crate) mod qcow_sync;
mod sparse;
use std::alloc::{Layout, alloc_zeroed};
use std::fmt::{self, Debug};
@@ -33,6 +27,7 @@ use std::path::Path;
use std::str::FromStr;
use std::{cmp, mem, result};
pub use formats::qcow::internal as qcow;
pub use formats::raw as raw_disk;
pub use formats::vhdx::internal as vhdx;
#[cfg(feature = "io_uring")]