(
backing_file_config: Option<&BackingFileConfig>,
direct_io: bool,
max_nesting_depth: u32,
sparse: bool,
)
| 187 | |
| 188 | impl BackingFile { |
| 189 | fn new( |
| 190 | backing_file_config: Option<&BackingFileConfig>, |
| 191 | direct_io: bool, |
| 192 | max_nesting_depth: u32, |
| 193 | sparse: bool, |
| 194 | ) -> BlockResult<Option<Self>> { |
| 195 | let Some(config) = backing_file_config else { |
| 196 | return Ok(None); |
| 197 | }; |
| 198 | |
| 199 | // Check nesting depth - applies to any backing file |
| 200 | if max_nesting_depth == 0 { |
| 201 | return Err(BlockError::new( |
| 202 | BlockErrorKind::Overflow, |
| 203 | Error::MaxNestingDepthExceeded, |
| 204 | )); |
| 205 | } |
| 206 | |
| 207 | let backing_raw_file = OpenOptions::new() |
| 208 | .read(true) |
| 209 | .open(&config.path) |
| 210 | .map_err(|e| { |
| 211 | BlockError::new( |
| 212 | BlockErrorKind::Io, |
| 213 | Error::BackingFileIo(config.path.clone(), e), |
| 214 | ) |
| 215 | })?; |
| 216 | |
| 217 | let mut raw_file = RawFile::new(backing_raw_file, direct_io); |
| 218 | |
| 219 | // Determine backing file format from header extension or auto-detect |
| 220 | let backing_format = match config.format { |
| 221 | Some(format) => format, |
| 222 | None => detect_image_type(&mut raw_file)?, |
| 223 | }; |
| 224 | |
| 225 | let (kind, virtual_size) = match backing_format { |
| 226 | ImageType::Raw => { |
| 227 | let size = raw_file.seek(SeekFrom::End(0)).map_err(|e| { |
| 228 | BlockError::new( |
| 229 | BlockErrorKind::Io, |
| 230 | Error::BackingFileIo(config.path.clone(), e), |
| 231 | ) |
| 232 | })?; |
| 233 | raw_file.rewind().map_err(|e| { |
| 234 | BlockError::new( |
| 235 | BlockErrorKind::Io, |
| 236 | Error::BackingFileIo(config.path.clone(), e), |
| 237 | ) |
| 238 | })?; |
| 239 | (BackingKind::Raw(raw_file), size) |
| 240 | } |
| 241 | ImageType::Qcow2 => { |
| 242 | let (inner, nested_backing, _sparse) = |
| 243 | parse_qcow(raw_file, max_nesting_depth - 1, sparse).map_err(|e| { |
| 244 | let kind = e.kind(); |
| 245 | let source = e |
| 246 | .into_source() |
nothing calls this directly
no test coverage detected