@@ -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 } ;
@@ -525,6 +525,7 @@ impl OndiskInodeWrapper {
525
525
i. mode ( ) as u32 & libc:: S_IFMT as u32
526
526
}
527
527
528
+ #[ allow( clippy:: too_many_arguments) ]
528
529
fn make_chunk_io (
529
530
& self ,
530
531
state : & Guard < Arc < DirectMappingState > > ,
@@ -533,6 +534,8 @@ impl OndiskInodeWrapper {
533
534
content_offset : u32 ,
534
535
content_len : u32 ,
535
536
user_io : bool ,
537
+ is_tarfs_mode : bool ,
538
+ is_tail : bool ,
536
539
) -> Option < BlobIoDesc > {
537
540
let blob_index = chunk_addr. blob_index ( ) ;
538
541
let chunk_index = chunk_addr. blob_ci_index ( ) ;
@@ -545,9 +548,29 @@ impl OndiskInodeWrapper {
545
548
) ;
546
549
None
547
550
}
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
+ }
551
574
}
552
575
}
553
576
@@ -777,6 +800,9 @@ impl RafsInode for OndiskInodeWrapper {
777
800
return Ok ( vec) ;
778
801
}
779
802
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 ( ) ;
780
806
let content_offset = ( offset % chunk_size as u64 ) as u32 ;
781
807
let mut left = std:: cmp:: min ( self . size ( ) - offset, size as u64 ) as u32 ;
782
808
let mut content_len = std:: cmp:: min ( chunk_size - content_offset, left) ;
@@ -788,6 +814,8 @@ impl RafsInode for OndiskInodeWrapper {
788
814
content_offset,
789
815
content_len,
790
816
user_io,
817
+ is_tarfs_mode,
818
+ curr_chunk_index == tail_chunk_index,
791
819
)
792
820
. ok_or_else ( || einval ! ( "failed to get chunk information" ) ) ?;
793
821
@@ -797,9 +825,19 @@ impl RafsInode for OndiskInodeWrapper {
797
825
if left != 0 {
798
826
// Handle the rest of chunks since they shares the same content length = 0.
799
827
for c in chunks. iter ( ) . skip ( 1 ) {
828
+ curr_chunk_index += 1 ;
800
829
content_len = std:: cmp:: min ( chunk_size, left) ;
801
830
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
+ )
803
841
. ok_or_else ( || einval ! ( "failed to get chunk information" ) ) ?;
804
842
if desc. blob . blob_index ( ) != descs. blob_index ( ) {
805
843
vec. push ( descs) ;
@@ -1286,7 +1324,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
1286
1324
} else if state. is_tarfs ( ) {
1287
1325
let blob_index = chunk_addr. blob_index ( ) ;
1288
1326
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 ;
1290
1328
let size = if idx == self . get_chunk_count ( ) - 1 {
1291
1329
( self . size ( ) % self . chunk_size ( ) as u64 ) as u32
1292
1330
} else {
0 commit comments