mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: Add owned raw sync I/O path
Implement the owned AsyncIo path for RawFileSync while keeping the legacy borrowed iovec methods available until all callers can be converted. Signed-off-by: Dylan Reid <dgreid@fb.com>
This commit is contained in:
@@ -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<AsyncIoCompletion>,
|
||||
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<AsyncIoCompletion> {
|
||||
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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user