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