From 8cd2c957ef53da1e12cbf0d3ce991e9af2488f70 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 20 Mar 2026 16:13:23 +0100 Subject: [PATCH] block: qcow: Move shared_backing_from to qcow/backing Move the backing file constructor into qcow/backing alongside the types it creates. Both qcow_sync and qcow_async can now import shared_backing_from directly from qcow/backing. Signed-off-by: Anatol Belski --- block/src/qcow/backing.rs | 38 ++++++++++++++++++++++++++++++++++- block/src/qcow_sync.rs | 42 +++------------------------------------ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/block/src/qcow/backing.rs b/block/src/qcow/backing.rs index c688900c5..e5e037b0a 100644 --- a/block/src/qcow/backing.rs +++ b/block/src/qcow/backing.rs @@ -7,10 +7,12 @@ //! Thread safe backing file readers for QCOW2 images. use std::io; -use std::os::fd::{AsRawFd, OwnedFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd}; use std::sync::Arc; +use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp}; use crate::qcow::metadata::{BackingRead, ClusterReadMapping, QcowMetadata}; +use crate::qcow::{BackingFile, BackingKind, Error as QcowError}; use crate::qcow_common::pread_exact; /// Raw backing file using pread64 on a duplicated fd. @@ -128,3 +130,37 @@ impl Drop for Qcow2MetadataBacking { self.metadata.shutdown(); } } + +/// Construct a thread safe backing file reader. +pub fn shared_backing_from(bf: BackingFile) -> BlockResult> { + let (kind, virtual_size) = bf.into_kind(); + + let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult { + fd.try_clone_to_owned().map_err(|e| { + BlockError::new( + BlockErrorKind::Io, + QcowError::BackingFileIo(String::new(), e), + ) + .with_op(ErrorOp::DupBackingFd) + }) + }; + + match kind { + BackingKind::Raw(raw_file) => { + let fd = dup_fd(raw_file.as_fd())?; + Ok(Arc::new(RawBacking { fd, virtual_size })) + } + BackingKind::Qcow { inner, backing } => { + let data_fd = dup_fd(inner.raw_file.as_fd())?; + Ok(Arc::new(Qcow2MetadataBacking { + metadata: Arc::new(QcowMetadata::new(*inner)), + data_fd, + backing_file: backing.map(|bf| shared_backing_from(*bf)).transpose()?, + })) + } + #[cfg(test)] + BackingKind::QcowFile(_) => { + unreachable!("QcowFile variant is only used by set_backing_file() in tests") + } + } +} diff --git a/block/src/qcow_sync.rs b/block/src/qcow_sync.rs index 483db80f5..f948a3b5f 100644 --- a/block/src/qcow_sync.rs +++ b/block/src/qcow_sync.rs @@ -5,7 +5,7 @@ use std::cmp::min; use std::collections::VecDeque; use std::fs::File; -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd}; +use std::os::fd::{AsFd, AsRawFd}; use std::sync::Arc; use std::{fmt, io}; @@ -15,52 +15,16 @@ use vmm_sys_util::write_zeroes::{PunchHole, WriteZeroesAt}; use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFileError}; use crate::disk_file; use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp}; -use crate::qcow::backing::{Qcow2MetadataBacking, RawBacking}; +use crate::qcow::backing::shared_backing_from; use crate::qcow::metadata::{ BackingRead, ClusterReadMapping, ClusterWriteMapping, DeallocAction, QcowMetadata, }; use crate::qcow::qcow_raw_file::QcowRawFile; -use crate::qcow::{ - BackingFile, BackingKind, Error as QcowError, MAX_NESTING_DEPTH, RawFile, parse_qcow, -}; +use crate::qcow::{MAX_NESTING_DEPTH, RawFile, parse_qcow}; use crate::qcow_common::{ gather_from_iovecs, pread_exact, pwrite_all, scatter_to_iovecs, zero_fill_iovecs, }; -/// Construct a thread safe backing file reader. -fn shared_backing_from(bf: BackingFile) -> BlockResult> { - let (kind, virtual_size) = bf.into_kind(); - - let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult { - fd.try_clone_to_owned().map_err(|e| { - BlockError::new( - BlockErrorKind::Io, - QcowError::BackingFileIo(String::new(), e), - ) - .with_op(ErrorOp::DupBackingFd) - }) - }; - - match kind { - BackingKind::Raw(raw_file) => { - let fd = dup_fd(raw_file.as_fd())?; - Ok(Arc::new(RawBacking { fd, virtual_size })) - } - BackingKind::Qcow { inner, backing } => { - let data_fd = dup_fd(inner.raw_file.as_fd())?; - Ok(Arc::new(Qcow2MetadataBacking { - metadata: Arc::new(QcowMetadata::new(*inner)), - data_fd, - backing_file: backing.map(|bf| shared_backing_from(*bf)).transpose()?, - })) - } - #[cfg(test)] - BackingKind::QcowFile(_) => { - unreachable!("QcowFile variant is only used by set_backing_file() in tests") - } - } -} - pub struct QcowDiskSync { metadata: Arc, /// Shared across queues, resolved once at construction.