diff --git a/block/src/formats/raw/engine_aio.rs b/block/src/formats/raw/engine_aio.rs index 49a527769..d73ac4b24 100644 --- a/block/src/formats/raw/engine_aio.rs +++ b/block/src/formats/raw/engine_aio.rs @@ -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)); diff --git a/block/src/formats/raw/engine_uring.rs b/block/src/formats/raw/engine_uring.rs index 0ef2c21bd..7e1dc10df 100644 --- a/block/src/formats/raw/engine_uring.rs +++ b/block/src/formats/raw/engine_uring.rs @@ -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) -> 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)); } diff --git a/block/src/formats/raw/mod.rs b/block/src/formats/raw/mod.rs index f65573776..9aaacda23 100644 --- a/block/src/formats/raw/mod.rs +++ b/block/src/formats/raw/mod.rs @@ -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 { 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)]