MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / execute_async

Method execute_async

block/src/request.rs:237–503  ·  view source on GitHub ↗
(
        &mut self,
        mem: &vm_memory::GuestMemoryMmap<B>,
        disk_nsectors: u64,
        disk_image: &mut dyn AsyncIo,
        serial: &[u8],
        disable_sector0_writes: bool,
       

Source from the content-addressed store, hash-verified

235 }
236
237 pub fn execute_async<B: Bitmap + 'static>(
238 &mut self,
239 mem: &vm_memory::GuestMemoryMmap<B>,
240 disk_nsectors: u64,
241 disk_image: &mut dyn AsyncIo,
242 serial: &[u8],
243 disable_sector0_writes: bool,
244 user_data: u64,
245 ) -> Result<ExecuteAsync, ExecuteError> {
246 let sector = self.sector;
247 let request_type = self.request_type;
248 let offset = (sector << SECTOR_SHIFT) as libc::off_t;
249 let alignment = disk_image.alignment();
250
251 self.check_data_bounds(disk_nsectors)?;
252
253 let mut iovecs: SmallVec<[libc::iovec; DEFAULT_DESCRIPTOR_VEC_SIZE]> =
254 SmallVec::with_capacity(self.data_descriptors.len());
255 for &(data_addr, data_len) in &self.data_descriptors {
256 let _: u32 = data_len; // compiler-checked documentation
257 const _: () = assert!(
258 core::mem::size_of::<u32>() <= core::mem::size_of::<usize>(),
259 "unsupported platform"
260 );
261 if data_len == 0 {
262 continue;
263 }
264 let data_len = data_len as usize;
265
266 let origin_ptr = mem
267 .get_slice(data_addr, data_len)
268 .map_err(ExecuteError::GetHostAddress)?;
269 assert!(origin_ptr.len() >= data_len);
270 let origin_ptr = origin_ptr.ptr_guard_mut();
271
272 // O_DIRECT requires buffer addresses to be aligned to the
273 // backend device's logical block size. In case it's not properly
274 // aligned, an intermediate buffer is created with the correct
275 // alignment, and a copy from/to the origin buffer is performed,
276 // depending on the type of operation.
277 let iov_base = if (origin_ptr.as_ptr() as u64).is_multiple_of(alignment) {
278 origin_ptr.as_ptr().cast()
279 } else {
280 let mut aligned_op = AlignedOperation::new(data_addr, data_len, alignment as usize)
281 .map_err(ExecuteError::TemporaryBufferAllocation)?;
282
283 // We need to perform the copy beforehand in case we're writing
284 // data out.
285 if request_type == RequestType::Out {
286 mem.read_slice(aligned_op.as_bytes_mut(), data_addr)
287 .map_err(ExecuteError::Read)?;
288 }
289
290 let aligned_ptr = aligned_op.as_mut_ptr();
291 self.aligned_operations.push(aligned_op);
292
293 aligned_ptr.cast()
294 };

Callers 1

process_queue_submitMethod · 0.80

Calls 13

newFunction · 0.85
check_data_boundsMethod · 0.80
as_bytes_mutMethod · 0.80
as_mut_ptrMethod · 0.80
alignmentMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45
read_vectoredMethod · 0.45
write_vectoredMethod · 0.45
fsyncMethod · 0.45
punch_holeMethod · 0.45

Tested by

no test coverage detected