diff --git a/src/bin/nydus-image/core/bootstrap.rs b/src/bin/nydus-image/core/bootstrap.rs index 031e9f53869..3def2171ee2 100644 --- a/src/bin/nydus-image/core/bootstrap.rs +++ b/src/bin/nydus-image/core/bootstrap.rs @@ -24,6 +24,7 @@ use nydus_utils::digest::{self, DigestHasher, RafsDigest}; use super::context::{ ArtifactStorage, BlobManager, BootstrapContext, BootstrapManager, BuildContext, ConversionType, }; +use super::feature::Feature; use super::node::{Node, WhiteoutType, OVERLAYFS_WHITEOUT_OPAQUE}; use super::tree::Tree; @@ -599,13 +600,16 @@ impl Bootstrap { ext_sb.set_blob_table_offset(blob_table_offset); ext_sb.set_blob_table_size(blob_table_size as u32); - // collect all chunks in this bootstrap. + // Collect all chunks in this bootstrap. // HashChunkDict cannot be used here, because there will be duplicate chunks between layers, // but there is no deduplication during the actual construction. // Each layer uses the corresponding chunk in the blob of its own layer. - // If HashChunkDict is used here, it will cause duplication. The chunks are removed, - // resulting in incomplete chunk info. - let mut chunk_cache = BTreeMap::new(); + // For RAFSv6 with chunk digest array, there's no need to save the chunk info array anymore. + let mut chunk_cache = if ctx.features.is_enabled(Feature::BlobToc) { + None + } else { + Some(BTreeMap::new()) + }; // Dump bootstrap timing_tracer!( @@ -616,7 +620,7 @@ impl Bootstrap { bootstrap_ctx.writer.as_mut(), orig_meta_addr, meta_addr, - &mut chunk_cache, + chunk_cache.as_mut(), ) .context("failed to dump bootstrap")?; } @@ -644,25 +648,26 @@ impl Bootstrap { pt.store(bootstrap_ctx.writer.as_mut()).unwrap(); } - // TODO: get rid of the chunk info array. - // Dump chunk info array. - let chunk_table_offset = bootstrap_ctx - .writer - .seek_to_end() - .context("failed to seek to bootstrap's end for chunk table")?; - let mut chunk_table_size: u64 = 0; - for (_, chunk) in chunk_cache.iter() { - let chunk_size = chunk - .store(bootstrap_ctx.writer.as_mut()) - .context("failed to dump chunk table")?; - chunk_table_size += chunk_size as u64; + if let Some(chunk_cache) = chunk_cache.as_ref() { + // Dump chunk info array if needed. + let chunk_table_offset = bootstrap_ctx + .writer + .seek_to_end() + .context("failed to seek to bootstrap's end for chunk table")?; + let mut chunk_table_size: u64 = 0; + for (_, chunk) in chunk_cache.iter() { + let chunk_size = chunk + .store(bootstrap_ctx.writer.as_mut()) + .context("failed to dump chunk table")?; + chunk_table_size += chunk_size as u64; + } + ext_sb.set_chunk_table(chunk_table_offset, chunk_table_size); + debug!( + "chunk_table offset {} size {}", + chunk_table_offset, chunk_table_size + ); + Self::rafsv6_align_to_block(bootstrap_ctx)?; } - ext_sb.set_chunk_table(chunk_table_offset, chunk_table_size); - debug!( - "chunk_table offset {} size {}", - chunk_table_offset, chunk_table_size - ); - Self::rafsv6_align_to_block(bootstrap_ctx)?; // Prepare device slots. let pos = bootstrap_ctx diff --git a/src/bin/nydus-image/core/node.rs b/src/bin/nydus-image/core/node.rs index 4587024e40d..c03ff1cf609 100644 --- a/src/bin/nydus-image/core/node.rs +++ b/src/bin/nydus-image/core/node.rs @@ -899,7 +899,7 @@ impl Node { f_bootstrap: &mut dyn RafsIoWrite, orig_meta_addr: u64, meta_addr: u64, - chunk_cache: &mut BTreeMap, + chunk_cache: Option<&mut BTreeMap>, ) -> Result<()> { let xattr_inline_count = self.xattrs.count_v6(); ensure!( @@ -1273,7 +1273,7 @@ impl Node { &mut self, ctx: &mut BuildContext, f_bootstrap: &mut dyn RafsIoWrite, - chunk_cache: &mut BTreeMap, + mut chunk_cache: Option<&mut BTreeMap>, inode: &mut Box, ) -> Result<()> { let mut is_continuous = true; @@ -1289,10 +1289,12 @@ impl Node { v6_chunk.set_blob_ci_index(chunk.inner.index()); v6_chunk.set_block_addr((uncompressed_offset / EROFS_BLOCK_SIZE) as u32); chunks.extend(v6_chunk.as_ref()); - chunk_cache.insert( - DigestWithBlobIndex(*chunk.inner.id(), chunk.inner.blob_index() + 1), - chunk.inner.clone(), - ); + if let Some(v) = chunk_cache.as_mut() { + v.insert( + DigestWithBlobIndex(*chunk.inner.id(), chunk.inner.blob_index() + 1), + chunk.inner.clone(), + ); + } if let Some((prev_idx, prev_pos)) = prev { if prev_pos + ctx.chunk_size as u64 != uncompressed_offset || prev_idx != blob_idx {