feat(disk/qcow): support compressed qcow2 clusters (zlib + zstd) with…#3
Open
lateautumn233 wants to merge 1 commit into
Open
feat(disk/qcow): support compressed qcow2 clusters (zlib + zstd) with…#3lateautumn233 wants to merge 1 commit into
lateautumn233 wants to merge 1 commit into
Conversation
… COW writes Add read and copy-on-write support for compressed qcow2 clusters. Compressed clusters are decompressed on read and rewritten as plain clusters on write, so images produced by `qemu-img convert -c` can be used and modified. - Decode both compression types: zlib (raw DEFLATE via flate2's zlib-rs backend) and zstd (C libzstd via the zstd crate). Enable the `qcow` feature's new flate2/zstd deps in Cargo.toml and wire libflate2/libzstd_rust into disk/Android.bp. - Validate the incompatible-features header: tolerate the dirty and compression bits, reject corrupt/external-data-file/extended-L2 and any unknown bit, and require the compression bit to agree with the compression-type field. - Add a 2 MiB LRU cache of decompressed clusters and parallelize multi-cluster compressed reads across worker threads (single-cluster reads decode inline). - Fix COPIED-flag corruption: write_pointer_table no longer ORs OFLAG_COPIED (bit 63) onto compressed L2 entries (bit 62), which the qcow2 spec forbids, and strips any stray bit-63 left by prior writes. This stops `qemu-img check` from reporting "OFLAG_COPIED must never be set for compressed" on written images.
There was a problem hiding this comment.
Pull request overview
Adds qcow2 compressed-cluster support to the disk crate’s qcow implementation so images created with qemu-img convert -c can be read and modified. The PR extends header validation, introduces decompression (zlib + zstd) with caching/parallel decode, and updates refcount/COW logic to correctly handle compressed L2 entries (including preventing forbidden OFLAG_COPIED on compressed entries).
Changes:
- Add decoding for qcow2 compressed clusters (zlib raw DEFLATE + zstd) with an LRU cache and parallel multi-cluster decode.
- Validate qcow2 incompatible-features bits and compression-type consistency; reject unsupported incompatible bits/types.
- Fix pointer-table writeback to avoid propagating
OFLAG_COPIEDonto compressed L2 entries and reclaim freed compressed storage safely.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| disk/src/qcow/qcow_raw_file.rs | Adjust pointer-table writeback to preserve compressed descriptors and strip forbidden/copied bits. |
| disk/src/qcow/mod.rs | Implement compressed-cluster read/COW-write paths, caching/prefetch, header validation, and refcount handling updates. |
| disk/Cargo.toml | Enable qcow feature to pull in flate2 (zlib-rs backend) and zstd dependencies. |
| disk/Android.bp | Wire flate2/zstd Rust libs and enable required features for Android builds. |
| Cargo.lock | Lockfile update for new/updated dependencies (flate2/zlib-rs, zstd, etc.). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+311
to
+314
| fn decompress_zstd_cluster(compressed: &[u8], out: &mut [u8]) -> std::io::Result<()> { | ||
| let decoder = zstd::stream::read::Decoder::with_buffer(compressed)?; | ||
| read_fill(&mut decoder.single_frame(), out) | ||
| } |
Comment on lines
+1419
to
+1423
| entry if entry & COMPRESSED_FLAG != 0 => { | ||
| // Copy-on-write from a compressed cluster: decompress it into a freshly allocated | ||
| // uncompressed cluster and repoint the L2 entry there (clearing the compressed | ||
| // descriptor), unless the caller overwrites the whole cluster — then hand out a | ||
| // zeroed cluster and skip the decompression. Fill the new cluster before |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
… COW writes
Add read and copy-on-write support for compressed qcow2 clusters. Compressed clusters are decompressed on read and rewritten as plain clusters on write, so images produced by
qemu-img convert -ccan be used and modified.qcowfeature's new flate2/zstd deps in Cargo.toml and wire libflate2/libzstd_rust into disk/Android.bp.qemu-img checkfrom reporting "OFLAG_COPIED must never be set for compressed" on written images.We don't accept any GitHub pull requests to crosvm. We use
Chromium Gerrit for the code review process. See
the contribution guide for the details.