From 6389191185082ebf011bc8c6d183789f1b072ff7 Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:05:13 +0800 Subject: [PATCH 1/7] rafs/v6: add a method inodes_count for rafs v6 Signed-off-by: Changwei Ge --- rafs/src/metadata/layout/v6.rs | 5 +++++ rafs/src/metadata/md_v6.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/rafs/src/metadata/layout/v6.rs b/rafs/src/metadata/layout/v6.rs index 2cfa1497c3d..10e1aaa4d99 100644 --- a/rafs/src/metadata/layout/v6.rs +++ b/rafs/src/metadata/layout/v6.rs @@ -219,6 +219,11 @@ impl RafsV6SuperBlock { self.s_inos = inos.to_le(); } + /// Get total inodes count of this Rafs + pub fn inodes_count(&self) -> u64 { + self.s_inos + } + /// Set number of logical blocks. pub fn set_blocks(&mut self, blocks: u32) { self.s_blocks = blocks.to_le(); diff --git a/rafs/src/metadata/md_v6.rs b/rafs/src/metadata/md_v6.rs index 0626d333862..08c42464002 100644 --- a/rafs/src/metadata/md_v6.rs +++ b/rafs/src/metadata/md_v6.rs @@ -40,6 +40,7 @@ impl RafsSuper { self.meta.blob_table_size = ext_sb.blob_table_size(); self.meta.chunk_table_offset = ext_sb.chunk_table_offset(); self.meta.chunk_table_size = ext_sb.chunk_table_size(); + self.meta.inodes_count = sb.inodes_count(); self.meta.flags = RafsSuperFlags::from_bits(ext_sb.flags()) .ok_or_else(|| einval!(format!("invalid super flags {:x}", ext_sb.flags())))?; From 8fd5dd627be0048d73f504478adf650a9ab6422c Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:06:58 +0800 Subject: [PATCH 2/7] rafs: use real inode number when get path from ino rafs v5 han v6 has different root inode numbers. Signed-off-by: Changwei Ge --- rafs/src/metadata/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rafs/src/metadata/mod.rs b/rafs/src/metadata/mod.rs index 1a735a9284d..ce9bb57089b 100644 --- a/rafs/src/metadata/mod.rs +++ b/rafs/src/metadata/mod.rs @@ -20,7 +20,7 @@ use std::time::Duration; use anyhow::bail; use fuse_backend_rs::abi::fuse_abi::Attr; -use fuse_backend_rs::api::filesystem::{Entry, ROOT_ID}; +use fuse_backend_rs::api::filesystem::Entry; use nydus_utils::compress; use nydus_utils::digest::{self, RafsDigest}; use serde::Serialize; @@ -550,7 +550,7 @@ impl RafsSuper { /// Convert an inode number to a file path. pub fn path_from_ino(&self, ino: Inode) -> Result { - if ino == ROOT_ID { + if ino == self.superblock.root_ino() { return Ok(self.get_inode(ino, false)?.name().into()); } @@ -563,7 +563,7 @@ impl RafsSuper { let e: PathBuf = inode.name().into(); path = e.join(path); - if inode.ino() == ROOT_ID { + if inode.ino() == self.superblock.root_ino() { break; } else { cur_ino = inode.parent(); From d2ea78333b94ae5deca62fcdc0c46e753cfd93c6 Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:08:24 +0800 Subject: [PATCH 3/7] nydus-image: only validate inode size when it's regular file Because root dir's size is zero before gathering prefetching files. Signed-off-by: Changwei Ge --- src/bin/nydus-image/core/prefetch.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bin/nydus-image/core/prefetch.rs b/src/bin/nydus-image/core/prefetch.rs index b2c2fb39aea..62e9d35ddb1 100644 --- a/src/bin/nydus-image/core/prefetch.rs +++ b/src/bin/nydus-image/core/prefetch.rs @@ -123,7 +123,11 @@ impl Prefetch { let index = node.index; let mut remove_node = false; - if self.policy == PrefetchPolicy::None || self.disabled || node.inode.size() == 0 { + // Newly created root inode of this rafs has zero size + if self.policy == PrefetchPolicy::None + || self.disabled + || (node.inode.is_reg() && node.inode.size() == 0) + { return; } From 69aa21c5b609137225587c126ad47ec3551b56c2 Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:10:18 +0800 Subject: [PATCH 4/7] nydus-image: fill readahead patterns with node index Rafs v6 can't decide each inode number when walking and building nodes tree. So record those prefetching files' index in nodes array in readahead patterns. Signed-off-by: Changwei Ge --- src/bin/nydus-image/core/prefetch.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bin/nydus-image/core/prefetch.rs b/src/bin/nydus-image/core/prefetch.rs index 62e9d35ddb1..dd02bbd9784 100644 --- a/src/bin/nydus-image/core/prefetch.rs +++ b/src/bin/nydus-image/core/prefetch.rs @@ -119,7 +119,6 @@ impl Prefetch { pub fn insert_if_need(&mut self, node: &Node) { let path = node.target(); - let inode = node.inode.ino(); let index = node.index; let mut remove_node = false; @@ -135,11 +134,13 @@ impl Prefetch { // As path is canonicalized, it should be reliable. if path == f { if self.policy == PrefetchPolicy::Fs { - *v = Some(inode); + *v = Some(index); } self.readahead_files.insert(path.clone(), index); } else if path.starts_with(f) { + // FIXME: path may not exist in prefetch pattern, no need to remove it from readahead_patterns remove_node = true; + debug!("remove path {:?}", path); self.readahead_files.insert(path.clone(), index); } } @@ -168,6 +169,7 @@ impl Prefetch { if self.policy == PrefetchPolicy::Fs { let mut prefetch_table = RafsV5PrefetchTable::new(); for i in self.readahead_patterns.values().filter_map(|v| *v) { + // Rafs v5 has inode number equal to index. prefetch_table.add_entry(i as u32); } Some(prefetch_table) From 5ee192823039ea6001ecba24c1cf01c466d867ce Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:13:29 +0800 Subject: [PATCH 5/7] nydus-image/inspect: print more info about rafs layout Signed-off-by: Changwei Ge --- rafs/src/metadata/direct_v6.rs | 8 ++++---- src/bin/nydus-image/inspect.rs | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rafs/src/metadata/direct_v6.rs b/rafs/src/metadata/direct_v6.rs index e64b1e2bef0..ac8ff25b6e6 100644 --- a/rafs/src/metadata/direct_v6.rs +++ b/rafs/src/metadata/direct_v6.rs @@ -1098,7 +1098,7 @@ impl RafsInode for OndiskInodeWrapper { /// # Safety /// It depends on Self::validate() to ensure valid memory layout. fn name(&self) -> OsString { - let mut curr_name = OsString::from(""); + let mut cur_name = OsString::from(""); match self.name.borrow().as_ref() { Some(name) => return name.clone(), None => { @@ -1113,7 +1113,7 @@ impl RafsInode for OndiskInodeWrapper { 0, &mut |inode: Option>, name: OsString, ino, offset| { if cur_ino == ino { - curr_name = name; + cur_name = name; return Ok(PostWalkAction::Break); } Ok(PostWalkAction::Continue) @@ -1122,8 +1122,8 @@ impl RafsInode for OndiskInodeWrapper { .unwrap(); } } - *self.name.borrow_mut() = Some(curr_name.clone()); - curr_name + *self.name.borrow_mut() = Some(cur_name.clone()); + cur_name } // RafsV5 flags, not used by v6, return 0 fn flags(&self) -> u64 { diff --git a/src/bin/nydus-image/inspect.rs b/src/bin/nydus-image/inspect.rs index 1884c62ca0f..cdf660d08bb 100644 --- a/src/bin/nydus-image/inspect.rs +++ b/src/bin/nydus-image/inspect.rs @@ -65,12 +65,14 @@ impl RafsInspector { r#" Version: {version} Inodes Count: {inodes_count} - Chunk Size: {chunk_size} + Chunk Size: {chunk_size}KB + Root Inode: {root_inode} Flags: {flags}"#, - version = self.rafs_meta.meta.version, + version = self.rafs_meta.meta.version >> 8, inodes_count = self.rafs_meta.meta.inodes_count, - chunk_size = self.rafs_meta.meta.chunk_size, + chunk_size = self.rafs_meta.meta.chunk_size / 1024, flags = self.rafs_meta.meta.flags, + root_inode = self.rafs_meta.superblock.root_ino(), ); None }; @@ -288,7 +290,7 @@ Compressed Size: {compressed_size} Some(value) } else { println!( - "Prefetched Files: {}", + "Total Prefetching Files: {}", self.rafs_meta.meta.prefetch_table_entries ); for ino in prefetch_inos { From 6c78cd0de409adc840f584f2aac61e21277c36b4 Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 12:14:05 +0800 Subject: [PATCH 6/7] nyuds-image: only set root ino for rafs v5 Signed-off-by: Changwei Ge --- src/bin/nydus-image/core/bootstrap.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bin/nydus-image/core/bootstrap.rs b/src/bin/nydus-image/core/bootstrap.rs index e3c72a9abd0..be892ea8510 100644 --- a/src/bin/nydus-image/core/bootstrap.rs +++ b/src/bin/nydus-image/core/bootstrap.rs @@ -61,7 +61,10 @@ impl Bootstrap { tree: &mut Tree, ) -> Result<()> { tree.node.index = RAFS_ROOT_INODE; - tree.node.inode.set_ino(RAFS_ROOT_INODE); + // Rafs v6 root inode number can't be decided until the end of dumping. + if ctx.fs_version.is_v5() { + tree.node.inode.set_ino(RAFS_ROOT_INODE); + } // Filesystem walking skips root inode within subsequent while loop, however, we allow // user to pass the source root as prefetch hint. Check it here. ctx.prefetch.insert_if_need(&tree.node); From ab354576d9c93b728e762996dbf79989e68d16ea Mon Sep 17 00:00:00 2001 From: Changwei Ge Date: Fri, 30 Sep 2022 13:03:12 +0800 Subject: [PATCH 7/7] nydus-test: explicitly set prefetch_all in rafs config By default, prefeth_all is true in rafs config. We can't verify prefetch table contents then. Signed-off-by: Changwei Ge --- contrib/nydus-test/framework/rafs.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contrib/nydus-test/framework/rafs.py b/contrib/nydus-test/framework/rafs.py index b5503062b5f..b2bb7fe0d33 100644 --- a/contrib/nydus-test/framework/rafs.py +++ b/contrib/nydus-test/framework/rafs.py @@ -196,14 +196,13 @@ def enable_fs_prefetch( threads_count=8, merging_size=128 * 1024, bandwidth_rate=0, - prefetch_all=None, + prefetch_all=False, ): self._configure_rafs("fs_prefetch.enable", True) self._configure_rafs("fs_prefetch.threads_count", threads_count) self._configure_rafs("fs_prefetch.merging_size", merging_size) self._configure_rafs("fs_prefetch.bandwidth_rate", bandwidth_rate) - if prefetch_all is not None: - self._configure_rafs("fs_prefetch.prefetch_all", prefetch_all) + self._configure_rafs("fs_prefetch.prefetch_all", prefetch_all) return self