Skip to content

Commit

Permalink
rafs: only invoke v5 related code for v5 builds
Browse files Browse the repository at this point in the history
Only invoke v5 related code for v5 builds, also enforce strictly
validation when creating missing directory for tar based builds.

Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
  • Loading branch information
jiangliu committed Mar 12, 2023
1 parent c00c578 commit 3691e5d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 36 deletions.
31 changes: 9 additions & 22 deletions rafs/src/builder/core/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,19 @@ impl Node {
return Ok(0);
} else if self.is_symlink() {
if let Some(symlink) = self.info.symlink.as_ref() {
self.inode
.set_digest(RafsDigest::from_buf(symlink.as_bytes(), ctx.digester));
if self.inode.is_v5() {
self.inode
.set_digest(RafsDigest::from_buf(symlink.as_bytes(), ctx.digester));
}
return Ok(0);
} else {
return Err(Error::msg("inode's symblink is invalid."));
}
} else if self.is_special() {
self.inode
.set_digest(RafsDigest::hasher(ctx.digester).digest_finalize());
if self.inode.is_v5() {
self.inode
.set_digest(RafsDigest::hasher(ctx.digester).digest_finalize());
}
return Ok(0);
}

Expand Down Expand Up @@ -581,7 +585,7 @@ impl Node {
// calculate it later by ourself.
if !self.is_dir() {
self.inode.set_size(meta.st_size());
self.set_inode_blocks();
self.v5_set_inode_blocks();
}
self.info = Arc::new(info);

Expand Down Expand Up @@ -736,23 +740,6 @@ impl Node {
&self.info.target
}

/// Calculate and set `i_blocks` for inode.
///
/// In order to support repeatable build, we can't reuse `i_blocks` from source filesystems,
/// so let's calculate it by ourself for stable `i_block`.
///
/// Normal filesystem includes the space occupied by Xattr into the directory size,
/// let's follow the normal behavior.
pub fn set_inode_blocks(&mut self) {
// Set inode blocks for RAFS v5 inode, v6 will calculate it at runtime.
if let InodeWrapper::V5(_) = self.inode {
self.inode.set_blocks(div_round_up(
self.inode.size() + self.info.xattrs.aligned_size_v5() as u64,
512,
));
}
}

/// Set symlink target for the node.
pub fn set_symlink(&mut self, symlink: OsString) {
let mut info = self.info.deref().clone();
Expand Down
21 changes: 19 additions & 2 deletions rafs/src/builder/core/v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::mem::size_of;

use anyhow::{bail, Context, Result};
use nydus_utils::digest::{DigestHasher, RafsDigest};
use nydus_utils::{root_tracer, timing_tracer, try_round_up_4k};
use nydus_utils::{div_round_up, root_tracer, timing_tracer, try_round_up_4k};

use super::bootstrap::STARGZ_DEFAULT_BLOCK_SIZE;
use super::node::Node;
Expand Down Expand Up @@ -102,7 +102,24 @@ impl Node {
// Safe to unwrap() because we have u32 for child count.
self.inode.set_size(try_round_up_4k(d_size).unwrap());
}
self.set_inode_blocks();
self.v5_set_inode_blocks();
}

/// Calculate and set `i_blocks` for inode.
///
/// In order to support repeatable build, we can't reuse `i_blocks` from source filesystems,
/// so let's calculate it by ourself for stable `i_block`.
///
/// Normal filesystem includes the space occupied by Xattr into the directory size,
/// let's follow the normal behavior.
pub fn v5_set_inode_blocks(&mut self) {
// Set inode blocks for RAFS v5 inode, v6 will calculate it at runtime.
if let InodeWrapper::V5(_) = self.inode {
self.inode.set_blocks(div_round_up(
self.inode.size() + self.info.xattrs.aligned_size_v5() as u64,
512,
));
}
}
}

Expand Down
26 changes: 20 additions & 6 deletions rafs/src/builder/tarball.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ impl<'a> TarballTreeBuilder<'a> {
}

// Update inode.i_blocks for RAFS v5.
if !entry_type.is_dir() {
node.set_inode_blocks();
if self.ctx.fs_version == RafsVersion::V5 && !entry_type.is_dir() {
node.v5_set_inode_blocks();
}

Ok(node)
Expand Down Expand Up @@ -466,10 +466,24 @@ impl<'a> TarballTreeBuilder<'a> {

fn make_lost_dirs<P: AsRef<Path>>(&mut self, path: P, nodes: &mut Vec<Node>) -> Result<()> {
if let Some(parent_path) = path.as_ref().parent() {
if !self.path_inode_map.contains_key(parent_path) {
self.make_lost_dirs(parent_path, nodes)?;
let node = self.create_directory(parent_path, nodes.len())?;
nodes.push(node);
match self.path_inode_map.get(parent_path) {
Some((i, idx)) => {
if !nodes[*idx].is_dir() {
panic!(
"tarball: existing inode is not a directory {} {} {}",
i,
nodes.len(),
nodes[*idx].is_dir()
);
}
}
None => {
if !self.path_inode_map.contains_key(parent_path) {
self.make_lost_dirs(parent_path, nodes)?;
let node = self.create_directory(parent_path, nodes.len())?;
nodes.push(node);
}
}
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/bin/nydus-image/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,12 @@ impl Command {
.unwrap_or_default()
.parse()?;
let blob_data_size = Self::get_blob_size(matches, conversion_type)?;
let features = Features::try_from(
matches
.get_one::<String>("features")
.map(|s| s.as_str())
.unwrap_or_default(),
)?;

match conversion_type {
ConversionType::DirectoryToRafs => {
Expand Down Expand Up @@ -770,12 +776,6 @@ impl Command {
}
}

let features = Features::try_from(
matches
.get_one::<String>("features")
.map(|s| s.as_str())
.unwrap_or_default(),
)?;
if features.is_enabled(Feature::BlobToc) && version == RafsVersion::V5 {
bail!("`--features blob-toc` can't be used with `--version 5` ");
}
Expand Down

0 comments on commit 3691e5d

Please sign in to comment.