xref: /cloud-hypervisor/block/src/fixed_vhd_sync.rs (revision 3ce0fef7fd546467398c914dbc74d8542e45cf6f)
1 // Copyright © 2021 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 
5 use crate::async_io::{
6     AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
7 };
8 use crate::fixed_vhd::FixedVhd;
9 use crate::raw_sync::RawFileSync;
10 use crate::BlockBackend;
11 use std::fs::File;
12 use std::os::unix::io::{AsRawFd, RawFd};
13 use vmm_sys_util::eventfd::EventFd;
14 
15 pub struct FixedVhdDiskSync(FixedVhd);
16 
17 impl FixedVhdDiskSync {
18     pub fn new(file: File) -> std::io::Result<Self> {
19         Ok(Self(FixedVhd::new(file)?))
20     }
21 }
22 
23 impl DiskFile for FixedVhdDiskSync {
24     fn size(&mut self) -> DiskFileResult<u64> {
25         Ok(self.0.size().unwrap())
26     }
27 
28     fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
29         Ok(Box::new(
30             FixedVhdSync::new(self.0.as_raw_fd(), self.0.size().unwrap())
31                 .map_err(DiskFileError::NewAsyncIo)?,
32         ) as Box<dyn AsyncIo>)
33     }
34 }
35 
36 pub struct FixedVhdSync {
37     raw_file_sync: RawFileSync,
38     size: u64,
39 }
40 
41 impl FixedVhdSync {
42     pub fn new(fd: RawFd, size: u64) -> std::io::Result<Self> {
43         Ok(FixedVhdSync {
44             raw_file_sync: RawFileSync::new(fd),
45             size,
46         })
47     }
48 }
49 
50 impl AsyncIo for FixedVhdSync {
51     fn notifier(&self) -> &EventFd {
52         self.raw_file_sync.notifier()
53     }
54 
55     fn read_vectored(
56         &mut self,
57         offset: libc::off_t,
58         iovecs: &[libc::iovec],
59         user_data: u64,
60     ) -> AsyncIoResult<()> {
61         if offset as u64 >= self.size {
62             return Err(AsyncIoError::ReadVectored(std::io::Error::new(
63                 std::io::ErrorKind::InvalidData,
64                 format!(
65                     "Invalid offset {}, can't be larger than file size {}",
66                     offset, self.size
67                 ),
68             )));
69         }
70 
71         self.raw_file_sync.read_vectored(offset, iovecs, user_data)
72     }
73 
74     fn write_vectored(
75         &mut self,
76         offset: libc::off_t,
77         iovecs: &[libc::iovec],
78         user_data: u64,
79     ) -> AsyncIoResult<()> {
80         if offset as u64 >= self.size {
81             return Err(AsyncIoError::WriteVectored(std::io::Error::new(
82                 std::io::ErrorKind::InvalidData,
83                 format!(
84                     "Invalid offset {}, can't be larger than file size {}",
85                     offset, self.size
86                 ),
87             )));
88         }
89 
90         self.raw_file_sync.write_vectored(offset, iovecs, user_data)
91     }
92 
93     fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
94         self.raw_file_sync.fsync(user_data)
95     }
96 
97     fn next_completed_request(&mut self) -> Option<(u64, i32)> {
98         self.raw_file_sync.next_completed_request()
99     }
100 }
101