devices/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::virtio::block::DiskOption;
19use crate::virtio::BlockAsync;
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 pwritev2(
37 borrowed_fd,
38 IoBufMut::as_iobufs(&iovs),
39 0,
40 libc::RWF_DONTCACHE,
41 )
42 } else {
43 preadv2(borrowed_fd, &mut iovs, 0, libc::RWF_DONTCACHE)
44 };
45 if res < 0 {
46 let err = base::Error::last();
47 match err.errno() {
48 libc::EOPNOTSUPP | libc::EINVAL | libc::ENOSYS => false,
49 _ => {
50 base::warn!("Unexpected error checking for DONTCACHE support: {err}");
51 false
52 }
53 }
54 } else {
55 true
56 }
57}
58
59impl DiskOption {
60 pub fn open(&self) -> anyhow::Result<Box<dyn DiskFile>> {
62 disk::open_disk_file(disk::DiskFileParams {
63 path: self.path.clone(),
64 is_read_only: self.read_only,
65 is_sparse_file: self.sparse,
66 is_direct: self.direct,
67 lock: self.lock,
68 ..Default::default()
69 })
70 .context("open_disk_file failed")
71 }
72}
73
74impl BlockAsync {
75 pub fn create_executor(&self) -> Executor {
76 Executor::with_executor_kind(self.executor_kind).expect("Failed to create an executor")
77 }
78}