block_util: Factorize common code for synchronous implementations

Since QCOW and RAW synchronous implementation are very close, it makes
sense to introduce some common functions that can be shared between
these two.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2021-01-22 15:19:26 +01:00
committed by Rob Bradford
parent f6c8e4b045
commit 060df69f07
3 changed files with 169 additions and 165 deletions

View File

@@ -2,12 +2,10 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileResult};
use crate::{disk_size, fsync_sync, read_vectored_sync, write_vectored_sync};
use qcow::RawFile;
use std::fs::File;
use std::io::{IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use std::sync::{Arc, Mutex};
use vmm_sys_util::eventfd::EventFd;
@@ -27,14 +25,7 @@ impl RawFileDiskSync {
impl DiskFile for RawFileDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
// Take the semaphore to ensure other threads are not interacting with
// the underlying file.
let _lock = self.semaphore.lock().unwrap();
Ok(self
.raw_file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)? as u64)
disk_size(&mut self.raw_file, &mut self.semaphore)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
@@ -74,32 +65,15 @@ impl AsyncIo for RawFileSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSliceMut
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSliceMut::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = self.semaphore.lock().unwrap();
// Move the cursor to the right offset
self.raw_file
.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?;
// Read vectored
self.raw_file
.read_vectored(slices.as_mut_slice())
.map_err(AsyncIoError::ReadVectored)?
};
self.completion_list.push((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
read_vectored_sync(
offset,
iovecs,
user_data,
&mut self.raw_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn write_vectored(
@@ -108,52 +82,25 @@ impl AsyncIo for RawFileSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSlice
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSlice::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = self.semaphore.lock().unwrap();
// Move the cursor to the right offset
self.raw_file
.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?;
// Write vectored
self.raw_file
.write_vectored(slices.as_slice())
.map_err(AsyncIoError::WriteVectored)?
};
self.completion_list.push((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
write_vectored_sync(
offset,
iovecs,
user_data,
&mut self.raw_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
let result: i32 = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = self.semaphore.lock().unwrap();
// Flush
self.raw_file.flush().map_err(AsyncIoError::Fsync)?;
0
};
if let Some(user_data) = user_data {
self.completion_list.push((user_data, result));
self.eventfd.write(1).unwrap();
}
Ok(())
fsync_sync(
user_data,
&mut self.raw_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn complete(&mut self) -> Vec<(u64, i32)> {