mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: raw: Route aio and uring bounce through the vectored API
Reimplement run_unaligned_operation over AlignedFile read_vectored_at and write_vectored_at instead of scattering and gathering through the per operation write_bytes_at and read_bytes_at closures. The aio and uring engines already reach this helper for the O_DIRECT misaligned case, so both now share the same vectored bounce path as the sync engine and the scatter gather logic lives only in AlignedFile. The operation iovecs point at the same memory that write_bytes_at and read_bytes_at reach, and the aligned fast path already hands those iovecs to the kernel, so the direct vectored call is equivalent. For guest memory read targets the destination pages are marked dirty by mark_read_dirty in execute_async before the operation is submitted, independent of how the bounce copies bytes, so the raw iovec path preserves dirty tracking. Drop the now unneeded mut bindings at the call sites. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
441eb0671a
commit
4f9fcfa22b
@@ -51,7 +51,7 @@ impl AsyncIo for RawAio {
|
||||
self.alignment
|
||||
}
|
||||
|
||||
fn submit_data_operation(&mut self, mut op: AsyncIoOperation) -> AsyncIoResult<()> {
|
||||
fn submit_data_operation(&mut self, op: AsyncIoOperation) -> AsyncIoResult<()> {
|
||||
let is_read = op.is_read();
|
||||
|
||||
if operation_is_aligned(&op, self.alignment) {
|
||||
@@ -65,7 +65,7 @@ impl AsyncIo for RawAio {
|
||||
});
|
||||
}
|
||||
|
||||
let result = run_unaligned_operation(&self.raw_file, &mut op)?;
|
||||
let result = run_unaligned_operation(&self.raw_file, &op)?;
|
||||
self.data_io
|
||||
.inject_completion(AsyncIoCompletion::from_operation(op, result));
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ impl AsyncIo for RawAsync {
|
||||
self.alignment
|
||||
}
|
||||
|
||||
fn submit_data_operation(&mut self, mut op: AsyncIoOperation) -> AsyncIoResult<()> {
|
||||
fn submit_data_operation(&mut self, op: AsyncIoOperation) -> AsyncIoResult<()> {
|
||||
let is_read = op.is_read();
|
||||
|
||||
if operation_is_aligned(&op, self.alignment) {
|
||||
@@ -62,7 +62,7 @@ impl AsyncIo for RawAsync {
|
||||
});
|
||||
}
|
||||
|
||||
let result = run_unaligned_operation(&self.raw_file, &mut op)?;
|
||||
let result = run_unaligned_operation(&self.raw_file, &op)?;
|
||||
self.data_io
|
||||
.inject_completion(AsyncIoCompletion::from_operation(op, result));
|
||||
|
||||
@@ -94,11 +94,11 @@ impl AsyncIo for RawAsync {
|
||||
fn submit_batch_requests(&mut self, batch_request: Vec<AsyncIoOperation>) -> AsyncIoResult<()> {
|
||||
if self.alignment != 0 {
|
||||
let mut aligned_batch = Vec::with_capacity(batch_request.len());
|
||||
for mut op in batch_request {
|
||||
for op in batch_request {
|
||||
if operation_is_aligned(&op, self.alignment) {
|
||||
aligned_batch.push(op);
|
||||
} else {
|
||||
let result = run_unaligned_operation(&self.raw_file, &mut op)?;
|
||||
let result = run_unaligned_operation(&self.raw_file, &op)?;
|
||||
self.data_io
|
||||
.inject_completion(AsyncIoCompletion::from_operation(op, result));
|
||||
}
|
||||
|
||||
@@ -181,22 +181,24 @@ fn operation_is_aligned(op: &AsyncIoOperation, alignment: u64) -> bool {
|
||||
/// Runs an unaligned O_DIRECT operation synchronously through `aligned_file`.
|
||||
fn run_unaligned_operation(
|
||||
aligned_file: &AlignedFile,
|
||||
op: &mut AsyncIoOperation,
|
||||
op: &AsyncIoOperation,
|
||||
) -> AsyncIoResult<i32> {
|
||||
let offset = op.offset() as u64;
|
||||
let total_len = op.total_len();
|
||||
let iovecs = op.iovecs();
|
||||
|
||||
if op.is_read() {
|
||||
let n = aligned_file
|
||||
.read_unaligned(offset, total_len, |data| op.write_bytes_at(0, data))
|
||||
.map_err(AsyncIoError::ReadVectored)?;
|
||||
Ok(n as i32)
|
||||
let n = if op.is_read() {
|
||||
// SAFETY: op.iovecs() describes valid memory for iov_len bytes by
|
||||
// construction of AsyncIoOperation.
|
||||
unsafe { aligned_file.read_vectored_at(iovecs, offset) }
|
||||
.map_err(AsyncIoError::ReadVectored)?
|
||||
} else {
|
||||
let n = aligned_file
|
||||
.write_unaligned(offset, total_len, |data| op.read_bytes_at(0, data))
|
||||
.map_err(AsyncIoError::WriteVectored)?;
|
||||
Ok(n as i32)
|
||||
}
|
||||
// SAFETY: op.iovecs() describes valid memory for iov_len bytes by
|
||||
// construction of AsyncIoOperation.
|
||||
unsafe { aligned_file.write_vectored_at(iovecs, offset) }
|
||||
.map_err(AsyncIoError::WriteVectored)?
|
||||
};
|
||||
|
||||
Ok(n as i32)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user