device_virtio_block/sys/
linux.rs1use std::cmp::max;
6use std::cmp::min;
7use std::os::fd::BorrowedFd;
8
9use anyhow::Context;
10use base::linux::preadv2;
11use base::linux::pwritev2;
12use base::unix::iov_max;
13use base::IoBufMut;
14use base::RawDescriptor;
15use cros_async::Executor;
16use disk::DiskFile;
17
18use crate::asynchronous::BlockAsync;
19use crate::DiskOption;
20
21pub fn get_seg_max(queue_size: u16) -> u32 {
22 let seg_max = min(max(iov_max(), 1), u32::MAX as usize) as u32;
23
24 min(seg_max, u32::from(queue_size) - 2)
28}
29
30pub fn check_dontcache_support(fd: RawDescriptor, write: bool) -> bool {
31 let mut buf = [0u8; 1];
32 let mut iovs = [IoBufMut::new(&mut buf)];
33 let borrowed_fd = unsafe { BorrowedFd::borrow_raw(fd) };
35 let res = if write {
36 if preadv2(borrowed_fd, &mut iovs, 0, 0) != 1 {
39 return false;
40 }
41 pwritev2(
42 borrowed_fd,
43 IoBufMut::as_iobufs(&iovs),
44 0,
45 libc::RWF_DONTCACHE,
46 )
47 } else {
48 preadv2(borrowed_fd, &mut iovs, 0, libc::RWF_DONTCACHE)
49 };
50 if res < 0 {
51 let err = base::Error::last();
52 match err.errno() {
53 libc::EOPNOTSUPP | libc::EINVAL | libc::ENOSYS => false,
54 _ => {
55 base::warn!("Unexpected error checking for DONTCACHE support: {err}");
56 false
57 }
58 }
59 } else {
60 true
61 }
62}
63
64impl DiskOption {
65 pub fn open(&self) -> anyhow::Result<Box<dyn DiskFile>> {
67 disk::open_disk_file(disk::DiskFileParams {
68 path: self.path.clone(),
69 is_read_only: self.read_only,
70 is_sparse_file: self.sparse,
71 is_direct: self.direct,
72 lock: self.lock,
73 ..Default::default()
74 })
75 .context("open_disk_file failed")
76 }
77}
78
79impl BlockAsync {
80 pub fn create_executor(&self) -> Executor {
81 Executor::with_executor_kind(self.executor_kind).expect("Failed to create an executor")
82 }
83}