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 c45bf90
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
6 changes: 1 addition & 5 deletions 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,10 +616,6 @@ impl FileSystem for Rafs {
}

let real_size = cmp::min(size as u64, inode_size - offset);
if self.sb.meta.flags.contains(RafsSuperFlags::TARTFS_MODE) {
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
52 changes: 45 additions & 7 deletions rafs/src/metadata/direct_v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ 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,
RafsV6XattrEntry, RafsV6XattrIbodyHeader, EROFS_BLOCK_BITS_9, 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::{bytes_to_os_str, MetaRange, XattrName, XattrValue};
Expand Down Expand Up @@ -525,6 +525,7 @@ impl OndiskInodeWrapper {
i.mode() as u32 & libc::S_IFMT as u32
}

#[allow(clippy::too-many-arguments)]
fn make_chunk_io(
&self,
state: &Guard<Arc<DirectMappingState>>,
Expand All @@ -533,6 +534,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 +548,29 @@ 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 = PlainChunkInfoV6::new(blob_index, chunk_index, offset, size);
let chunk = Arc::new(chunk) 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,6 +800,9 @@ impl RafsInode for OndiskInodeWrapper {
return Ok(vec);
}

let mut curr_chunk_index = head_chunk_index as u32;
let tail_chunk_index = self.get_chunk_count() - 1;
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);
Expand All @@ -788,6 +814,8 @@ impl RafsInode for OndiskInodeWrapper {
content_offset,
content_len,
user_io,
is_tarfs_mode,
curr_chunk_index == tail_chunk_index,
)
.ok_or_else(|| einval!("failed to get chunk information"))?;

Expand All @@ -797,9 +825,19 @@ impl RafsInode for OndiskInodeWrapper {
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 Down Expand Up @@ -1286,7 +1324,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 c45bf90

Please sign in to comment.