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 <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-03-05 16:57:20 +01:00
committed by Rob Bradford
parent b1bc376c91
commit 2bcbe25539
2 changed files with 15 additions and 10 deletions
+10 -8
View File
@@ -59,10 +59,10 @@ use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
#[sorted] #[sorted]
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum Error { pub enum Error {
#[error("Backing file io error")] #[error("Backing file I/O error: {0}")]
BackingFileIo(#[source] io::Error), BackingFileIo(String /* path */, #[source] io::Error),
#[error("Backing file open error")] #[error("Backing file open error: {0}")]
BackingFileOpen(#[source] Box<Error>), BackingFileOpen(String /* path */, #[source] Box<Error>),
#[error("Backing file support is disabled")] #[error("Backing file support is disabled")]
BackingFilesDisabled, BackingFilesDisabled,
#[error("Backing file name is too long: {0} bytes over")] #[error("Backing file name is too long: {0} bytes over")]
@@ -201,7 +201,7 @@ impl BackingFile {
let backing_raw_file = OpenOptions::new() let backing_raw_file = OpenOptions::new()
.read(true) .read(true)
.open(&config.path) .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); let mut raw_file = RawFile::new(backing_raw_file, direct_io);
@@ -215,14 +215,16 @@ impl BackingFile {
ImageType::Raw => { ImageType::Raw => {
let size = raw_file let size = raw_file
.seek(SeekFrom::End(0)) .seek(SeekFrom::End(0))
.map_err(Error::BackingFileIo)?; .map_err(|e| Error::BackingFileIo(config.path.clone(), e))?;
raw_file.rewind().map_err(Error::BackingFileIo)?; raw_file
.rewind()
.map_err(|e| Error::BackingFileIo(config.path.clone(), e))?;
(BackingKind::Raw(raw_file), size) (BackingKind::Raw(raw_file), size)
} }
ImageType::Qcow2 => { ImageType::Qcow2 => {
let (inner, nested_backing, _sparse) = let (inner, nested_backing, _sparse) =
parse_qcow(raw_file, max_nesting_depth - 1, 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; let size = inner.header.size;
( (
BackingKind::Qcow { BackingKind::Qcow {
+5 -2
View File
@@ -144,8 +144,11 @@ fn shared_backing_from(bf: BackingFile) -> BlockResult<Arc<dyn BackingRead>> {
let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult<OwnedFd> { let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult<OwnedFd> {
fd.try_clone_to_owned().map_err(|e| { fd.try_clone_to_owned().map_err(|e| {
BlockError::new(BlockErrorKind::Io, QcowError::BackingFileIo(e)) BlockError::new(
.with_op(ErrorOp::DupBackingFd) BlockErrorKind::Io,
QcowError::BackingFileIo(String::new(), e),
)
.with_op(ErrorOp::DupBackingFd)
}) })
}; };