@@ -407,6 +407,7 @@ impl BlobMetaInfo {
407407 chunks : chunk_infos,
408408 base : base as * const u8 ,
409409 unmap_len : expected_size,
410+ is_stargz : blob_info. is_stargz ( ) ,
410411 } ) ;
411412
412413 Ok ( BlobMetaInfo { state } )
@@ -465,7 +466,9 @@ impl BlobMetaInfo {
465466 index += 1 ;
466467 let entry = & infos[ index] ;
467468 self . validate_chunk ( entry) ?;
468- if entry. uncompressed_offset ( ) != last_end {
469+
470+ // For stargz chunks, disable this check.
471+ if !self . state . is_stargz && entry. uncompressed_offset ( ) != last_end {
469472 return Err ( einval ! ( format!(
470473 "mismatch uncompressed {} size {} last_end {}" ,
471474 entry. uncompressed_offset( ) ,
@@ -562,7 +565,8 @@ impl BlobMetaInfo {
562565
563566 #[ inline]
564567 fn validate_chunk ( & self , entry : & BlobChunkInfoOndisk ) -> Result < ( ) > {
565- if entry. compressed_end ( ) > self . state . compressed_size
568+ // For stargz blob, self.state.compressed_size == 0, so don't validate it.
569+ if ( !self . state . is_stargz && entry. compressed_end ( ) > self . state . compressed_size )
566570 || entry. uncompressed_end ( ) > self . state . uncompressed_size
567571 {
568572 Err ( einval ! ( ) )
@@ -646,6 +650,8 @@ pub struct BlobMetaState {
646650 chunks : ManuallyDrop < Vec < BlobChunkInfoOndisk > > ,
647651 base : * const u8 ,
648652 unmap_len : usize ,
653+ /// The blob meta is for an stargz image.
654+ is_stargz : bool ,
649655}
650656
651657// // Safe to Send/Sync because the underlying data structures are readonly
@@ -671,6 +677,25 @@ impl BlobMetaState {
671677 let mut start = 0 ;
672678 let mut end = 0 ;
673679
680+ if self . is_stargz {
681+ // FIXME: since stargz chunks are not currently allocated chunk index in the order of uncompressed_offset,
682+ // a binary search is not available for now, here is a heavy overhead workaround, need to be fixed.
683+ for i in 0 ..self . chunk_count {
684+ let off = if compressed {
685+ chunks[ i as usize ] . compressed_offset ( )
686+ } else {
687+ chunks[ i as usize ] . uncompressed_offset ( )
688+ } ;
689+ if addr == off {
690+ return Ok ( i as usize ) ;
691+ }
692+ }
693+ return Err ( einval ! ( format!(
694+ "can't find stargz chunk by offset {}" ,
695+ addr,
696+ ) ) ) ;
697+ }
698+
674699 while left < right {
675700 let mid = left + size / 2 ;
676701 // SAFETY: the call is made safe by the following invariants:
@@ -799,6 +824,7 @@ mod tests {
799824 ] ) ,
800825 base : std:: ptr:: null ( ) ,
801826 unmap_len : 0 ,
827+ is_stargz : false ,
802828 } ;
803829
804830 assert_eq ! ( state. get_chunk_index_nocheck( 0 , false ) . unwrap( ) , 0 ) ;
@@ -883,6 +909,7 @@ mod tests {
883909 ] ) ,
884910 base : std:: ptr:: null ( ) ,
885911 unmap_len : 0 ,
912+ is_stargz : false ,
886913 } ;
887914 let info = BlobMetaInfo {
888915 state : Arc :: new ( state) ,
0 commit comments