Thanks to visit codestin.com
Credit goes to github.com

Skip to content

block: qcow: Consolidate BE file I/O with BeUint trait - #7637

Merged
rbradford merged 2 commits into
cloud-hypervisor:mainfrom
weltling:qcow-be-io
Jan 27, 2026
Merged

rbradford merged 2 commits into
cloud-hypervisor:mainfrom
weltling:qcow-be-io

Conversation

@weltling

@weltling weltling commented Jan 26, 2026

Copy link
Copy Markdown
Member

Extend the BeUint trait with a read_be() method and make it pub(super) so it can be used across the qcow module. Change BeUint::write_be() to take Self instead of u64, providing type safety through TryFrom conversion.

Update QcowHeader and other related places to use BeUint methods internally for reading/writing header fields.

This removes the byteorder dependency from mod.rs and consolidates all big-endian file I/O through the shared BeUint trait.

Suggested-by: Rob Bradford [email protected]

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left a few remarks

Comment thread block/src/qcow/qcow_raw_file.rs Outdated
fn write_refcount<T: BeUint>(file: &mut RawFile, table: &[u64]) -> io::Result<()> {
fn write_refcount<T: BeUint + TryFrom<u64>>(file: &mut RawFile, table: &[u64]) -> io::Result<()>
where
<T as TryFrom<u64>>::Error: std::fmt::Debug,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I prefer to use Debug here with a use statement in the top

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

Comment thread block/src/qcow/qcow_raw_file.rs Outdated
let bytes_per_entry = size_of::<T>();
let mut buffer = BufWriter::with_capacity(table.len() * bytes_per_entry, file);
for &val in table {
T::write(&mut buffer, val)?;
T::write(&mut buffer, T::try_from(val).unwrap())?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use expect("should <explain condition why this should be okay>) here or a comment explaining why this can never panic.

It is currently not clear to me from reading the code why this won't fail on the happy path or won't fail at all

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an expect, which seems better than a comment as it can catch a bug. For the refcount validation, please see mod.rs around lines 116 and 1171 throwing RefcountOverflow. Thus the downcast is expected to be safe.

Thanks

Comment thread block/src/qcow/qcow_raw_file.rs Outdated
Comment thread block/src/qcow/qcow_raw_file.rs Outdated
@@ -40,8 +46,12 @@ impl BeUint for u16 {
u16::from_be_bytes([bytes[0], bytes[1]]) as u64
}
#[inline(always)]
fn write<W: Write>(w: &mut W, val: u64) -> io::Result<()> {
w.write_u16::<BigEndian>(val as u16)
fn read<R: Read>(r: &mut R) -> io::Result<Self> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would strongly prefer to make sure these methods include _be in the name - so it's very apparent from the call side the endianness.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I see now also u64::write is unclear, as the trait only imported at the top but the connection is not obvious. Did the renames now. Thanks

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now! Left a nit, feel free to address.

Comment thread block/src/qcow/qcow_raw_file.rs Outdated
@@ -18,9 +19,10 @@ type RefcountReader = fn(&mut RawFile, usize) -> io::Result<Vec<u64>>;
type RefcountWriter = fn(&mut RawFile, &[u64]) -> io::Result<()>;

/// Big-endian file access trait.
trait BeUint: Sized + Copy {
pub trait BeUint: Sized + Copy {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the commit message says

BeUint trait and make it pub so it can be
used across the qcow module.

so this line could also be pub(super) trait BeUint: ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good that you notice. I was considering that but saw other structs being just pub so did alike. Fixed tihs. Thanks!

Add a read_be() method to the BeUint trait and make it pub(super)
so it can be used across the qcow module. Change BeUint::write_be()
to take Self instead of u64, providing type safety through TryFrom
conversion.

Suggested-by: Rob Bradford <[email protected]>
Signed-off-by: Anatol Belski <[email protected]>
Comment thread block/src/qcow/mod.rs Outdated
fn write_u32_to_file<F: Write>(f: &mut F, value: u32) -> Result<()> {
f.write_u32::<BigEndian>(value)
.map_err(Error::WritingHeader)
fn write_u32<F: Write>(f: &mut F, value: u32) -> Result<()> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I should have been clearer. I still think that calling this write_u32_be would just be safer for readability. I know the original code didn't do that but I think this is an opportunity to improve that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, renamed the local helpers to include the _be suffix as well. Checked - everything I touched here has the suffix now. Thanks

Update QcowHeader and other related places to use BeUint methods
internally for reading/writing header fields.

This removes the byteorder dependency from mod.rs and consolidates
all big-endian file I/O through the shared BeUint trait.

Suggested-by: Rob Bradford <[email protected]>
Signed-off-by: Anatol Belski <[email protected]>

@rbradford rbradford left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@rbradford
rbradford added this pull request to the merge queue Jan 27, 2026
Merged via the queue into cloud-hypervisor:main with commit 87e8ac3 Jan 27, 2026
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants