Skip to main content

dio_align/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, allow(unused_attributes))]
4#![deny(missing_docs)]
5
6// Linux kernel version less than 6.1
7#[path = "linux/mod.rs"]
8#[cfg(target_os = "linux")]
9mod os;
10
11#[path = "apple.rs"]
12#[cfg(any(
13  target_os = "macos",
14  target_os = "ios",
15  target_os = "tvos",
16  target_os = "watchos",
17  target_os = "visionos",
18))]
19mod os;
20
21#[path = "windows.rs"]
22#[cfg(windows)]
23mod os;
24
25#[cfg(any(
26  target_os = "linux",
27  target_os = "macos",
28  target_os = "ios",
29  target_os = "tvos",
30  target_os = "watchos",
31  target_os = "visionos",
32  windows,
33))]
34pub use os::*;
35
36/// Direct I/O alignment information for a filesystem path.
37#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
38pub struct DirectInfo {
39  #[cfg(linux_kernel_6_1)]
40  mem_align: u32,
41  logical: u32,
42  physical: u32,
43}
44
45impl DirectInfo {
46  #[inline]
47  const fn new(#[cfg(linux_kernel_6_1)] mem_align: u32, logical: u32, physical: u32) -> Self {
48    Self {
49      #[cfg(linux_kernel_6_1)]
50      mem_align,
51      logical,
52      physical,
53    }
54  }
55
56  /// Returns the required memory alignment in bytes, if available.
57  ///
58  /// On Linux this uses `statx(DIOALIGN)` for kernels `>= 6.1`.
59  #[cfg_attr(not(tarpaulin), inline(always))]
60  #[cfg(linux_kernel_6_1)]
61  #[cfg_attr(docsrs, doc(cfg(linux_kernel_6_1)))]
62  pub const fn mem_align(&self) -> u32 {
63    self.mem_align
64  }
65
66  /// Returns the logical block size in bytes.
67  #[cfg_attr(not(tarpaulin), inline(always))]
68  pub const fn logical_block_size(&self) -> u32 {
69    self.logical
70  }
71
72  /// Returns the physical block size in bytes.
73  #[cfg_attr(not(tarpaulin), inline(always))]
74  pub const fn physical_block_size(&self) -> u32 {
75    self.physical
76  }
77}
78
79#[test]
80fn test_direct_info() {
81  use tempfile::NamedTempFile;
82
83  let file = NamedTempFile::new().unwrap();
84  let info = fetch(file.path()).unwrap();
85  println!(
86    "logical: {}, physical: {}",
87    info.logical_block_size(),
88    info.physical_block_size()
89  );
90  assert!(info.logical_block_size().is_power_of_two());
91
92  #[cfg(not(apple))]
93  assert!(info.physical_block_size().is_power_of_two());
94
95  assert!(info.physical_block_size() % 2 == 0);
96
97  #[cfg(linux_kernel_6_1)]
98  assert!(info.mem_align().is_power_of_two());
99}