Skip to content

Commit

Permalink
rafs: enhance RAFS FUSE implementation to support TARFS
Browse files Browse the repository at this point in the history
Enhance RAFS FUSE implementation to support RAFS filesystms in
TARFS mode.

Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
  • Loading branch information
jiangliu committed Mar 19, 2023
1 parent 8f1d146 commit 8b5a392
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 23 deletions.
12 changes: 11 additions & 1 deletion rafs/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -667,6 +676,7 @@ impl FileSystem for Rafs {
}
}
self.ios.latency_end(&start, Read);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Ok(result)
}
Expand Down
64 changes: 42 additions & 22 deletions rafs/src/metadata/direct_v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -533,6 +527,8 @@ impl OndiskInodeWrapper {
content_offset: u32,
content_len: u32,
user_io: bool,
is_tarfs_mode: bool,
is_tail: bool,
) -> Option<BlobIoDesc> {
let blob_index = chunk_addr.blob_index();
let chunk_index = chunk_addr.blob_ci_index();
Expand All @@ -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<dyn BlobChunkInfo>;
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))
}
}
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -816,6 +835,7 @@ impl RafsInode for OndiskInodeWrapper {
vec.push(descs)
}
assert_eq!(left, 0);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Ok(vec)
}
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 8b5a392

Please sign in to comment.