diff --git a/rafs/src/fs.rs b/rafs/src/fs.rs index d4ccf3b9619..7751ed2034e 100644 --- a/rafs/src/fs.rs +++ b/rafs/src/fs.rs @@ -39,7 +39,7 @@ use nydus_utils::{ }; use crate::metadata::{ - Inode, RafsInode, RafsInodeWalkAction, RafsSuper, RafsSuperFlags, RafsSuperMeta, DOT, DOTDOT, + Inode, RafsInode, RafsInodeWalkAction, RafsSuper, RafsSuperMeta, DOT, DOTDOT, }; use crate::{RafsError, RafsIoReader, RafsResult}; @@ -616,11 +616,20 @@ impl FileSystem for Rafs { } let real_size = cmp::min(size as u64, inode_size - offset); + /* if self.sb.meta.flags.contains(RafsSuperFlags::TARTFS_MODE) { + let chunk_idx = offset as u32; + let blob_idx = offset; + if inode.get_chunk_count() <= chunk_idx { + recorder.mark_success(0); + return Ok(0); + } return Err(enosys!("rafs: `TARFS` mode is not supported by FUSE yet")); } + */ let mut result = 0; + //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< let mut descs = inode.alloc_bio_vecs(&self.device, offset, real_size as usize, true)?; assert!(!descs.is_empty() && !descs[0].is_empty()); @@ -667,6 +676,7 @@ impl FileSystem for Rafs { } } self.ios.latency_end(&start, Read); + //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ok(result) } diff --git a/rafs/src/metadata/direct_v6.rs b/rafs/src/metadata/direct_v6.rs index fedcfd9b92c..8be02ce6c4b 100644 --- a/rafs/src/metadata/direct_v6.rs +++ b/rafs/src/metadata/direct_v6.rs @@ -37,13 +37,7 @@ use nydus_utils::filemap::{clone_file, FileMapState}; use nydus_utils::{digest::RafsDigest, div_round_up, round_up}; use crate::metadata::layout::v5::RafsV5ChunkInfo; -use crate::metadata::layout::v6::{ - rafsv6_load_blob_extra_info, recover_namespace, RafsV6BlobTable, RafsV6Dirent, - RafsV6InodeChunkAddr, RafsV6InodeCompact, RafsV6InodeExtended, RafsV6OndiskInode, - RafsV6XattrEntry, RafsV6XattrIbodyHeader, EROFS_BLOCK_SIZE_4096, EROFS_BLOCK_SIZE_512, - EROFS_INODE_CHUNK_BASED, EROFS_INODE_FLAT_INLINE, EROFS_INODE_FLAT_PLAIN, - EROFS_INODE_SLOT_SIZE, EROFS_I_DATALAYOUT_BITS, EROFS_I_VERSION_BIT, EROFS_I_VERSION_BITS, -}; +use crate::metadata::layout::v6::{rafsv6_load_blob_extra_info, recover_namespace, RafsV6BlobTable, RafsV6Dirent, RafsV6InodeChunkAddr, RafsV6InodeCompact, RafsV6InodeExtended, RafsV6OndiskInode, RafsV6XattrEntry, RafsV6XattrIbodyHeader, EROFS_BLOCK_SIZE_4096, EROFS_BLOCK_SIZE_512, EROFS_INODE_CHUNK_BASED, EROFS_INODE_FLAT_INLINE, EROFS_INODE_FLAT_PLAIN, EROFS_INODE_SLOT_SIZE, EROFS_I_DATALAYOUT_BITS, EROFS_I_VERSION_BIT, EROFS_I_VERSION_BITS, EROFS_BLOCK_BITS_9}; use crate::metadata::layout::{bytes_to_os_str, MetaRange, XattrName, XattrValue}; use crate::metadata::{ Attr, Entry, Inode, RafsBlobExtraInfo, RafsInode, RafsInodeWalkAction, RafsInodeWalkHandler, @@ -533,6 +527,8 @@ impl OndiskInodeWrapper { content_offset: u32, content_len: u32, user_io: bool, + is_tarfs_mode: bool, + is_tail: bool, ) -> Option { let blob_index = chunk_addr.blob_index(); let chunk_index = chunk_addr.blob_ci_index(); @@ -545,9 +541,22 @@ impl OndiskInodeWrapper { ); None } - Ok(blob) => device - .create_io_chunk(blob.blob_index(), chunk_index) - .map(|v| BlobIoDesc::new(blob, v, content_offset, content_len, user_io)), + Ok(blob) => { + if is_tarfs_mode { + let offset = (chunk_addr.block_addr() as u64) << EROFS_BLOCK_BITS_9; + let size = if is_tail { + (self.size() % self.chunk_size() as u64) as u32 + } else { + self.chunk_size() + }; + let chunk = Arc::new(PlainChunkInfoV6::new(blob_index, chunk_index, offset, size)) as Arc; + Some(BlobIoDesc::new(blob, chunk.into(), content_offset, content_len, user_io)) + } else { + device + .create_io_chunk(blob.blob_index(), chunk_index) + .map(|v| BlobIoDesc::new(blob, v, content_offset, content_len, user_io)) + } + } } } @@ -777,29 +786,39 @@ impl RafsInode for OndiskInodeWrapper { return Ok(vec); } + let tail_chunk_index = self.get_chunk_count() - 1; + let mut curr_chunk_index = head_chunk_index as u32; + let is_tarfs_mode = state.is_tarfs(); let content_offset = (offset % chunk_size as u64) as u32; let mut left = std::cmp::min(self.size() - offset, size as u64) as u32; let mut content_len = std::cmp::min(chunk_size - content_offset, left); - let desc = self - .make_chunk_io( - &state, - device, - &chunks[0], - content_offset, - content_len, - user_io, - ) - .ok_or_else(|| einval!("failed to get chunk information"))?; + let desc = + self + .make_chunk_io( + &state, + device, + &chunks[0], + content_offset, + content_len, + user_io, + is_tarfs_mode, + curr_chunk_index == tail_chunk_index, + ) + .ok_or_else(|| einval!("failed to get chunk information"))?; + //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< let mut descs = BlobIoVec::new(desc.blob.clone()); descs.push(desc); left -= content_len; if left != 0 { // Handle the rest of chunks since they shares the same content length = 0. for c in chunks.iter().skip(1) { + curr_chunk_index -= 1; content_len = std::cmp::min(chunk_size, left); let desc = self - .make_chunk_io(&state, device, c, 0, content_len, user_io) + .make_chunk_io(&state, device, c, 0, content_len, user_io, is_tarfs_mode, + curr_chunk_index == tail_chunk_index, + ) .ok_or_else(|| einval!("failed to get chunk information"))?; if desc.blob.blob_index() != descs.blob_index() { vec.push(descs); @@ -816,6 +835,7 @@ impl RafsInode for OndiskInodeWrapper { vec.push(descs) } assert_eq!(left, 0); + //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ok(vec) } @@ -1286,7 +1306,7 @@ impl RafsInodeExt for OndiskInodeWrapper { } else if state.is_tarfs() { let blob_index = chunk_addr.blob_index(); let chunk_index = chunk_addr.blob_ci_index(); - let offset = (chunk_addr.block_addr() as u64) << 9; + let offset = (chunk_addr.block_addr() as u64) << EROFS_BLOCK_BITS_9; let size = if idx == self.get_chunk_count() - 1 { (self.size() % self.chunk_size() as u64) as u32 } else {