| 809 | } |
| 810 | |
| 811 | pub fn probe(f: &File) -> std::io::Result<Self> { |
| 812 | if !Self::is_block_device(f)? { |
| 813 | // For regular files opened with O_DIRECT, the logical block size |
| 814 | // must reflect the filesystem DIO alignment so the guest issues |
| 815 | // correctly sized I/O. |
| 816 | // SAFETY: fcntl(F_GETFL) is always safe on a valid fd. |
| 817 | let flags = unsafe { libc::fcntl(f.as_raw_fd(), libc::F_GETFL) }; |
| 818 | if flags >= 0 && (flags & libc::O_DIRECT) != 0 { |
| 819 | let alignment = Self::query_file_alignment(f); |
| 820 | return Ok(DiskTopology { |
| 821 | logical_block_size: alignment, |
| 822 | physical_block_size: alignment, |
| 823 | minimum_io_size: alignment, |
| 824 | optimal_io_size: 0, |
| 825 | }); |
| 826 | } |
| 827 | return Ok(DiskTopology::default()); |
| 828 | } |
| 829 | |
| 830 | Ok(DiskTopology { |
| 831 | logical_block_size: Self::query_block_size(f, BlockSize::LogicalBlock)?, |
| 832 | physical_block_size: Self::query_block_size(f, BlockSize::PhysicalBlock)?, |
| 833 | minimum_io_size: Self::query_block_size(f, BlockSize::MinimumIo)?, |
| 834 | optimal_io_size: Self::query_block_size(f, BlockSize::OptimalIo)?, |
| 835 | }) |
| 836 | } |
| 837 | } |
| 838 | |
| 839 | #[cfg(test)] |