@@ -412,6 +412,7 @@ impl BlobMetaInfo {
412412 chunks : chunk_infos,
413413 base : base as * const u8 ,
414414 unmap_len : expected_size,
415+ is_stargz : blob_info. is_stargz ( ) ,
415416 } ) ;
416417
417418 Ok ( BlobMetaInfo { state } )
@@ -470,7 +471,9 @@ impl BlobMetaInfo {
470471 index += 1 ;
471472 let entry = & infos[ index] ;
472473 self . validate_chunk ( entry) ?;
473- if entry. uncompressed_offset ( ) != last_end {
474+
475+ // For stargz chunks, disable this check.
476+ if !self . state . is_stargz && entry. uncompressed_offset ( ) != last_end {
474477 return Err ( einval ! ( format!(
475478 "mismatch uncompressed {} size {} last_end {}" ,
476479 entry. uncompressed_offset( ) ,
@@ -567,7 +570,8 @@ impl BlobMetaInfo {
567570
568571 #[ inline]
569572 fn validate_chunk ( & self , entry : & BlobChunkInfoOndisk ) -> Result < ( ) > {
570- if entry. compressed_end ( ) > self . state . compressed_size
573+ // For stargz blob, self.state.compressed_size == 0, so don't validate it.
574+ if ( !self . state . is_stargz && entry. compressed_end ( ) > self . state . compressed_size )
571575 || entry. uncompressed_end ( ) > self . state . uncompressed_size
572576 {
573577 Err ( einval ! ( ) )
@@ -651,6 +655,8 @@ pub struct BlobMetaState {
651655 chunks : ManuallyDrop < Vec < BlobChunkInfoOndisk > > ,
652656 base : * const u8 ,
653657 unmap_len : usize ,
658+ /// The blob meta is for an stargz image.
659+ is_stargz : bool ,
654660}
655661
656662// // Safe to Send/Sync because the underlying data structures are readonly
@@ -676,6 +682,25 @@ impl BlobMetaState {
676682 let mut start = 0 ;
677683 let mut end = 0 ;
678684
685+ if self . is_stargz {
686+ // FIXME: since stargz chunks are not currently allocated chunk index in the order of uncompressed_offset,
687+ // a binary search is not available for now, here is a heavy overhead workaround, need to be fixed.
688+ for i in 0 ..self . chunk_count {
689+ let off = if compressed {
690+ chunks[ i as usize ] . compressed_offset ( )
691+ } else {
692+ chunks[ i as usize ] . uncompressed_offset ( )
693+ } ;
694+ if addr == off {
695+ return Ok ( i as usize ) ;
696+ }
697+ }
698+ return Err ( einval ! ( format!(
699+ "can't find stargz chunk by offset {}" ,
700+ addr,
701+ ) ) ) ;
702+ }
703+
679704 while left < right {
680705 let mid = left + size / 2 ;
681706 // SAFETY: the call is made safe by the following invariants:
@@ -804,6 +829,7 @@ mod tests {
804829 ] ) ,
805830 base : std:: ptr:: null ( ) ,
806831 unmap_len : 0 ,
832+ is_stargz : false ,
807833 } ;
808834
809835 assert_eq ! ( state. get_chunk_index_nocheck( 0 , false ) . unwrap( ) , 0 ) ;
@@ -888,6 +914,7 @@ mod tests {
888914 ] ) ,
889915 base : std:: ptr:: null ( ) ,
890916 unmap_len : 0 ,
917+ is_stargz : false ,
891918 } ;
892919 let info = BlobMetaInfo {
893920 state : Arc :: new ( state) ,
0 commit comments