block: qcow: Switch parse_qcow and BackingFile::new to BlockResult

Switch parse_qcow and BackingFile::new from qcow::Result to
BlockResult. Every early return site now produces an explicit
BlockError with the appropriate kind. Remaining internal calls to
functions still on qcow::Result rely on the From scaffolding and
will be converted in subsequent commits.

Two helpers are added to BlockError. with_kind replaces the
classification on an existing error, used in QcowDiskSync::new to
avoid double wrapping when the caller needs a different kind.
into_source consumes the error and returns the boxed source, used
at the recursive BackingFile open to extract the qcow::Error for
BackingFileOpen without letting qcow::Error hold a BlockError.

The qcow_sync boundary is simplified to a single closure that
operates on the BlockError already returned by parse_qcow.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-03-13 23:39:45 +01:00
committed by Rob Bradford
parent c4a5c7f843
commit be9ef116aa
3 changed files with 92 additions and 36 deletions

View File

@@ -197,25 +197,14 @@ impl QcowDiskSync {
) -> BlockResult<Self> {
let max_nesting_depth = if backing_files { MAX_NESTING_DEPTH } else { 0 };
let (inner, backing_file, sparse) =
parse_qcow(RawFile::new(file, direct_io), max_nesting_depth, sparse)
.map_err(|e| match e {
QcowError::MaxNestingDepthExceeded if !backing_files => {
QcowError::BackingFilesDisabled
}
other => other,
})
.map_err(|e| {
let kind = match &e {
QcowError::InvalidMagic | QcowError::UnsupportedVersion(_) => {
BlockErrorKind::InvalidFormat
}
QcowError::UnsupportedFeature(_) | QcowError::BackingFilesDisabled => {
BlockErrorKind::UnsupportedFeature
}
_ => BlockErrorKind::Io,
};
BlockError::new(kind, e).with_op(ErrorOp::Open)
})?;
parse_qcow(RawFile::new(file, direct_io), max_nesting_depth, sparse).map_err(|e| {
let e = if !backing_files && matches!(e.kind(), BlockErrorKind::Overflow) {
e.with_kind(BlockErrorKind::UnsupportedFeature)
} else {
e
};
e.with_op(ErrorOp::Open)
})?;
let data_raw_file = inner.raw_file.clone();
Ok(QcowDiskSync {
metadata: Arc::new(QcowMetadata::new(inner)),