@@ -46,9 +46,7 @@ use std::ptr::copy_nonoverlapping;
4646
4747use virtio_queue:: DescriptorChain ;
4848use vm_memory:: bitmap:: { BitmapSlice , MS } ;
49- use vm_memory:: {
50- Address , ByteValued , GuestMemory , GuestMemoryRegion , MemoryRegionAddress , VolatileSlice ,
51- } ;
49+ use vm_memory:: { Address , ByteValued , GuestMemory , GuestMemoryRegion , MemoryRegionAddress } ;
5250
5351use super :: { Error , FileReadWriteVolatile , FileVolatileSlice , IoBuffers , Reader , Result , Writer } ;
5452
@@ -73,28 +71,31 @@ impl<'a> Reader<'a> {
7371 M :: Target : GuestMemory + Sized ,
7472 {
7573 let mut total_len: usize = 0 ;
76- let buffers = desc_chain
77- . readable ( )
78- . map ( |desc| {
79- // Verify that summing the descriptor sizes does not overflow.
80- // This can happen if a driver tricks a device into reading more data than
81- // fits in a `usize`.
82- total_len = total_len
83- . checked_add ( desc. len ( ) as usize )
84- . ok_or ( Error :: DescriptorChainOverflow ) ?;
85-
86- let region = mem
87- . find_region ( desc. addr ( ) )
88- . ok_or ( Error :: FindMemoryRegion ) ?;
89- let offset = desc
90- . addr ( )
91- . checked_sub ( region. start_addr ( ) . raw_value ( ) )
92- . unwrap ( ) ;
74+ // Allocate VecDeque with 64 capacity and hope it could hold all slices to avoid expending
75+ // VecDeque repeatedly.
76+ let mut buffers = VecDeque :: with_capacity ( 64 ) ;
77+ for desc in desc_chain. readable ( ) {
78+ // Verify that summing the descriptor sizes does not overflow.
79+ // This can happen if a driver tricks a device into reading more data than
80+ // fits in a `usize`.
81+ total_len = total_len
82+ . checked_add ( desc. len ( ) as usize )
83+ . ok_or ( Error :: DescriptorChainOverflow ) ?;
84+
85+ let region = mem
86+ . find_region ( desc. addr ( ) )
87+ . ok_or ( Error :: FindMemoryRegion ) ?;
88+ let offset = desc
89+ . addr ( )
90+ . checked_sub ( region. start_addr ( ) . raw_value ( ) )
91+ . unwrap ( ) ;
92+
93+ buffers. push_back (
9394 region
9495 . get_slice ( MemoryRegionAddress ( offset. raw_value ( ) ) , desc. len ( ) as usize )
95- . map_err ( Error :: GuestMemoryError )
96- } )
97- . collect :: < Result < VecDeque < VolatileSlice < ' a , MS < M :: Target > > > > > ( ) ? ;
96+ . map_err ( Error :: GuestMemoryError ) ? ,
97+ ) ;
98+ }
9899
99100 Ok ( Reader {
100101 buffers : IoBuffers {
@@ -128,28 +129,31 @@ impl<'a> VirtioFsWriter<'a> {
128129 M :: Target : GuestMemory + Sized ,
129130 {
130131 let mut total_len: usize = 0 ;
131- let buffers = desc_chain
132- . writable ( )
133- . map ( |desc| {
134- // Verify that summing the descriptor sizes does not overflow.
135- // This can happen if a driver tricks a device into writing more data than
136- // fits in a `usize`.
137- total_len = total_len
138- . checked_add ( desc. len ( ) as usize )
139- . ok_or ( Error :: DescriptorChainOverflow ) ?;
140-
141- let region = mem
142- . find_region ( desc. addr ( ) )
143- . ok_or ( Error :: FindMemoryRegion ) ?;
144- let offset = desc
145- . addr ( )
146- . checked_sub ( region. start_addr ( ) . raw_value ( ) )
147- . unwrap ( ) ;
132+ // Allocate VecDeque with 64 capacity and hope it could hold all slices to avoid expending
133+ // VecDeque repeatedly.
134+ let mut buffers = VecDeque :: with_capacity ( 64 ) ;
135+ for desc in desc_chain. writable ( ) {
136+ // Verify that summing the descriptor sizes does not overflow.
137+ // This can happen if a driver tricks a device into writing more data than
138+ // fits in a `usize`.
139+ total_len = total_len
140+ . checked_add ( desc. len ( ) as usize )
141+ . ok_or ( Error :: DescriptorChainOverflow ) ?;
142+
143+ let region = mem
144+ . find_region ( desc. addr ( ) )
145+ . ok_or ( Error :: FindMemoryRegion ) ?;
146+ let offset = desc
147+ . addr ( )
148+ . checked_sub ( region. start_addr ( ) . raw_value ( ) )
149+ . unwrap ( ) ;
150+
151+ buffers. push_back (
148152 region
149153 . get_slice ( MemoryRegionAddress ( offset. raw_value ( ) ) , desc. len ( ) as usize )
150- . map_err ( Error :: GuestMemoryError )
151- } )
152- . collect :: < Result < VecDeque < VolatileSlice < ' a , MS < M :: Target > > > > > ( ) ? ;
154+ . map_err ( Error :: GuestMemoryError ) ? ,
155+ )
156+ }
153157
154158 Ok ( VirtioFsWriter {
155159 buffers : IoBuffers {
0 commit comments