Skip to content

Commit 7cf69a5

Browse files
committed
builder: handle estargz's chunk info for rafs v6
Signed-off-by: Yan Song <[email protected]>
1 parent 1b331b1 commit 7cf69a5

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

rafs/src/metadata/layout/v6.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use lazy_static::lazy_static;
1717
use nydus_utils::{compress, digest, round_up, ByteSize};
1818
use storage::device::{BlobFeatures, BlobInfo};
1919
use storage::meta::{BlobMetaHeaderOndisk, BLOB_FEATURE_4K_ALIGNED};
20-
use storage::RAFS_MAX_CHUNK_SIZE;
2120

2221
use crate::metadata::{layout::RafsXAttrs, RafsStore, RafsSuperFlags};
2322
use crate::{impl_bootstrap_converter, impl_pub_getter_setter, RafsIoReader, RafsIoWrite};
@@ -353,10 +352,7 @@ impl RafsV6SuperBlockExt {
353352
}
354353

355354
let chunk_size = u32::from_le(self.s_chunk_size) as u64;
356-
if !chunk_size.is_power_of_two()
357-
|| chunk_size < EROFS_BLOCK_SIZE
358-
|| chunk_size > RAFS_MAX_CHUNK_SIZE
359-
{
355+
if !chunk_size.is_power_of_two() || chunk_size < EROFS_BLOCK_SIZE {
360356
return Err(einval!("invalid chunk size in Rafs v6 extended superblock"));
361357
}
362358

@@ -1296,11 +1292,7 @@ impl RafsV6Blob {
12961292
}
12971293

12981294
let c_size = u32::from_le(self.chunk_size) as u64;
1299-
if c_size.count_ones() != 1
1300-
|| c_size < EROFS_BLOCK_SIZE
1301-
|| c_size > RAFS_MAX_CHUNK_SIZE
1302-
|| c_size != chunk_size as u64
1303-
{
1295+
if c_size.count_ones() != 1 || c_size < EROFS_BLOCK_SIZE || c_size != chunk_size as u64 {
13041296
error!(
13051297
"RafsV6Blob: idx {} invalid c_size {}, count_ones() {}",
13061298
blob_index,

src/bin/nydus-image/builder/stargz.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use nix::sys::stat::makedev;
1818
use serde::{Deserialize, Serialize};
1919

2020
use nydus_utils::digest::{self, Algorithm, DigestHasher, RafsDigest};
21-
use nydus_utils::ByteSize;
21+
use nydus_utils::{try_round_up_4k, ByteSize};
2222
use rafs::metadata::layout::v5::{RafsV5ChunkInfo, RafsV5Inode, RafsV5InodeFlags};
2323
use rafs::metadata::layout::RafsXAttrs;
2424
use rafs::metadata::Inode;
@@ -352,6 +352,7 @@ impl StargzIndexTreeBuilder {
352352
let mut tree: Option<Tree> = None;
353353
let mut last_reg_entry: Option<&TocEntry> = None;
354354

355+
let mut uncompress_offset = 0;
355356
for entry in toc_index.entries.iter() {
356357
if !entry.is_supported() {
357358
continue;
@@ -370,6 +371,15 @@ impl StargzIndexTreeBuilder {
370371
}
371372

372373
if (entry.is_reg() || entry.is_chunk()) && decompress_size != 0 {
374+
let aligned_chunk_size = if ctx.aligned_chunk {
375+
// Safe to unwrap because `chunk_size` is much less than u32::MAX.
376+
try_round_up_4k(decompress_size).unwrap()
377+
} else {
378+
decompress_size
379+
};
380+
let pre_uncompress_offset = uncompress_offset;
381+
uncompress_offset += aligned_chunk_size;
382+
373383
let block_id = entry.block_id(&ctx.blob_id)?;
374384
let v5_chunk_info = ChunkWrapper::V5(RafsV5ChunkInfo {
375385
block_id,
@@ -381,7 +391,7 @@ impl StargzIndexTreeBuilder {
381391
uncompress_size: decompress_size as u32,
382392
compress_offset: entry.offset as u64,
383393
// No available data on entry
384-
uncompress_offset: 0,
394+
uncompress_offset: pre_uncompress_offset,
385395
file_offset: entry.chunk_offset as u64,
386396
index: 0,
387397
reserved: 0,
@@ -594,6 +604,8 @@ impl StargzBuilder {
594604
blob_ctx.set_meta_info_enabled(ctx.fs_version == RafsVersion::V6);
595605
blob_ctx.blob_meta_header = header;
596606

607+
let mut chunk_map = HashMap::new();
608+
597609
// Set blob index and inode digest for upper nodes
598610
for node in &mut bootstrap_ctx.nodes {
599611
if node.overlay.is_lower_layer() {
@@ -603,8 +615,13 @@ impl StargzBuilder {
603615
let mut inode_hasher = RafsDigest::hasher(digest::Algorithm::Sha256);
604616

605617
for chunk in node.chunks.iter_mut() {
606-
let chunk_index = blob_ctx.alloc_index()?;
607-
chunk.inner.set_index(chunk_index);
618+
if let Some(chunk_index) = chunk_map.get(chunk.inner.id()) {
619+
chunk.inner.set_index(*chunk_index);
620+
} else {
621+
let chunk_index = blob_ctx.alloc_index()?;
622+
chunk.inner.set_index(chunk_index);
623+
chunk_map.insert(*chunk.inner.id(), chunk.inner.index());
624+
}
608625
chunk.inner.set_blob_index(blob_index);
609626
decompressed_blob_size += chunk.inner.uncompressed_size() as u64;
610627
compressed_blob_size += chunk.inner.compressed_size() as u64;

src/bin/nydus-image/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -952,10 +952,7 @@ impl Command {
952952
let param = v.trim_start_matches("0x").trim_end_matches("0X");
953953
let chunk_size =
954954
u32::from_str_radix(param, 16).context(format!("invalid chunk size {}", v))?;
955-
if chunk_size as u64 > RAFS_DEFAULT_CHUNK_SIZE
956-
|| chunk_size < 0x1000
957-
|| !chunk_size.is_power_of_two()
958-
{
955+
if chunk_size < 0x1000 || !chunk_size.is_power_of_two() {
959956
bail!("invalid chunk size: {}", chunk_size);
960957
}
961958
Ok(chunk_size)

0 commit comments

Comments
 (0)