Skip to content

Commit 81592f6

Browse files
committed
rafs: enhance RAFS FUSE implementation to support TARFS
Enhance RAFS FUSE implementation to support RAFS filesystms in TARFS mode. Signed-off-by: Jiang Liu <[email protected]>
1 parent d8d67a8 commit 81592f6

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

rafs/src/fs.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use nydus_utils::{
3939
};
4040

4141
use crate::metadata::{
42-
Inode, RafsInode, RafsInodeWalkAction, RafsSuper, RafsSuperFlags, RafsSuperMeta, DOT, DOTDOT,
42+
Inode, RafsInode, RafsInodeWalkAction, RafsSuper, RafsSuperMeta, DOT, DOTDOT,
4343
};
4444
use crate::{RafsError, RafsIoReader, RafsResult};
4545

@@ -616,10 +616,6 @@ impl FileSystem for Rafs {
616616
}
617617

618618
let real_size = cmp::min(size as u64, inode_size - offset);
619-
if self.sb.meta.flags.contains(RafsSuperFlags::TARTFS_MODE) {
620-
return Err(enosys!("rafs: `TARFS` mode is not supported by FUSE yet"));
621-
}
622-
623619
let mut result = 0;
624620
let mut descs = inode.alloc_bio_vecs(&self.device, offset, real_size as usize, true)?;
625621
assert!(!descs.is_empty() && !descs[0].is_empty());

rafs/src/metadata/direct_v6.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ use crate::metadata::layout::v5::RafsV5ChunkInfo;
4040
use crate::metadata::layout::v6::{
4141
rafsv6_load_blob_extra_info, recover_namespace, RafsV6BlobTable, RafsV6Dirent,
4242
RafsV6InodeChunkAddr, RafsV6InodeCompact, RafsV6InodeExtended, RafsV6OndiskInode,
43-
RafsV6XattrEntry, RafsV6XattrIbodyHeader, EROFS_BLOCK_SIZE_4096, EROFS_BLOCK_SIZE_512,
44-
EROFS_INODE_CHUNK_BASED, EROFS_INODE_FLAT_INLINE, EROFS_INODE_FLAT_PLAIN,
43+
RafsV6XattrEntry, RafsV6XattrIbodyHeader, EROFS_BLOCK_BITS_9, EROFS_BLOCK_SIZE_4096,
44+
EROFS_BLOCK_SIZE_512, EROFS_INODE_CHUNK_BASED, EROFS_INODE_FLAT_INLINE, EROFS_INODE_FLAT_PLAIN,
4545
EROFS_INODE_SLOT_SIZE, EROFS_I_DATALAYOUT_BITS, EROFS_I_VERSION_BIT, EROFS_I_VERSION_BITS,
4646
};
4747
use crate::metadata::layout::{bytes_to_os_str, MetaRange, XattrName, XattrValue};
@@ -525,6 +525,7 @@ impl OndiskInodeWrapper {
525525
i.mode() as u32 & libc::S_IFMT as u32
526526
}
527527

528+
#[allow(clippy::too_many_arguments)]
528529
fn make_chunk_io(
529530
&self,
530531
state: &Guard<Arc<DirectMappingState>>,
@@ -533,6 +534,8 @@ impl OndiskInodeWrapper {
533534
content_offset: u32,
534535
content_len: u32,
535536
user_io: bool,
537+
is_tarfs_mode: bool,
538+
is_tail: bool,
536539
) -> Option<BlobIoDesc> {
537540
let blob_index = chunk_addr.blob_index();
538541
let chunk_index = chunk_addr.blob_ci_index();
@@ -545,9 +548,29 @@ impl OndiskInodeWrapper {
545548
);
546549
None
547550
}
548-
Ok(blob) => device
549-
.create_io_chunk(blob.blob_index(), chunk_index)
550-
.map(|v| BlobIoDesc::new(blob, v, content_offset, content_len, user_io)),
551+
Ok(blob) => {
552+
if is_tarfs_mode {
553+
let offset = (chunk_addr.block_addr() as u64) << EROFS_BLOCK_BITS_9;
554+
let size = if is_tail {
555+
(self.size() % self.chunk_size() as u64) as u32
556+
} else {
557+
self.chunk_size()
558+
};
559+
let chunk = PlainChunkInfoV6::new(blob_index, chunk_index, offset, size);
560+
let chunk = Arc::new(chunk) as Arc<dyn BlobChunkInfo>;
561+
Some(BlobIoDesc::new(
562+
blob,
563+
chunk.into(),
564+
content_offset,
565+
content_len,
566+
user_io,
567+
))
568+
} else {
569+
device
570+
.create_io_chunk(blob.blob_index(), chunk_index)
571+
.map(|v| BlobIoDesc::new(blob, v, content_offset, content_len, user_io))
572+
}
573+
}
551574
}
552575
}
553576

@@ -777,6 +800,9 @@ impl RafsInode for OndiskInodeWrapper {
777800
return Ok(vec);
778801
}
779802

803+
let mut curr_chunk_index = head_chunk_index as u32;
804+
let tail_chunk_index = self.get_chunk_count() - 1;
805+
let is_tarfs_mode = state.is_tarfs();
780806
let content_offset = (offset % chunk_size as u64) as u32;
781807
let mut left = std::cmp::min(self.size() - offset, size as u64) as u32;
782808
let mut content_len = std::cmp::min(chunk_size - content_offset, left);
@@ -788,6 +814,8 @@ impl RafsInode for OndiskInodeWrapper {
788814
content_offset,
789815
content_len,
790816
user_io,
817+
is_tarfs_mode,
818+
curr_chunk_index == tail_chunk_index,
791819
)
792820
.ok_or_else(|| einval!("failed to get chunk information"))?;
793821

@@ -797,9 +825,19 @@ impl RafsInode for OndiskInodeWrapper {
797825
if left != 0 {
798826
// Handle the rest of chunks since they shares the same content length = 0.
799827
for c in chunks.iter().skip(1) {
828+
curr_chunk_index += 1;
800829
content_len = std::cmp::min(chunk_size, left);
801830
let desc = self
802-
.make_chunk_io(&state, device, c, 0, content_len, user_io)
831+
.make_chunk_io(
832+
&state,
833+
device,
834+
c,
835+
0,
836+
content_len,
837+
user_io,
838+
is_tarfs_mode,
839+
curr_chunk_index == tail_chunk_index,
840+
)
803841
.ok_or_else(|| einval!("failed to get chunk information"))?;
804842
if desc.blob.blob_index() != descs.blob_index() {
805843
vec.push(descs);
@@ -1286,7 +1324,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
12861324
} else if state.is_tarfs() {
12871325
let blob_index = chunk_addr.blob_index();
12881326
let chunk_index = chunk_addr.blob_ci_index();
1289-
let offset = (chunk_addr.block_addr() as u64) << 9;
1327+
let offset = (chunk_addr.block_addr() as u64) << EROFS_BLOCK_BITS_9;
12901328
let size = if idx == self.get_chunk_count() - 1 {
12911329
(self.size() % self.chunk_size() as u64) as u32
12921330
} else {

0 commit comments

Comments
 (0)