1use crate::{to_io, BlckExt};
2use std::fs::File;
3use std::io::Result;
4use std::os::unix::fs::FileTypeExt;
5use std::os::unix::io::AsRawFd;
6
7impl BlckExt for File {
8 fn is_block_device(&self) -> bool {
9 match self.metadata() {
10 Err(_) => false,
11 Ok(meta) => meta.file_type().is_block_device(),
12 }
13 }
14
15 fn get_block_device_size(&self) -> Result<u64> {
16 let fd = self.as_raw_fd();
17 let mut blksize = 0;
18 unsafe {
19 ioctls::blkgetsize64(fd, &mut blksize).map_err(to_io)?;
20 Ok(blksize)
21 }
22 }
23
24 fn get_size_of_block(&self) -> Result<u64> {
25 let fd = self.as_raw_fd();
26 let mut blksize = 0;
27 unsafe {
28 ioctls::blksszget(fd, &mut blksize).map_err(to_io)?;
29 }
30 Ok(blksize as u64)
31 }
32
33 fn get_block_count(&self) -> Result<u64> {
34 Ok(self.get_block_device_size()? / self.get_size_of_block()?)
35 }
36
37 fn block_reread_paritions(&self) -> Result<()> {
38 let fd = self.as_raw_fd();
39 unsafe {
40 ioctls::blkrrpart(fd).map_err(to_io)?;
41 }
42 Ok(())
43 }
44
45 fn block_discard_zeros(&self) -> Result<bool> {
46 let fd = self.as_raw_fd();
47 let mut discard_zeros = 0;
48 unsafe {
49 ioctls::blkdiscardzeros(fd, &mut discard_zeros).map_err(to_io)?;
50 }
51 Ok(discard_zeros != 0)
52 }
53
54 fn block_discard(&self, offset: u64, len: u64) -> Result<()> {
55 let fd = self.as_raw_fd();
56 let range = [offset, len];
57 unsafe {
58 ioctls::blkdiscard(fd, &range).map_err(to_io)?;
59 }
60 Ok(())
61 }
62
63 fn block_zero_out(&mut self, offset: u64, len: u64) -> Result<()> {
64 let fd = self.as_raw_fd();
65 let range = [offset, len];
66 unsafe {
67 ioctls::blkzeroout(fd, &range).map_err(to_io)?;
68 }
69 Ok(())
70 }
71
72 fn sync_data(&self) -> Result<()> {
73 File::sync_data(self)
74 }
75}
76
77mod ioctls {
78 use nix::{
79 ioctl_none, ioctl_read_bad, ioctl_write_ptr_bad, request_code_none, request_code_read,
80 };
81
82 ioctl_none!(blkrrpart, 0x12, 95);
83 ioctl_read_bad!(
84 blkgetsize64,
85 request_code_read!(0x12, 114, ::std::mem::size_of::<usize>()),
86 u64
87 );
88 ioctl_read_bad!(
89 blkdiscardzeros,
90 request_code_none!(0x12, 124),
91 ::std::os::raw::c_uint
92 );
93 ioctl_write_ptr_bad!(blkdiscard, request_code_none!(0x12, 119), [u64; 2]);
94 ioctl_write_ptr_bad!(blkzeroout, request_code_none!(0x12, 127), [u64; 2]);
95 ioctl_read_bad!(
96 blksszget,
97 request_code_none!(0x12, 104),
98 ::std::os::raw::c_int
99 );
100}