block: qcow: Read the image magic positionally

detect_image_type saved the cursor, rewound, read the magic, then
restored the cursor. Read the four magic bytes with read_exact_at at
offset 0 and decode with from_be_bytes, so the save, rewind, and
restore go away. BeUint moves to the test module, its only remaining
user in this file.

The result is unchanged.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-06-30 17:36:28 +02:00
committed by Rob Bradford
parent abc03f998a
commit 6a1dee64e7

View File

@@ -32,7 +32,7 @@ use header::{
offset_is_cluster_boundary, offset_is_cluster_boundary,
}; };
use log::warn; use log::warn;
use qcow_raw_file::{BeUint, QcowRawFile}; use qcow_raw_file::QcowRawFile;
use refcount::RefCount; use refcount::RefCount;
use remain::sorted; use remain::sorted;
use thiserror::Error; use thiserror::Error;
@@ -874,20 +874,15 @@ fn rebuild_refcounts(raw_file: &mut QcowRawFile, header: QcowHeader) -> BlockRes
/// Detect the type of an image file by checking for a valid qcow2 header. /// Detect the type of an image file by checking for a valid qcow2 header.
pub fn detect_image_type(file: &mut AlignedFile) -> BlockResult<ImageType> { pub fn detect_image_type(file: &mut AlignedFile) -> BlockResult<ImageType> {
let orig_seek = file let mut magic_bytes = [0u8; 4];
.stream_position() file.read_exact_at(&mut magic_bytes, 0)
.map_err(|e| BlockError::new(BlockErrorKind::Io, Error::SeekingFile(e)))?;
file.rewind()
.map_err(|e| BlockError::new(BlockErrorKind::Io, Error::SeekingFile(e)))?;
let magic = u32::read_be(file)
.map_err(|e| BlockError::new(BlockErrorKind::Io, Error::ReadingHeader(e)))?; .map_err(|e| BlockError::new(BlockErrorKind::Io, Error::ReadingHeader(e)))?;
let magic = u32::from_be_bytes(magic_bytes);
let image_type = if magic == QCOW_MAGIC { let image_type = if magic == QCOW_MAGIC {
ImageType::Qcow2 ImageType::Qcow2
} else { } else {
ImageType::Raw ImageType::Raw
}; };
file.seek(SeekFrom::Start(orig_seek))
.map_err(|e| BlockError::new(BlockErrorKind::Io, Error::SeekingFile(e)))?;
Ok(image_type) Ok(image_type)
} }
#[cfg(test)] #[cfg(test)]
@@ -905,6 +900,7 @@ mod unit_tests {
AUTOCLEAR_FEATURES_OFFSET, DEFAULT_CLUSTER_BITS, DEFAULT_REFCOUNT_ORDER, AUTOCLEAR_FEATURES_OFFSET, DEFAULT_CLUSTER_BITS, DEFAULT_REFCOUNT_ORDER,
HEADER_EXT_BACKING_FORMAT, HEADER_EXT_END, V2_BARE_HEADER_SIZE, V3_BARE_HEADER_SIZE, HEADER_EXT_BACKING_FORMAT, HEADER_EXT_END, V2_BARE_HEADER_SIZE, V3_BARE_HEADER_SIZE,
}; };
use super::qcow_raw_file::BeUint;
use super::util::ZERO_FLAG; use super::util::ZERO_FLAG;
use super::*; use super::*;
use crate::formats::qcow::{QcowDisk, QcowTempDisk}; use crate::formats::qcow::{QcowDisk, QcowTempDisk};