diff --git a/block/src/raw_sync.rs b/block/src/raw_sync.rs index 91ab4bac8..2c4a79c01 100644 --- a/block/src/raw_sync.rs +++ b/block/src/raw_sync.rs @@ -1,5 +1,7 @@ // Copyright © 2021 Intel Corporation // +// Copyright (c) Meta Platforms, Inc. and affiliates. +// // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause use std::collections::VecDeque; @@ -7,14 +9,14 @@ use std::os::unix::io::RawFd; use vmm_sys_util::eventfd::EventFd; -use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult}; +use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult}; use crate::sparse::{punch_hole, write_zeroes}; use crate::{SECTOR_SIZE, is_block_device}; pub struct RawFileSync { fd: RawFd, eventfd: EventFd, - completion_list: VecDeque<(u64, i32)>, + completion_list: VecDeque, alignment: u64, is_block_device: bool, } @@ -60,7 +62,8 @@ impl AsyncIo for RawFileSync { return Err(AsyncIoError::ReadVectored(std::io::Error::last_os_error())); } - self.completion_list.push_back((user_data, result as i32)); + self.completion_list + .push_back(AsyncIoCompletion::new(user_data, result as i32, None)); self.eventfd.write(1).unwrap(); Ok(()) @@ -85,7 +88,54 @@ impl AsyncIo for RawFileSync { return Err(AsyncIoError::WriteVectored(std::io::Error::last_os_error())); } - self.completion_list.push_back((user_data, result as i32)); + self.completion_list + .push_back(AsyncIoCompletion::new(user_data, result as i32, None)); + self.eventfd.write(1).unwrap(); + + Ok(()) + } + + fn submit_data_operation(&mut self, op: AsyncIoOperation) -> AsyncIoResult<()> { + let offset = op.offset(); + let is_read = op.is_read(); + let iovecs = op.iovecs(); + + let result = if is_read { + // SAFETY: the memory pointed to by `iovecs` is backed by the op, + // and valid for the kernel to write to by construction of + // AsyncIoOperation. + unsafe { + libc::preadv( + self.fd as libc::c_int, + iovecs.as_ptr(), + iovecs.len() as libc::c_int, + offset, + ) + } + } else { + // SAFETY: the memory pointed to by `iovecs` is backed by the op, + // and valid for the kernel to read from by construction of + // AsyncIoOperation. + unsafe { + libc::pwritev( + self.fd as libc::c_int, + iovecs.as_ptr(), + iovecs.len() as libc::c_int, + offset, + ) + } + }; + if result < 0 { + let error = std::io::Error::last_os_error(); + return Err(if is_read { + AsyncIoError::ReadVectored(error) + } else { + AsyncIoError::WriteVectored(error) + }); + } + + self.completion_list + .push_back(AsyncIoCompletion::from_operation(op, result as i32)); self.eventfd.write(1).unwrap(); Ok(()) @@ -99,21 +149,23 @@ impl AsyncIo for RawFileSync { } if let Some(user_data) = user_data { - self.completion_list.push_back((user_data, result)); + self.completion_list + .push_back(AsyncIoCompletion::new(user_data, result, None)); self.eventfd.write(1).unwrap(); } Ok(()) } - fn next_completed_request(&mut self) -> Option<(u64, i32)> { + fn next_completion(&mut self) -> Option { self.completion_list.pop_front() } fn punch_hole(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> { punch_hole(self.fd, self.is_block_device, offset, length) .map_err(AsyncIoError::PunchHole)?; - self.completion_list.push_back((user_data, 0)); + self.completion_list + .push_back(AsyncIoCompletion::new(user_data, 0, None)); self.eventfd.write(1).unwrap(); Ok(()) } @@ -121,7 +173,8 @@ impl AsyncIo for RawFileSync { fn write_zeroes(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> { write_zeroes(self.fd, self.is_block_device, offset, length) .map_err(AsyncIoError::WriteZeroes)?; - self.completion_list.push_back((user_data, 0)); + self.completion_list + .push_back(AsyncIoCompletion::new(user_data, 0, None)); self.eventfd.write(1).unwrap(); Ok(()) }