@@ -785,6 +785,7 @@ pub(crate) fn fake_read_write_queue<const QUEUE_SIZE: usize>(
785785 handler : impl FnOnce ( Vec < u8 > ) -> Vec < u8 > ,
786786) {
787787 use core:: { ops:: Deref , slice} ;
788+ use zerocopy:: LayoutVerified ;
788789
789790 let available_ring = queue_driver_area as * const AvailRing < QUEUE_SIZE > ;
790791 let used_ring = queue_device_area as * mut UsedRing < QUEUE_SIZE > ;
@@ -800,47 +801,99 @@ pub(crate) fn fake_read_write_queue<const QUEUE_SIZE: usize>(
800801 let head_descriptor_index = ( * available_ring) . ring [ next_slot as usize ] ;
801802 let mut descriptor = & ( * descriptors) [ head_descriptor_index as usize ] ;
802803
803- // Loop through all input descriptors in the chain, reading data from them.
804- let mut input = Vec :: new ( ) ;
805- while !descriptor. flags . contains ( DescFlags :: WRITE ) {
806- input. extend_from_slice ( slice:: from_raw_parts (
807- descriptor. addr as * const u8 ,
808- descriptor. len as usize ,
809- ) ) ;
804+ let input_length;
805+ let output;
806+ if descriptor. flags . contains ( DescFlags :: INDIRECT ) {
807+ // The descriptor shouldn't have any other flags if it is indirect.
808+ assert_eq ! ( descriptor. flags, DescFlags :: INDIRECT ) ;
809+
810+ // Loop through all input descriptors in the indirect descriptor list, reading data from
811+ // them.
812+ let indirect_descriptor_list: & [ Descriptor ] = LayoutVerified :: new_slice (
813+ slice:: from_raw_parts ( descriptor. addr as * const u8 , descriptor. len as usize ) ,
814+ )
815+ . unwrap ( )
816+ . into_slice ( ) ;
817+ let mut input = Vec :: new ( ) ;
818+ let mut indirect_descriptor_index = 0 ;
819+ while indirect_descriptor_index < indirect_descriptor_list. len ( ) {
820+ let indirect_descriptor = & indirect_descriptor_list[ indirect_descriptor_index] ;
821+ if indirect_descriptor. flags . contains ( DescFlags :: WRITE ) {
822+ break ;
823+ }
810824
811- if let Some ( next) = descriptor. next ( ) {
812- descriptor = & ( * descriptors) [ next as usize ] ;
813- } else {
814- break ;
825+ input. extend_from_slice ( slice:: from_raw_parts (
826+ indirect_descriptor. addr as * const u8 ,
827+ indirect_descriptor. len as usize ,
828+ ) ) ;
829+
830+ indirect_descriptor_index += 1 ;
815831 }
816- }
817- let input_length = input. len ( ) ;
832+ input_length = input. len ( ) ;
818833
819- // Let the test handle the request.
820- let output = handler ( input) ;
834+ // Let the test handle the request.
835+ output = handler ( input) ;
821836
822- // Write the response to the remaining descriptors.
823- let mut remaining_output = output. deref ( ) ;
824- if descriptor . flags . contains ( DescFlags :: WRITE ) {
825- loop {
826- assert ! ( descriptor . flags. contains( DescFlags :: WRITE ) ) ;
837+ // Write the response to the remaining descriptors.
838+ let mut remaining_output = output. deref ( ) ;
839+ while indirect_descriptor_index < indirect_descriptor_list . len ( ) {
840+ let indirect_descriptor = & indirect_descriptor_list [ indirect_descriptor_index ] ;
841+ assert ! ( indirect_descriptor . flags. contains( DescFlags :: WRITE ) ) ;
827842
828- let length_to_write = min ( remaining_output. len ( ) , descriptor . len as usize ) ;
843+ let length_to_write = min ( remaining_output. len ( ) , indirect_descriptor . len as usize ) ;
829844 ptr:: copy (
830845 remaining_output. as_ptr ( ) ,
831- descriptor . addr as * mut u8 ,
846+ indirect_descriptor . addr as * mut u8 ,
832847 length_to_write,
833848 ) ;
834849 remaining_output = & remaining_output[ length_to_write..] ;
835850
851+ indirect_descriptor_index += 1 ;
852+ }
853+ assert_eq ! ( remaining_output. len( ) , 0 ) ;
854+ } else {
855+ // Loop through all input descriptors in the chain, reading data from them.
856+ let mut input = Vec :: new ( ) ;
857+ while !descriptor. flags . contains ( DescFlags :: WRITE ) {
858+ input. extend_from_slice ( slice:: from_raw_parts (
859+ descriptor. addr as * const u8 ,
860+ descriptor. len as usize ,
861+ ) ) ;
862+
836863 if let Some ( next) = descriptor. next ( ) {
837864 descriptor = & ( * descriptors) [ next as usize ] ;
838865 } else {
839866 break ;
840867 }
841868 }
869+ input_length = input. len ( ) ;
870+
871+ // Let the test handle the request.
872+ output = handler ( input) ;
873+
874+ // Write the response to the remaining descriptors.
875+ let mut remaining_output = output. deref ( ) ;
876+ if descriptor. flags . contains ( DescFlags :: WRITE ) {
877+ loop {
878+ assert ! ( descriptor. flags. contains( DescFlags :: WRITE ) ) ;
879+
880+ let length_to_write = min ( remaining_output. len ( ) , descriptor. len as usize ) ;
881+ ptr:: copy (
882+ remaining_output. as_ptr ( ) ,
883+ descriptor. addr as * mut u8 ,
884+ length_to_write,
885+ ) ;
886+ remaining_output = & remaining_output[ length_to_write..] ;
887+
888+ if let Some ( next) = descriptor. next ( ) {
889+ descriptor = & ( * descriptors) [ next as usize ] ;
890+ } else {
891+ break ;
892+ }
893+ }
894+ }
895+ assert_eq ! ( remaining_output. len( ) , 0 ) ;
842896 }
843- assert_eq ! ( remaining_output. len( ) , 0 ) ;
844897
845898 // Mark the buffer as used.
846899 ( * used_ring) . ring [ next_slot as usize ] . id = head_descriptor_index as u32 ;
0 commit comments