/rust/registry/src/index.crates.io-6f17d22bba15001f/nix-0.26.2/src/sys/statfs.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Get filesystem statistics, non-portably |
2 | | //! |
3 | | //! See [`statvfs`](crate::sys::statvfs) for a portable alternative. |
4 | | #[cfg(not(any(target_os = "linux", target_os = "android")))] |
5 | | use std::ffi::CStr; |
6 | | use std::fmt::{self, Debug}; |
7 | | use std::mem; |
8 | | use std::os::unix::io::AsRawFd; |
9 | | |
10 | | use cfg_if::cfg_if; |
11 | | |
12 | | #[cfg(all( |
13 | | feature = "mount", |
14 | | any( |
15 | | target_os = "dragonfly", |
16 | | target_os = "freebsd", |
17 | | target_os = "macos", |
18 | | target_os = "netbsd", |
19 | | target_os = "openbsd" |
20 | | ) |
21 | | ))] |
22 | | use crate::mount::MntFlags; |
23 | | #[cfg(target_os = "linux")] |
24 | | use crate::sys::statvfs::FsFlags; |
25 | | use crate::{errno::Errno, NixPath, Result}; |
26 | | |
27 | | /// Identifies a mounted file system |
28 | | #[cfg(target_os = "android")] |
29 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
30 | | pub type fsid_t = libc::__fsid_t; |
31 | | /// Identifies a mounted file system |
32 | | #[cfg(not(target_os = "android"))] |
33 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
34 | | pub type fsid_t = libc::fsid_t; |
35 | | |
36 | | cfg_if! { |
37 | | if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] { |
38 | | type type_of_statfs = libc::statfs64; |
39 | | const LIBC_FSTATFS: unsafe extern fn |
40 | | (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int |
41 | | = libc::fstatfs64; |
42 | | const LIBC_STATFS: unsafe extern fn |
43 | | (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int |
44 | | = libc::statfs64; |
45 | | } else { |
46 | | type type_of_statfs = libc::statfs; |
47 | | const LIBC_FSTATFS: unsafe extern fn |
48 | | (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int |
49 | | = libc::fstatfs; |
50 | | const LIBC_STATFS: unsafe extern fn |
51 | | (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int |
52 | | = libc::statfs; |
53 | | } |
54 | | } |
55 | | |
56 | | /// Describes a mounted file system |
57 | 0 | #[derive(Clone, Copy)] |
58 | | #[repr(transparent)] |
59 | | pub struct Statfs(type_of_statfs); |
60 | | |
61 | | #[cfg(target_os = "freebsd")] |
62 | | type fs_type_t = u32; |
63 | | #[cfg(target_os = "android")] |
64 | | type fs_type_t = libc::c_ulong; |
65 | | #[cfg(all(target_os = "linux", target_arch = "s390x"))] |
66 | | type fs_type_t = libc::c_uint; |
67 | | #[cfg(all(target_os = "linux", target_env = "musl"))] |
68 | | type fs_type_t = libc::c_ulong; |
69 | | #[cfg(all(target_os = "linux", target_env = "uclibc"))] |
70 | | type fs_type_t = libc::c_int; |
71 | | #[cfg(all( |
72 | | target_os = "linux", |
73 | | not(any( |
74 | | target_arch = "s390x", |
75 | | target_env = "musl", |
76 | | target_env = "uclibc" |
77 | | )) |
78 | | ))] |
79 | | type fs_type_t = libc::__fsword_t; |
80 | | |
81 | | /// Describes the file system type as known by the operating system. |
82 | | #[cfg(any( |
83 | | target_os = "freebsd", |
84 | | target_os = "android", |
85 | | all(target_os = "linux", target_arch = "s390x"), |
86 | | all(target_os = "linux", target_env = "musl"), |
87 | | all( |
88 | | target_os = "linux", |
89 | | not(any(target_arch = "s390x", target_env = "musl")) |
90 | | ), |
91 | | ))] |
92 | 0 | #[derive(Eq, Copy, Clone, PartialEq, Debug)] |
93 | | pub struct FsType(pub fs_type_t); |
94 | | |
95 | | // These constants are defined without documentation in the Linux headers, so we |
96 | | // can't very well document them here. |
97 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
98 | | #[allow(missing_docs)] |
99 | | pub const ADFS_SUPER_MAGIC: FsType = |
100 | | FsType(libc::ADFS_SUPER_MAGIC as fs_type_t); |
101 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
102 | | #[allow(missing_docs)] |
103 | | pub const AFFS_SUPER_MAGIC: FsType = |
104 | | FsType(libc::AFFS_SUPER_MAGIC as fs_type_t); |
105 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
106 | | #[allow(missing_docs)] |
107 | | pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t); |
108 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
109 | | #[allow(missing_docs)] |
110 | | pub const AUTOFS_SUPER_MAGIC: FsType = |
111 | | FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t); |
112 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
113 | | #[allow(missing_docs)] |
114 | | pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t); |
115 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
116 | | #[allow(missing_docs)] |
117 | | pub const BTRFS_SUPER_MAGIC: FsType = |
118 | | FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t); |
119 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
120 | | #[allow(missing_docs)] |
121 | | pub const CGROUP2_SUPER_MAGIC: FsType = |
122 | | FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t); |
123 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
124 | | #[allow(missing_docs)] |
125 | | pub const CGROUP_SUPER_MAGIC: FsType = |
126 | | FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t); |
127 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
128 | | #[allow(missing_docs)] |
129 | | pub const CODA_SUPER_MAGIC: FsType = |
130 | | FsType(libc::CODA_SUPER_MAGIC as fs_type_t); |
131 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
132 | | #[allow(missing_docs)] |
133 | | pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t); |
134 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
135 | | #[allow(missing_docs)] |
136 | | pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t); |
137 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
138 | | #[allow(missing_docs)] |
139 | | pub const DEVPTS_SUPER_MAGIC: FsType = |
140 | | FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t); |
141 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
142 | | #[allow(missing_docs)] |
143 | | pub const ECRYPTFS_SUPER_MAGIC: FsType = |
144 | | FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t); |
145 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
146 | | #[allow(missing_docs)] |
147 | | pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t); |
148 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
149 | | #[allow(missing_docs)] |
150 | | pub const EXT2_SUPER_MAGIC: FsType = |
151 | | FsType(libc::EXT2_SUPER_MAGIC as fs_type_t); |
152 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
153 | | #[allow(missing_docs)] |
154 | | pub const EXT3_SUPER_MAGIC: FsType = |
155 | | FsType(libc::EXT3_SUPER_MAGIC as fs_type_t); |
156 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
157 | | #[allow(missing_docs)] |
158 | | pub const EXT4_SUPER_MAGIC: FsType = |
159 | | FsType(libc::EXT4_SUPER_MAGIC as fs_type_t); |
160 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
161 | | #[allow(missing_docs)] |
162 | | pub const F2FS_SUPER_MAGIC: FsType = |
163 | | FsType(libc::F2FS_SUPER_MAGIC as fs_type_t); |
164 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
165 | | #[allow(missing_docs)] |
166 | | pub const FUSE_SUPER_MAGIC: FsType = |
167 | | FsType(libc::FUSE_SUPER_MAGIC as fs_type_t); |
168 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
169 | | #[allow(missing_docs)] |
170 | | pub const FUTEXFS_SUPER_MAGIC: FsType = |
171 | | FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t); |
172 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
173 | | #[allow(missing_docs)] |
174 | | pub const HOSTFS_SUPER_MAGIC: FsType = |
175 | | FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t); |
176 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
177 | | #[allow(missing_docs)] |
178 | | pub const HPFS_SUPER_MAGIC: FsType = |
179 | | FsType(libc::HPFS_SUPER_MAGIC as fs_type_t); |
180 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
181 | | #[allow(missing_docs)] |
182 | | pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t); |
183 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
184 | | #[allow(missing_docs)] |
185 | | pub const ISOFS_SUPER_MAGIC: FsType = |
186 | | FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t); |
187 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
188 | | #[allow(missing_docs)] |
189 | | pub const JFFS2_SUPER_MAGIC: FsType = |
190 | | FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t); |
191 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
192 | | #[allow(missing_docs)] |
193 | | pub const MINIX2_SUPER_MAGIC2: FsType = |
194 | | FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t); |
195 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
196 | | #[allow(missing_docs)] |
197 | | pub const MINIX2_SUPER_MAGIC: FsType = |
198 | | FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t); |
199 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
200 | | #[allow(missing_docs)] |
201 | | pub const MINIX3_SUPER_MAGIC: FsType = |
202 | | FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t); |
203 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
204 | | #[allow(missing_docs)] |
205 | | pub const MINIX_SUPER_MAGIC2: FsType = |
206 | | FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t); |
207 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
208 | | #[allow(missing_docs)] |
209 | | pub const MINIX_SUPER_MAGIC: FsType = |
210 | | FsType(libc::MINIX_SUPER_MAGIC as fs_type_t); |
211 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
212 | | #[allow(missing_docs)] |
213 | | pub const MSDOS_SUPER_MAGIC: FsType = |
214 | | FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t); |
215 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
216 | | #[allow(missing_docs)] |
217 | | pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t); |
218 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
219 | | #[allow(missing_docs)] |
220 | | pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t); |
221 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
222 | | #[allow(missing_docs)] |
223 | | pub const NILFS_SUPER_MAGIC: FsType = |
224 | | FsType(libc::NILFS_SUPER_MAGIC as fs_type_t); |
225 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
226 | | #[allow(missing_docs)] |
227 | | pub const OCFS2_SUPER_MAGIC: FsType = |
228 | | FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t); |
229 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
230 | | #[allow(missing_docs)] |
231 | | pub const OPENPROM_SUPER_MAGIC: FsType = |
232 | | FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t); |
233 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
234 | | #[allow(missing_docs)] |
235 | | pub const OVERLAYFS_SUPER_MAGIC: FsType = |
236 | | FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t); |
237 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
238 | | #[allow(missing_docs)] |
239 | | pub const PROC_SUPER_MAGIC: FsType = |
240 | | FsType(libc::PROC_SUPER_MAGIC as fs_type_t); |
241 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
242 | | #[allow(missing_docs)] |
243 | | pub const QNX4_SUPER_MAGIC: FsType = |
244 | | FsType(libc::QNX4_SUPER_MAGIC as fs_type_t); |
245 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
246 | | #[allow(missing_docs)] |
247 | | pub const QNX6_SUPER_MAGIC: FsType = |
248 | | FsType(libc::QNX6_SUPER_MAGIC as fs_type_t); |
249 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
250 | | #[allow(missing_docs)] |
251 | | pub const RDTGROUP_SUPER_MAGIC: FsType = |
252 | | FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t); |
253 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
254 | | #[allow(missing_docs)] |
255 | | pub const REISERFS_SUPER_MAGIC: FsType = |
256 | | FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t); |
257 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
258 | | #[allow(missing_docs)] |
259 | | pub const SECURITYFS_MAGIC: FsType = |
260 | | FsType(libc::SECURITYFS_MAGIC as fs_type_t); |
261 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
262 | | #[allow(missing_docs)] |
263 | | pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t); |
264 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
265 | | #[allow(missing_docs)] |
266 | | pub const SMACK_MAGIC: FsType = FsType(libc::SMACK_MAGIC as fs_type_t); |
267 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
268 | | #[allow(missing_docs)] |
269 | | pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t); |
270 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
271 | | #[allow(missing_docs)] |
272 | | pub const SYSFS_MAGIC: FsType = FsType(libc::SYSFS_MAGIC as fs_type_t); |
273 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
274 | | #[allow(missing_docs)] |
275 | | pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t); |
276 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
277 | | #[allow(missing_docs)] |
278 | | pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t); |
279 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
280 | | #[allow(missing_docs)] |
281 | | pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t); |
282 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
283 | | #[allow(missing_docs)] |
284 | | pub const USBDEVICE_SUPER_MAGIC: FsType = |
285 | | FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t); |
286 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
287 | | #[allow(missing_docs)] |
288 | | pub const XENFS_SUPER_MAGIC: FsType = |
289 | | FsType(libc::XENFS_SUPER_MAGIC as fs_type_t); |
290 | | #[cfg(any(target_os = "linux", target_os = "android"))] |
291 | | #[allow(missing_docs)] |
292 | | pub const NSFS_MAGIC: FsType = FsType(libc::NSFS_MAGIC as fs_type_t); |
293 | | #[cfg(all( |
294 | | any(target_os = "linux", target_os = "android"), |
295 | | not(target_env = "musl") |
296 | | ))] |
297 | | #[allow(missing_docs)] |
298 | | pub const XFS_SUPER_MAGIC: FsType = FsType(libc::XFS_SUPER_MAGIC as fs_type_t); |
299 | | |
300 | | impl Statfs { |
301 | | /// Magic code defining system type |
302 | | #[cfg(not(any( |
303 | | target_os = "openbsd", |
304 | | target_os = "dragonfly", |
305 | | target_os = "ios", |
306 | | target_os = "macos" |
307 | | )))] |
308 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
309 | 0 | pub fn filesystem_type(&self) -> FsType { |
310 | 0 | FsType(self.0.f_type) |
311 | 0 | } |
312 | | |
313 | | /// Magic code defining system type |
314 | | #[cfg(not(any(target_os = "linux", target_os = "android")))] |
315 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
316 | | pub fn filesystem_type_name(&self) -> &str { |
317 | | let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) }; |
318 | | c_str.to_str().unwrap() |
319 | | } |
320 | | |
321 | | /// Optimal transfer block size |
322 | | #[cfg(any(target_os = "ios", target_os = "macos"))] |
323 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
324 | | pub fn optimal_transfer_size(&self) -> i32 { |
325 | | self.0.f_iosize |
326 | | } |
327 | | |
328 | | /// Optimal transfer block size |
329 | | #[cfg(target_os = "openbsd")] |
330 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
331 | | pub fn optimal_transfer_size(&self) -> u32 { |
332 | | self.0.f_iosize |
333 | | } |
334 | | |
335 | | /// Optimal transfer block size |
336 | | #[cfg(all(target_os = "linux", target_arch = "s390x"))] |
337 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
338 | | pub fn optimal_transfer_size(&self) -> u32 { |
339 | | self.0.f_bsize |
340 | | } |
341 | | |
342 | | /// Optimal transfer block size |
343 | | #[cfg(any( |
344 | | target_os = "android", |
345 | | all(target_os = "linux", target_env = "musl") |
346 | | ))] |
347 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
348 | | pub fn optimal_transfer_size(&self) -> libc::c_ulong { |
349 | | self.0.f_bsize |
350 | | } |
351 | | |
352 | | /// Optimal transfer block size |
353 | | #[cfg(all( |
354 | | target_os = "linux", |
355 | | not(any( |
356 | | target_arch = "s390x", |
357 | | target_env = "musl", |
358 | | target_env = "uclibc" |
359 | | )) |
360 | | ))] |
361 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
362 | 0 | pub fn optimal_transfer_size(&self) -> libc::__fsword_t { |
363 | 0 | self.0.f_bsize |
364 | 0 | } |
365 | | |
366 | | /// Optimal transfer block size |
367 | | #[cfg(all(target_os = "linux", target_env = "uclibc"))] |
368 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
369 | | pub fn optimal_transfer_size(&self) -> libc::c_int { |
370 | | self.0.f_bsize |
371 | | } |
372 | | |
373 | | /// Optimal transfer block size |
374 | | #[cfg(target_os = "dragonfly")] |
375 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
376 | | pub fn optimal_transfer_size(&self) -> libc::c_long { |
377 | | self.0.f_iosize |
378 | | } |
379 | | |
380 | | /// Optimal transfer block size |
381 | | #[cfg(target_os = "freebsd")] |
382 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
383 | | pub fn optimal_transfer_size(&self) -> u64 { |
384 | | self.0.f_iosize |
385 | | } |
386 | | |
387 | | /// Size of a block |
388 | | #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))] |
389 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
390 | | pub fn block_size(&self) -> u32 { |
391 | | self.0.f_bsize |
392 | | } |
393 | | |
394 | | /// Size of a block |
395 | | // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 |
396 | | #[cfg(all(target_os = "linux", target_arch = "s390x"))] |
397 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
398 | | pub fn block_size(&self) -> u32 { |
399 | | self.0.f_bsize |
400 | | } |
401 | | |
402 | | /// Size of a block |
403 | | // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 |
404 | | #[cfg(all(target_os = "linux", target_env = "musl"))] |
405 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
406 | | pub fn block_size(&self) -> libc::c_ulong { |
407 | | self.0.f_bsize |
408 | | } |
409 | | |
410 | | /// Size of a block |
411 | | // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 |
412 | | #[cfg(all(target_os = "linux", target_env = "uclibc"))] |
413 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
414 | | pub fn block_size(&self) -> libc::c_int { |
415 | | self.0.f_bsize |
416 | | } |
417 | | |
418 | | /// Size of a block |
419 | | // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 |
420 | | #[cfg(all( |
421 | | target_os = "linux", |
422 | | not(any( |
423 | | target_arch = "s390x", |
424 | | target_env = "musl", |
425 | | target_env = "uclibc" |
426 | | )) |
427 | | ))] |
428 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
429 | 0 | pub fn block_size(&self) -> libc::__fsword_t { |
430 | 0 | self.0.f_bsize |
431 | 0 | } |
432 | | |
433 | | /// Size of a block |
434 | | #[cfg(target_os = "freebsd")] |
435 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
436 | | pub fn block_size(&self) -> u64 { |
437 | | self.0.f_bsize |
438 | | } |
439 | | |
440 | | /// Size of a block |
441 | | #[cfg(target_os = "android")] |
442 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
443 | | pub fn block_size(&self) -> libc::c_ulong { |
444 | | self.0.f_bsize |
445 | | } |
446 | | |
447 | | /// Size of a block |
448 | | #[cfg(target_os = "dragonfly")] |
449 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
450 | | pub fn block_size(&self) -> libc::c_long { |
451 | | self.0.f_bsize |
452 | | } |
453 | | |
454 | | /// Get the mount flags |
455 | | #[cfg(all( |
456 | | feature = "mount", |
457 | | any( |
458 | | target_os = "dragonfly", |
459 | | target_os = "freebsd", |
460 | | target_os = "macos", |
461 | | target_os = "netbsd", |
462 | | target_os = "openbsd" |
463 | | ) |
464 | | ))] |
465 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
466 | | #[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches |
467 | | pub fn flags(&self) -> MntFlags { |
468 | | MntFlags::from_bits_truncate(self.0.f_flags as i32) |
469 | | } |
470 | | |
471 | | /// Get the mount flags |
472 | | // The f_flags field exists on Android and Fuchsia too, but without man |
473 | | // pages I can't tell if it can be cast to FsFlags. |
474 | | #[cfg(target_os = "linux")] |
475 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
476 | 0 | pub fn flags(&self) -> FsFlags { |
477 | 0 | FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong) |
478 | 0 | } |
479 | | |
480 | | /// Maximum length of filenames |
481 | | #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] |
482 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
483 | | pub fn maximum_name_length(&self) -> u32 { |
484 | | self.0.f_namemax |
485 | | } |
486 | | |
487 | | /// Maximum length of filenames |
488 | | #[cfg(all(target_os = "linux", target_arch = "s390x"))] |
489 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
490 | | pub fn maximum_name_length(&self) -> u32 { |
491 | | self.0.f_namelen |
492 | | } |
493 | | |
494 | | /// Maximum length of filenames |
495 | | #[cfg(all(target_os = "linux", target_env = "musl"))] |
496 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
497 | | pub fn maximum_name_length(&self) -> libc::c_ulong { |
498 | | self.0.f_namelen |
499 | | } |
500 | | |
501 | | /// Maximum length of filenames |
502 | | #[cfg(all(target_os = "linux", target_env = "uclibc"))] |
503 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
504 | | pub fn maximum_name_length(&self) -> libc::c_int { |
505 | | self.0.f_namelen |
506 | | } |
507 | | |
508 | | /// Maximum length of filenames |
509 | | #[cfg(all( |
510 | | target_os = "linux", |
511 | | not(any( |
512 | | target_arch = "s390x", |
513 | | target_env = "musl", |
514 | | target_env = "uclibc" |
515 | | )) |
516 | | ))] |
517 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
518 | 0 | pub fn maximum_name_length(&self) -> libc::__fsword_t { |
519 | 0 | self.0.f_namelen |
520 | 0 | } |
521 | | |
522 | | /// Maximum length of filenames |
523 | | #[cfg(target_os = "android")] |
524 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
525 | | pub fn maximum_name_length(&self) -> libc::c_ulong { |
526 | | self.0.f_namelen |
527 | | } |
528 | | |
529 | | /// Total data blocks in filesystem |
530 | | #[cfg(any( |
531 | | target_os = "ios", |
532 | | target_os = "macos", |
533 | | target_os = "android", |
534 | | target_os = "freebsd", |
535 | | target_os = "fuchsia", |
536 | | target_os = "openbsd", |
537 | | target_os = "linux", |
538 | | ))] |
539 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
540 | 0 | pub fn blocks(&self) -> u64 { |
541 | 0 | self.0.f_blocks |
542 | 0 | } |
543 | | |
544 | | /// Total data blocks in filesystem |
545 | | #[cfg(target_os = "dragonfly")] |
546 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
547 | | pub fn blocks(&self) -> libc::c_long { |
548 | | self.0.f_blocks |
549 | | } |
550 | | |
551 | | /// Total data blocks in filesystem |
552 | | #[cfg(target_os = "emscripten")] |
553 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
554 | | pub fn blocks(&self) -> u32 { |
555 | | self.0.f_blocks |
556 | | } |
557 | | |
558 | | /// Free blocks in filesystem |
559 | | #[cfg(any( |
560 | | target_os = "ios", |
561 | | target_os = "macos", |
562 | | target_os = "android", |
563 | | target_os = "freebsd", |
564 | | target_os = "fuchsia", |
565 | | target_os = "openbsd", |
566 | | target_os = "linux", |
567 | | ))] |
568 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
569 | 0 | pub fn blocks_free(&self) -> u64 { |
570 | 0 | self.0.f_bfree |
571 | 0 | } |
572 | | |
573 | | /// Free blocks in filesystem |
574 | | #[cfg(target_os = "dragonfly")] |
575 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
576 | | pub fn blocks_free(&self) -> libc::c_long { |
577 | | self.0.f_bfree |
578 | | } |
579 | | |
580 | | /// Free blocks in filesystem |
581 | | #[cfg(target_os = "emscripten")] |
582 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
583 | | pub fn blocks_free(&self) -> u32 { |
584 | | self.0.f_bfree |
585 | | } |
586 | | |
587 | | /// Free blocks available to unprivileged user |
588 | | #[cfg(any( |
589 | | target_os = "ios", |
590 | | target_os = "macos", |
591 | | target_os = "android", |
592 | | target_os = "fuchsia", |
593 | | target_os = "linux", |
594 | | ))] |
595 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
596 | 0 | pub fn blocks_available(&self) -> u64 { |
597 | 0 | self.0.f_bavail |
598 | 0 | } |
599 | | |
600 | | /// Free blocks available to unprivileged user |
601 | | #[cfg(target_os = "dragonfly")] |
602 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
603 | | pub fn blocks_available(&self) -> libc::c_long { |
604 | | self.0.f_bavail |
605 | | } |
606 | | |
607 | | /// Free blocks available to unprivileged user |
608 | | #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] |
609 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
610 | | pub fn blocks_available(&self) -> i64 { |
611 | | self.0.f_bavail |
612 | | } |
613 | | |
614 | | /// Free blocks available to unprivileged user |
615 | | #[cfg(target_os = "emscripten")] |
616 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
617 | | pub fn blocks_available(&self) -> u32 { |
618 | | self.0.f_bavail |
619 | | } |
620 | | |
621 | | /// Total file nodes in filesystem |
622 | | #[cfg(any( |
623 | | target_os = "ios", |
624 | | target_os = "macos", |
625 | | target_os = "android", |
626 | | target_os = "freebsd", |
627 | | target_os = "fuchsia", |
628 | | target_os = "openbsd", |
629 | | target_os = "linux", |
630 | | ))] |
631 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
632 | 0 | pub fn files(&self) -> u64 { |
633 | 0 | self.0.f_files |
634 | 0 | } |
635 | | |
636 | | /// Total file nodes in filesystem |
637 | | #[cfg(target_os = "dragonfly")] |
638 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
639 | | pub fn files(&self) -> libc::c_long { |
640 | | self.0.f_files |
641 | | } |
642 | | |
643 | | /// Total file nodes in filesystem |
644 | | #[cfg(target_os = "emscripten")] |
645 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
646 | | pub fn files(&self) -> u32 { |
647 | | self.0.f_files |
648 | | } |
649 | | |
650 | | /// Free file nodes in filesystem |
651 | | #[cfg(any( |
652 | | target_os = "ios", |
653 | | target_os = "macos", |
654 | | target_os = "android", |
655 | | target_os = "fuchsia", |
656 | | target_os = "openbsd", |
657 | | target_os = "linux", |
658 | | ))] |
659 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
660 | 0 | pub fn files_free(&self) -> u64 { |
661 | 0 | self.0.f_ffree |
662 | 0 | } |
663 | | |
664 | | /// Free file nodes in filesystem |
665 | | #[cfg(target_os = "dragonfly")] |
666 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
667 | | pub fn files_free(&self) -> libc::c_long { |
668 | | self.0.f_ffree |
669 | | } |
670 | | |
671 | | /// Free file nodes in filesystem |
672 | | #[cfg(target_os = "freebsd")] |
673 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
674 | | pub fn files_free(&self) -> i64 { |
675 | | self.0.f_ffree |
676 | | } |
677 | | |
678 | | /// Free file nodes in filesystem |
679 | | #[cfg(target_os = "emscripten")] |
680 | | #[cfg_attr(docsrs, doc(cfg(all())))] |
681 | | pub fn files_free(&self) -> u32 { |
682 | | self.0.f_ffree |
683 | | } |
684 | | |
685 | | /// Filesystem ID |
686 | 0 | pub fn filesystem_id(&self) -> fsid_t { |
687 | 0 | self.0.f_fsid |
688 | 0 | } |
689 | | } |
690 | | |
691 | | impl Debug for Statfs { |
692 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
693 | 0 | let mut ds = f.debug_struct("Statfs"); |
694 | 0 | ds.field("optimal_transfer_size", &self.optimal_transfer_size()); |
695 | 0 | ds.field("block_size", &self.block_size()); |
696 | 0 | ds.field("blocks", &self.blocks()); |
697 | 0 | ds.field("blocks_free", &self.blocks_free()); |
698 | 0 | ds.field("blocks_available", &self.blocks_available()); |
699 | 0 | ds.field("files", &self.files()); |
700 | 0 | ds.field("files_free", &self.files_free()); |
701 | 0 | ds.field("filesystem_id", &self.filesystem_id()); |
702 | 0 | #[cfg(all( |
703 | 0 | feature = "mount", |
704 | 0 | any( |
705 | 0 | target_os = "dragonfly", |
706 | 0 | target_os = "freebsd", |
707 | 0 | target_os = "macos", |
708 | 0 | target_os = "netbsd", |
709 | 0 | target_os = "openbsd" |
710 | 0 | ) |
711 | 0 | ))] |
712 | 0 | ds.field("flags", &self.flags()); |
713 | 0 | ds.finish() |
714 | 0 | } |
715 | | } |
716 | | |
717 | | /// Describes a mounted file system. |
718 | | /// |
719 | | /// The result is OS-dependent. For a portable alternative, see |
720 | | /// [`statvfs`](crate::sys::statvfs::statvfs). |
721 | | /// |
722 | | /// # Arguments |
723 | | /// |
724 | | /// `path` - Path to any file within the file system to describe |
725 | 0 | pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> { |
726 | 0 | unsafe { |
727 | 0 | let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit(); |
728 | 0 | let res = path.with_nix_path(|path| { |
729 | 0 | LIBC_STATFS(path.as_ptr(), stat.as_mut_ptr()) |
730 | 0 | })?; |
731 | 0 | Errno::result(res).map(|_| Statfs(stat.assume_init())) |
732 | | } |
733 | 0 | } |
734 | | |
735 | | /// Describes a mounted file system. |
736 | | /// |
737 | | /// The result is OS-dependent. For a portable alternative, see |
738 | | /// [`fstatvfs`](crate::sys::statvfs::fstatvfs). |
739 | | /// |
740 | | /// # Arguments |
741 | | /// |
742 | | /// `fd` - File descriptor of any open file within the file system to describe |
743 | 0 | pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> { |
744 | 0 | unsafe { |
745 | 0 | let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit(); |
746 | 0 | Errno::result(LIBC_FSTATFS(fd.as_raw_fd(), stat.as_mut_ptr())) |
747 | 0 | .map(|_| Statfs(stat.assume_init())) |
748 | 0 | } |
749 | 0 | } |
750 | | |
751 | | #[cfg(test)] |
752 | | mod test { |
753 | | use std::fs::File; |
754 | | |
755 | | use crate::sys::statfs::*; |
756 | | use crate::sys::statvfs::*; |
757 | | use std::path::Path; |
758 | | |
759 | | #[test] |
760 | | fn statfs_call() { |
761 | | check_statfs("/tmp"); |
762 | | check_statfs("/dev"); |
763 | | check_statfs("/run"); |
764 | | check_statfs("/"); |
765 | | } |
766 | | |
767 | | #[test] |
768 | | fn fstatfs_call() { |
769 | | check_fstatfs("/tmp"); |
770 | | check_fstatfs("/dev"); |
771 | | check_fstatfs("/run"); |
772 | | check_fstatfs("/"); |
773 | | } |
774 | | |
775 | | fn check_fstatfs(path: &str) { |
776 | | if !Path::new(path).exists() { |
777 | | return; |
778 | | } |
779 | | let vfs = statvfs(path.as_bytes()).unwrap(); |
780 | | let file = File::open(path).unwrap(); |
781 | | let fs = fstatfs(&file).unwrap(); |
782 | | assert_fs_equals(fs, vfs); |
783 | | } |
784 | | |
785 | | fn check_statfs(path: &str) { |
786 | | if !Path::new(path).exists() { |
787 | | return; |
788 | | } |
789 | | let vfs = statvfs(path.as_bytes()).unwrap(); |
790 | | let fs = statfs(path.as_bytes()).unwrap(); |
791 | | assert_fs_equals(fs, vfs); |
792 | | } |
793 | | |
794 | | // The cast is not unnecessary on all platforms. |
795 | | #[allow(clippy::unnecessary_cast)] |
796 | | fn assert_fs_equals(fs: Statfs, vfs: Statvfs) { |
797 | | assert_eq!(fs.files() as u64, vfs.files() as u64); |
798 | | assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); |
799 | | assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64); |
800 | | } |
801 | | |
802 | | // This test is ignored because files_free/blocks_free can change after statvfs call and before |
803 | | // statfs call. |
804 | | #[test] |
805 | | #[ignore] |
806 | | fn statfs_call_strict() { |
807 | | check_statfs_strict("/tmp"); |
808 | | check_statfs_strict("/dev"); |
809 | | check_statfs_strict("/run"); |
810 | | check_statfs_strict("/"); |
811 | | } |
812 | | |
813 | | // This test is ignored because files_free/blocks_free can change after statvfs call and before |
814 | | // fstatfs call. |
815 | | #[test] |
816 | | #[ignore] |
817 | | fn fstatfs_call_strict() { |
818 | | check_fstatfs_strict("/tmp"); |
819 | | check_fstatfs_strict("/dev"); |
820 | | check_fstatfs_strict("/run"); |
821 | | check_fstatfs_strict("/"); |
822 | | } |
823 | | |
824 | | fn check_fstatfs_strict(path: &str) { |
825 | | if !Path::new(path).exists() { |
826 | | return; |
827 | | } |
828 | | let vfs = statvfs(path.as_bytes()); |
829 | | let file = File::open(path).unwrap(); |
830 | | let fs = fstatfs(&file); |
831 | | assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) |
832 | | } |
833 | | |
834 | | fn check_statfs_strict(path: &str) { |
835 | | if !Path::new(path).exists() { |
836 | | return; |
837 | | } |
838 | | let vfs = statvfs(path.as_bytes()); |
839 | | let fs = statfs(path.as_bytes()); |
840 | | assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) |
841 | | } |
842 | | |
843 | | // The cast is not unnecessary on all platforms. |
844 | | #[allow(clippy::unnecessary_cast)] |
845 | | fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) { |
846 | | assert_eq!(fs.files_free() as u64, vfs.files_free() as u64); |
847 | | assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64); |
848 | | assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64); |
849 | | assert_eq!(fs.files() as u64, vfs.files() as u64); |
850 | | assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); |
851 | | assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64); |
852 | | } |
853 | | } |