From 2bcbe25539d2d329fe359a364c6b8805ec243f50 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 5 Mar 2026 16:57:20 +0100 Subject: [PATCH] block: qcow: Add backing file path to qcow error context Extend the BackingFileIo and BackingFileOpen variants of qcow::Error with a path field so that backing file failures report which file was involved. The path is populated from the backing file configuration. Signed-off-by: Anatol Belski --- block/src/qcow/mod.rs | 18 ++++++++++-------- block/src/qcow_sync.rs | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/block/src/qcow/mod.rs b/block/src/qcow/mod.rs index c0b4e8c72..9c9d56152 100644 --- a/block/src/qcow/mod.rs +++ b/block/src/qcow/mod.rs @@ -59,10 +59,10 @@ use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache}; #[sorted] #[derive(Debug, Error)] pub enum Error { - #[error("Backing file io error")] - BackingFileIo(#[source] io::Error), - #[error("Backing file open error")] - BackingFileOpen(#[source] Box), + #[error("Backing file I/O error: {0}")] + BackingFileIo(String /* path */, #[source] io::Error), + #[error("Backing file open error: {0}")] + BackingFileOpen(String /* path */, #[source] Box), #[error("Backing file support is disabled")] BackingFilesDisabled, #[error("Backing file name is too long: {0} bytes over")] @@ -201,7 +201,7 @@ impl BackingFile { let backing_raw_file = OpenOptions::new() .read(true) .open(&config.path) - .map_err(Error::BackingFileIo)?; + .map_err(|e| Error::BackingFileIo(config.path.clone(), e))?; let mut raw_file = RawFile::new(backing_raw_file, direct_io); @@ -215,14 +215,16 @@ impl BackingFile { ImageType::Raw => { let size = raw_file .seek(SeekFrom::End(0)) - .map_err(Error::BackingFileIo)?; - raw_file.rewind().map_err(Error::BackingFileIo)?; + .map_err(|e| Error::BackingFileIo(config.path.clone(), e))?; + raw_file + .rewind() + .map_err(|e| Error::BackingFileIo(config.path.clone(), e))?; (BackingKind::Raw(raw_file), size) } ImageType::Qcow2 => { let (inner, nested_backing, _sparse) = parse_qcow(raw_file, max_nesting_depth - 1, sparse) - .map_err(|e| Error::BackingFileOpen(Box::new(e)))?; + .map_err(|e| Error::BackingFileOpen(config.path.clone(), Box::new(e)))?; let size = inner.header.size; ( BackingKind::Qcow { diff --git a/block/src/qcow_sync.rs b/block/src/qcow_sync.rs index d2f17b059..e1ad08f4a 100644 --- a/block/src/qcow_sync.rs +++ b/block/src/qcow_sync.rs @@ -144,8 +144,11 @@ fn shared_backing_from(bf: BackingFile) -> BlockResult> { let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult { fd.try_clone_to_owned().map_err(|e| { - BlockError::new(BlockErrorKind::Io, QcowError::BackingFileIo(e)) - .with_op(ErrorOp::DupBackingFd) + BlockError::new( + BlockErrorKind::Io, + QcowError::BackingFileIo(String::new(), e), + ) + .with_op(ErrorOp::DupBackingFd) }) };