From e8cb4a8d53ff544931b0d9dd7734381bc28abc8c Mon Sep 17 00:00:00 2001 From: Andrew Gunnerson Date: Sun, 23 Mar 2025 18:50:44 -0400 Subject: [PATCH] Fix incorrect compression input for gzip CoW size estimation Instead of compressing the 64 MiB input in 2 MiB chunks, each loop iteration was compressing the full 64 MiB. This massively slowed down the patching process from seconds to potentially hours and would temporarily waste a bunch of space during OTA installation. Fixes: #433 Signed-off-by: Andrew Gunnerson --- avbroot/src/cli/ota.rs | 4 ++-- avbroot/src/format/payload.rs | 8 +++++--- e2e/e2e.toml | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/avbroot/src/cli/ota.rs b/avbroot/src/cli/ota.rs index 427a73b..b3a80be 100644 --- a/avbroot/src/cli/ota.rs +++ b/avbroot/src/cli/ota.rs @@ -683,8 +683,6 @@ pub fn compress_image( // update the CoW size estimate or else the CoW block device may run out of // space during flashing. let vabc_algo = if partition.estimate_cow_size.is_some() { - info!("Needs updated CoW size estimate: {name}"); - // Only CoW v2 seems to exist in the wild currently, so that is all we // support. let Some(dpm) = &header.manifest.dynamic_partition_metadata else { @@ -705,6 +703,8 @@ pub fn compress_image( bail!("Unsupported VABC compression: {compression}"); }; + info!("Needs updated {vabc_algo} CoW size estimate: {name}"); + Some(vabc_algo) } else { None diff --git a/avbroot/src/format/payload.rs b/avbroot/src/format/payload.rs index 21f448b..b7a9db4 100644 --- a/avbroot/src/format/payload.rs +++ b/avbroot/src/format/payload.rs @@ -965,20 +965,22 @@ impl VabcAlgo { while !raw_data.is_empty() { let n = raw_data.len().min(block_size as usize); + let (chunk, remaining) = raw_data.split_at(n); + // This should match CompressWorker::GetDefaultCompressionLevel() in // AOSP's libsnapshot. let compressed = match self { - Self::Lz4 => lz4_flex::block::compress(&raw_data[..n]), + Self::Lz4 => lz4_flex::block::compress(chunk), Self::Gzip => { let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); - encoder.write_all(raw_data).map_err(Error::GzCompress)?; + encoder.write_all(chunk).map_err(Error::GzCompress)?; encoder.finish().map_err(Error::GzCompress)? } }; total += compressed.len().min(n) as u64; - raw_data = &raw_data[n..]; + raw_data = remaining; } Ok(total) diff --git a/e2e/e2e.toml b/e2e/e2e.toml index c87f48c..5f4b20b 100644 --- a/e2e/e2e.toml +++ b/e2e/e2e.toml @@ -168,9 +168,9 @@ data.type = "vbmeta" data.deps = ["system"] [profile.pixel_v2.hashes_streaming] -original = "4b7e5675f834ac56bf3459628adfe1425c2346a1c224ee6ea0a3be9f996db254" -patched = "4a7ca99808b4e49a2dc77a620d4fb7d8219b974ab5b3d5b5709084942805dc9a" +original = "bd2f19cf3d2285e35e8b36d44f75ed910e8e0be44c3ebd29f17a812521ba754b" +patched = "cf65d5b90500af54cd1204a646379bb852825061bc7c3f973b7a042f353f75ad" [profile.pixel_v2.hashes_seekable] -original = "66b44b148b35a8a998214e0ae36470b42ffd6d2974e18cd8fa12cd8af0c98540" -patched = "5ddec4bb56dd78a49fbc49e9ad3de7710b0b008b031ff4dfce8fdc775e753ad1" +original = "7f96ebf7366e0b60c91ac1e5f196a2189ffdb0bbc73f77804a736466fcab7315" +patched = "c2d9d60d73c038da39f82073ffadb459c96b901d66db7af11f59da58e0dd53e4"