block: Add BackingFilesDisabled error for actionable user guidance

When a QCOW2 image has a backing file but backing_files=on is not set,
the error was MaxNestingDepthExceeded which gives no indication that
this is a policy decision or how to resolve it.

Add a BackingFilesDisabled error variant whose message indicates that
backing file support is disabled and references the backing_files
option. The translation from MaxNestingDepthExceeded to
BackingFilesDisabled happens at the QcowDiskSync boundary where the
policy decision is made, preserving the original error for genuine
recursive depth exhaustion.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski 2026-02-19 11:22:28 +01:00 committed by Rob Bradford
parent 68f746fbea
commit 94368c622e
2 changed files with 13 additions and 6 deletions

View file

@ -44,6 +44,8 @@ pub enum Error {
BackingFileIo(#[source] io::Error),
#[error("Backing file open error")]
BackingFileOpen(#[source] Box<Error>),
#[error("Backing file support is disabled")]
BackingFilesDisabled,
#[error("Backing file name is too long: {0} bytes over")]
BackingFileTooLong(usize),
#[error("Image is marked corrupt and cannot be opened for writing")]

View file

@ -14,7 +14,7 @@ use vmm_sys_util::write_zeroes::PunchHole;
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::qcow::{MAX_NESTING_DEPTH, QcowFile, RawFile, Result as QcowResult};
use crate::qcow::{Error as QcowError, MAX_NESTING_DEPTH, QcowFile, RawFile, Result as QcowResult};
use crate::{AsyncAdaptor, BlockBackend};
pub struct QcowDiskSync {
@ -32,12 +32,17 @@ pub struct QcowDiskSync {
impl QcowDiskSync {
pub fn new(file: File, direct_io: bool, backing_files: bool, sparse: bool) -> QcowResult<Self> {
let max_nesting_depth = if backing_files { MAX_NESTING_DEPTH } else { 0 };
let qcow_file = QcowFile::from_with_nesting_depth(
RawFile::new(file, direct_io),
max_nesting_depth,
sparse,
)
.map_err(|e| match e {
QcowError::MaxNestingDepthExceeded if !backing_files => QcowError::BackingFilesDisabled,
other => other,
})?;
Ok(QcowDiskSync {
qcow_file: Arc::new(Mutex::new(QcowFile::from_with_nesting_depth(
RawFile::new(file, direct_io),
max_nesting_depth,
sparse,
)?)),
qcow_file: Arc::new(Mutex::new(qcow_file)),
})
}
}