@@ -46,9 +46,7 @@ use std::ptr::copy_nonoverlapping;
46
46
47
47
use virtio_queue:: DescriptorChain ;
48
48
use 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 } ;
52
50
53
51
use super :: { Error , FileReadWriteVolatile , FileVolatileSlice , IoBuffers , Reader , Result , Writer } ;
54
52
@@ -73,28 +71,31 @@ impl<'a> Reader<'a> {
73
71
M :: Target : GuestMemory + Sized ,
74
72
{
75
73
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 (
93
94
region
94
95
. 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
+ }
98
99
99
100
Ok ( Reader {
100
101
buffers : IoBuffers {
@@ -128,28 +129,31 @@ impl<'a> VirtioFsWriter<'a> {
128
129
M :: Target : GuestMemory + Sized ,
129
130
{
130
131
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 (
148
152
region
149
153
. 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
+ }
153
157
154
158
Ok ( VirtioFsWriter {
155
159
buffers : IoBuffers {
0 commit comments