@@ -40,8 +40,8 @@ use crate::metadata::layout::v5::RafsV5ChunkInfo;
40
40
use crate :: metadata:: layout:: v6:: {
41
41
rafsv6_load_blob_extra_info, recover_namespace, RafsV6BlobTable , RafsV6Dirent ,
42
42
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 ,
45
45
EROFS_INODE_SLOT_SIZE , EROFS_I_DATALAYOUT_BITS , EROFS_I_VERSION_BIT , EROFS_I_VERSION_BITS ,
46
46
} ;
47
47
use crate :: metadata:: layout:: { bytes_to_os_str, MetaRange , XattrName , XattrValue } ;
@@ -533,6 +533,8 @@ impl OndiskInodeWrapper {
533
533
content_offset : u32 ,
534
534
content_len : u32 ,
535
535
user_io : bool ,
536
+ is_tarfs_mode : bool ,
537
+ is_tail : bool ,
536
538
) -> Option < BlobIoDesc > {
537
539
let blob_index = chunk_addr. blob_index ( ) ;
538
540
let chunk_index = chunk_addr. blob_ci_index ( ) ;
@@ -545,9 +547,29 @@ impl OndiskInodeWrapper {
545
547
) ;
546
548
None
547
549
}
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) ) ,
550
+ Ok ( blob) => {
551
+ if is_tarfs_mode {
552
+ let offset = ( chunk_addr. block_addr ( ) as u64 ) << EROFS_BLOCK_BITS_9 ;
553
+ let size = if is_tail {
554
+ ( self . size ( ) % self . chunk_size ( ) as u64 ) as u32
555
+ } else {
556
+ self . chunk_size ( )
557
+ } ;
558
+ let chunk = PlainChunkInfoV6 :: new ( blob_index, chunk_index, offset, size) ;
559
+ let chunk = Arc :: new ( chunk) as Arc < dyn BlobChunkInfo > ;
560
+ Some ( BlobIoDesc :: new (
561
+ blob,
562
+ chunk. into ( ) ,
563
+ content_offset,
564
+ content_len,
565
+ user_io,
566
+ ) )
567
+ } else {
568
+ device
569
+ . create_io_chunk ( blob. blob_index ( ) , chunk_index)
570
+ . map ( |v| BlobIoDesc :: new ( blob, v, content_offset, content_len, user_io) )
571
+ }
572
+ }
551
573
}
552
574
}
553
575
@@ -777,6 +799,9 @@ impl RafsInode for OndiskInodeWrapper {
777
799
return Ok ( vec) ;
778
800
}
779
801
802
+ let mut curr_chunk_index = head_chunk_index as u32 ;
803
+ let tail_chunk_index = self . get_chunk_count ( ) - 1 ;
804
+ let is_tarfs_mode = state. is_tarfs ( ) ;
780
805
let content_offset = ( offset % chunk_size as u64 ) as u32 ;
781
806
let mut left = std:: cmp:: min ( self . size ( ) - offset, size as u64 ) as u32 ;
782
807
let mut content_len = std:: cmp:: min ( chunk_size - content_offset, left) ;
@@ -788,6 +813,8 @@ impl RafsInode for OndiskInodeWrapper {
788
813
content_offset,
789
814
content_len,
790
815
user_io,
816
+ is_tarfs_mode,
817
+ curr_chunk_index == tail_chunk_index,
791
818
)
792
819
. ok_or_else ( || einval ! ( "failed to get chunk information" ) ) ?;
793
820
@@ -797,9 +824,19 @@ impl RafsInode for OndiskInodeWrapper {
797
824
if left != 0 {
798
825
// Handle the rest of chunks since they shares the same content length = 0.
799
826
for c in chunks. iter ( ) . skip ( 1 ) {
827
+ curr_chunk_index += 1 ;
800
828
content_len = std:: cmp:: min ( chunk_size, left) ;
801
829
let desc = self
802
- . make_chunk_io ( & state, device, c, 0 , content_len, user_io)
830
+ . make_chunk_io (
831
+ & state,
832
+ device,
833
+ c,
834
+ 0 ,
835
+ content_len,
836
+ user_io,
837
+ is_tarfs_mode,
838
+ curr_chunk_index == tail_chunk_index,
839
+ )
803
840
. ok_or_else ( || einval ! ( "failed to get chunk information" ) ) ?;
804
841
if desc. blob . blob_index ( ) != descs. blob_index ( ) {
805
842
vec. push ( descs) ;
@@ -1286,7 +1323,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
1286
1323
} else if state. is_tarfs ( ) {
1287
1324
let blob_index = chunk_addr. blob_index ( ) ;
1288
1325
let chunk_index = chunk_addr. blob_ci_index ( ) ;
1289
- let offset = ( chunk_addr. block_addr ( ) as u64 ) << 9 ;
1326
+ let offset = ( chunk_addr. block_addr ( ) as u64 ) << EROFS_BLOCK_BITS_9 ;
1290
1327
let size = if idx == self . get_chunk_count ( ) - 1 {
1291
1328
( self . size ( ) % self . chunk_size ( ) as u64 ) as u32
1292
1329
} else {
0 commit comments