1 use std::fmt::{self, Debug};
2 use std::mem;
3 use std::os::unix::io::AsRawFd;
4 #[cfg(not(any(target_os = "linux", target_os = "android")))]
5 use std::ffi::CStr;
6
7 use crate::{NixPath, Result, errno::Errno};
8
9 #[cfg(target_os = "android")]
10 pub type fsid_t = libc::__fsid_t;
11 #[cfg(not(target_os = "android"))]
12 pub type fsid_t = libc::fsid_t;
13
14 #[derive(Clone, Copy)]
15 #[repr(transparent)]
16 pub struct Statfs(libc::statfs);
17
18 #[cfg(target_os = "freebsd")]
19 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
20 pub struct FsType(pub u32);
21 #[cfg(target_os = "android")]
22 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
23 pub struct FsType(pub libc::c_ulong);
24 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
25 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
26 pub struct FsType(pub u32);
27 #[cfg(all(target_os = "linux", target_env = "musl"))]
28 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
29 pub struct FsType(pub libc::c_ulong);
30 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
31 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
32 pub struct FsType(pub libc::c_long);
33
34 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
35 pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC);
36 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
37 pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC);
38 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
39 pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC);
40 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
41 pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC);
42 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43 pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC);
44 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
45 pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC);
46 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
47 pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC);
48 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
49 pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC);
50 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
51 pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC);
52 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
53 pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC);
54 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
55 pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC);
56 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
57 pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC);
58 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
59 pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC);
60 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
61 pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2);
62 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
63 pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC);
64 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
65 pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2);
66 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
67 pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC);
68 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
69 pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC);
70 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
71 pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC);
72 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
73 pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC);
74 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
75 pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC);
76 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
77 pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC);
78 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
79 pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC);
80 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
81 pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC);
82 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
83 pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC);
84 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
85 pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC);
86 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
87 pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC);
88 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
89 pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC);
90 #[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
91 pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC);
92
93 impl Statfs {
94 /// Magic code defining system type
95 #[cfg(not(any(
96 target_os = "openbsd",
97 target_os = "dragonfly",
98 target_os = "ios",
99 target_os = "macos"
100 )))]
filesystem_type(&self) -> FsType101 pub fn filesystem_type(&self) -> FsType {
102 FsType(self.0.f_type)
103 }
104
105 /// Magic code defining system type
106 #[cfg(not(any(target_os = "linux", target_os = "android")))]
filesystem_type_name(&self) -> &str107 pub fn filesystem_type_name(&self) -> &str {
108 let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) };
109 c_str.to_str().unwrap()
110 }
111
112 /// Optimal transfer block size
113 #[cfg(any(target_os = "ios", target_os = "macos"))]
optimal_transfer_size(&self) -> i32114 pub fn optimal_transfer_size(&self) -> i32 {
115 self.0.f_iosize
116 }
117
118 /// Optimal transfer block size
119 #[cfg(target_os = "openbsd")]
optimal_transfer_size(&self) -> u32120 pub fn optimal_transfer_size(&self) -> u32 {
121 self.0.f_iosize
122 }
123
124 /// Optimal transfer block size
125 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
optimal_transfer_size(&self) -> u32126 pub fn optimal_transfer_size(&self) -> u32 {
127 self.0.f_bsize
128 }
129
130 /// Optimal transfer block size
131 #[cfg(any(
132 target_os = "android",
133 all(target_os = "linux", target_env = "musl")
134 ))]
optimal_transfer_size(&self) -> libc::c_ulong135 pub fn optimal_transfer_size(&self) -> libc::c_ulong {
136 self.0.f_bsize
137 }
138
139 /// Optimal transfer block size
140 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
optimal_transfer_size(&self) -> libc::c_long141 pub fn optimal_transfer_size(&self) -> libc::c_long {
142 self.0.f_bsize
143 }
144
145 /// Optimal transfer block size
146 #[cfg(target_os = "dragonfly")]
optimal_transfer_size(&self) -> libc::c_long147 pub fn optimal_transfer_size(&self) -> libc::c_long {
148 self.0.f_iosize
149 }
150
151 /// Optimal transfer block size
152 #[cfg(target_os = "freebsd")]
optimal_transfer_size(&self) -> u64153 pub fn optimal_transfer_size(&self) -> u64 {
154 self.0.f_iosize
155 }
156
157 /// Size of a block
158 #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
block_size(&self) -> u32159 pub fn block_size(&self) -> u32 {
160 self.0.f_bsize
161 }
162
163 /// Size of a block
164 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
165 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
block_size(&self) -> u32166 pub fn block_size(&self) -> u32 {
167 self.0.f_bsize
168 }
169
170 /// Size of a block
171 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
172 #[cfg(all(target_os = "linux", target_env = "musl"))]
block_size(&self) -> libc::c_ulong173 pub fn block_size(&self) -> libc::c_ulong {
174 self.0.f_bsize
175 }
176
177 /// Size of a block
178 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
179 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
block_size(&self) -> libc::c_long180 pub fn block_size(&self) -> libc::c_long {
181 self.0.f_bsize
182 }
183
184 /// Size of a block
185 #[cfg(target_os = "freebsd")]
block_size(&self) -> u64186 pub fn block_size(&self) -> u64 {
187 self.0.f_bsize
188 }
189
190 /// Size of a block
191 #[cfg(target_os = "android")]
block_size(&self) -> libc::c_ulong192 pub fn block_size(&self) -> libc::c_ulong {
193 self.0.f_bsize
194 }
195
196 /// Size of a block
197 #[cfg(target_os = "dragonfly")]
block_size(&self) -> libc::c_long198 pub fn block_size(&self) -> libc::c_long {
199 self.0.f_bsize
200 }
201
202 /// Maximum length of filenames
203 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
maximum_name_length(&self) -> u32204 pub fn maximum_name_length(&self) -> u32 {
205 self.0.f_namemax
206 }
207
208 /// Maximum length of filenames
209 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
maximum_name_length(&self) -> u32210 pub fn maximum_name_length(&self) -> u32 {
211 self.0.f_namelen
212 }
213
214 /// Maximum length of filenames
215 #[cfg(all(target_os = "linux", target_env = "musl"))]
maximum_name_length(&self) -> libc::c_ulong216 pub fn maximum_name_length(&self) -> libc::c_ulong {
217 self.0.f_namelen
218 }
219
220 /// Maximum length of filenames
221 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
maximum_name_length(&self) -> libc::c_long222 pub fn maximum_name_length(&self) -> libc::c_long {
223 self.0.f_namelen
224 }
225
226 /// Maximum length of filenames
227 #[cfg(target_os = "android")]
maximum_name_length(&self) -> libc::c_ulong228 pub fn maximum_name_length(&self) -> libc::c_ulong {
229 self.0.f_namelen
230 }
231
232 /// Total data blocks in filesystem
233 #[cfg(any(
234 target_os = "ios",
235 target_os = "macos",
236 target_os = "android",
237 target_os = "freebsd",
238 target_os = "openbsd",
239 ))]
blocks(&self) -> u64240 pub fn blocks(&self) -> u64 {
241 self.0.f_blocks
242 }
243
244 /// Total data blocks in filesystem
245 #[cfg(target_os = "dragonfly")]
blocks(&self) -> libc::c_long246 pub fn blocks(&self) -> libc::c_long {
247 self.0.f_blocks
248 }
249
250 /// Total data blocks in filesystem
251 #[cfg(all(target_os = "linux", target_env = "musl"))]
blocks(&self) -> u64252 pub fn blocks(&self) -> u64 {
253 self.0.f_blocks
254 }
255
256 /// Total data blocks in filesystem
257 #[cfg(not(any(
258 target_os = "ios",
259 target_os = "macos",
260 target_os = "android",
261 target_os = "freebsd",
262 target_os = "openbsd",
263 target_os = "dragonfly",
264 all(target_os = "linux", target_env = "musl")
265 )))]
blocks(&self) -> libc::c_ulong266 pub fn blocks(&self) -> libc::c_ulong {
267 self.0.f_blocks
268 }
269
270 /// Free blocks in filesystem
271 #[cfg(any(
272 target_os = "ios",
273 target_os = "macos",
274 target_os = "android",
275 target_os = "freebsd",
276 target_os = "openbsd",
277 ))]
blocks_free(&self) -> u64278 pub fn blocks_free(&self) -> u64 {
279 self.0.f_bfree
280 }
281
282 /// Free blocks in filesystem
283 #[cfg(target_os = "dragonfly")]
blocks_free(&self) -> libc::c_long284 pub fn blocks_free(&self) -> libc::c_long {
285 self.0.f_bfree
286 }
287
288 /// Free blocks in filesystem
289 #[cfg(all(target_os = "linux", target_env = "musl"))]
blocks_free(&self) -> u64290 pub fn blocks_free(&self) -> u64 {
291 self.0.f_bfree
292 }
293
294 /// Free blocks in filesystem
295 #[cfg(not(any(
296 target_os = "ios",
297 target_os = "macos",
298 target_os = "android",
299 target_os = "freebsd",
300 target_os = "openbsd",
301 target_os = "dragonfly",
302 all(target_os = "linux", target_env = "musl")
303 )))]
blocks_free(&self) -> libc::c_ulong304 pub fn blocks_free(&self) -> libc::c_ulong {
305 self.0.f_bfree
306 }
307
308 /// Free blocks available to unprivileged user
309 #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
blocks_available(&self) -> u64310 pub fn blocks_available(&self) -> u64 {
311 self.0.f_bavail
312 }
313
314 /// Free blocks available to unprivileged user
315 #[cfg(target_os = "dragonfly")]
blocks_available(&self) -> libc::c_long316 pub fn blocks_available(&self) -> libc::c_long {
317 self.0.f_bavail
318 }
319
320 /// Free blocks available to unprivileged user
321 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
blocks_available(&self) -> i64322 pub fn blocks_available(&self) -> i64 {
323 self.0.f_bavail
324 }
325
326 /// Free blocks available to unprivileged user
327 #[cfg(all(target_os = "linux", target_env = "musl"))]
blocks_available(&self) -> u64328 pub fn blocks_available(&self) -> u64 {
329 self.0.f_bavail
330 }
331
332 /// Free blocks available to unprivileged user
333 #[cfg(not(any(
334 target_os = "ios",
335 target_os = "macos",
336 target_os = "android",
337 target_os = "freebsd",
338 target_os = "openbsd",
339 target_os = "dragonfly",
340 all(target_os = "linux", target_env = "musl")
341 )))]
blocks_available(&self) -> libc::c_ulong342 pub fn blocks_available(&self) -> libc::c_ulong {
343 self.0.f_bavail
344 }
345
346 /// Total file nodes in filesystem
347 #[cfg(any(
348 target_os = "ios",
349 target_os = "macos",
350 target_os = "android",
351 target_os = "freebsd",
352 target_os = "openbsd",
353 ))]
files(&self) -> u64354 pub fn files(&self) -> u64 {
355 self.0.f_files
356 }
357
358 /// Total file nodes in filesystem
359 #[cfg(target_os = "dragonfly")]
files(&self) -> libc::c_long360 pub fn files(&self) -> libc::c_long {
361 self.0.f_files
362 }
363
364 /// Total file nodes in filesystem
365 #[cfg(all(target_os = "linux", target_env = "musl"))]
files(&self) -> u64366 pub fn files(&self) -> u64 {
367 self.0.f_files
368 }
369
370 /// Total file nodes in filesystem
371 #[cfg(not(any(
372 target_os = "ios",
373 target_os = "macos",
374 target_os = "android",
375 target_os = "freebsd",
376 target_os = "openbsd",
377 target_os = "dragonfly",
378 all(target_os = "linux", target_env = "musl")
379 )))]
files(&self) -> libc::c_ulong380 pub fn files(&self) -> libc::c_ulong {
381 self.0.f_files
382 }
383
384 /// Free file nodes in filesystem
385 #[cfg(any(
386 target_os = "android",
387 target_os = "ios",
388 all(target_os = "linux", target_env = "musl"),
389 target_os = "macos",
390 target_os = "openbsd"
391 ))]
files_free(&self) -> u64392 pub fn files_free(&self) -> u64 {
393 self.0.f_ffree
394 }
395
396 /// Free file nodes in filesystem
397 #[cfg(target_os = "dragonfly")]
files_free(&self) -> libc::c_long398 pub fn files_free(&self) -> libc::c_long {
399 self.0.f_ffree
400 }
401
402 /// Free file nodes in filesystem
403 #[cfg(target_os = "freebsd")]
files_free(&self) -> i64404 pub fn files_free(&self) -> i64 {
405 self.0.f_ffree
406 }
407
408 /// Free file nodes in filesystem
409 #[cfg(not(any(
410 target_os = "ios",
411 target_os = "macos",
412 target_os = "android",
413 target_os = "freebsd",
414 target_os = "openbsd",
415 target_os = "dragonfly",
416 all(target_os = "linux", target_env = "musl")
417 )))]
files_free(&self) -> libc::c_ulong418 pub fn files_free(&self) -> libc::c_ulong {
419 self.0.f_ffree
420 }
421
422 /// Filesystem ID
filesystem_id(&self) -> fsid_t423 pub fn filesystem_id(&self) -> fsid_t {
424 self.0.f_fsid
425 }
426 }
427
428 impl Debug for Statfs {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result429 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
430 f.debug_struct("Statfs")
431 .field("optimal_transfer_size", &self.optimal_transfer_size())
432 .field("block_size", &self.block_size())
433 .field("blocks", &self.blocks())
434 .field("blocks_free", &self.blocks_free())
435 .field("blocks_available", &self.blocks_available())
436 .field("files", &self.files())
437 .field("files_free", &self.files_free())
438 .field("filesystem_id", &self.filesystem_id())
439 .finish()
440 }
441 }
442
statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs>443 pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
444 unsafe {
445 let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
446 let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?;
447 Errno::result(res).map(|_| Statfs(stat.assume_init()))
448 }
449 }
450
fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs>451 pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
452 unsafe {
453 let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
454 Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr()))
455 .map(|_| Statfs(stat.assume_init()))
456 }
457 }
458
459 #[cfg(test)]
460 mod test {
461 use std::fs::File;
462
463 use crate::sys::statfs::*;
464 use crate::sys::statvfs::*;
465 use std::path::Path;
466
467 #[test]
statfs_call()468 fn statfs_call() {
469 check_statfs("/tmp");
470 check_statfs("/dev");
471 check_statfs("/run");
472 check_statfs("/");
473 }
474
475 #[test]
fstatfs_call()476 fn fstatfs_call() {
477 check_fstatfs("/tmp");
478 check_fstatfs("/dev");
479 check_fstatfs("/run");
480 check_fstatfs("/");
481 }
482
check_fstatfs(path: &str)483 fn check_fstatfs(path: &str) {
484 if !Path::new(path).exists() {
485 return;
486 }
487 let vfs = statvfs(path.as_bytes()).unwrap();
488 let file = File::open(path).unwrap();
489 let fs = fstatfs(&file).unwrap();
490 assert_fs_equals(fs, vfs);
491 }
492
check_statfs(path: &str)493 fn check_statfs(path: &str) {
494 if !Path::new(path).exists() {
495 return;
496 }
497 let vfs = statvfs(path.as_bytes()).unwrap();
498 let fs = statfs(path.as_bytes()).unwrap();
499 assert_fs_equals(fs, vfs);
500 }
501
assert_fs_equals(fs: Statfs, vfs: Statvfs)502 fn assert_fs_equals(fs: Statfs, vfs: Statvfs) {
503 assert_eq!(fs.files() as u64, vfs.files() as u64);
504 assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
505 assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
506 }
507
508 // This test is ignored because files_free/blocks_free can change after statvfs call and before
509 // statfs call.
510 #[test]
511 #[ignore]
statfs_call_strict()512 fn statfs_call_strict() {
513 check_statfs_strict("/tmp");
514 check_statfs_strict("/dev");
515 check_statfs_strict("/run");
516 check_statfs_strict("/");
517 }
518
519 // This test is ignored because files_free/blocks_free can change after statvfs call and before
520 // fstatfs call.
521 #[test]
522 #[ignore]
fstatfs_call_strict()523 fn fstatfs_call_strict() {
524 check_fstatfs_strict("/tmp");
525 check_fstatfs_strict("/dev");
526 check_fstatfs_strict("/run");
527 check_fstatfs_strict("/");
528 }
529
check_fstatfs_strict(path: &str)530 fn check_fstatfs_strict(path: &str) {
531 if !Path::new(path).exists() {
532 return;
533 }
534 let vfs = statvfs(path.as_bytes());
535 let file = File::open(path).unwrap();
536 let fs = fstatfs(&file);
537 assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
538 }
539
check_statfs_strict(path: &str)540 fn check_statfs_strict(path: &str) {
541 if !Path::new(path).exists() {
542 return;
543 }
544 let vfs = statvfs(path.as_bytes());
545 let fs = statfs(path.as_bytes());
546 assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
547 }
548
assert_fs_equals_strict(fs: Statfs, vfs: Statvfs)549 fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) {
550 assert_eq!(fs.files_free() as u64, vfs.files_free() as u64);
551 assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64);
552 assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64);
553 assert_eq!(fs.files() as u64, vfs.files() as u64);
554 assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
555 assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
556 }
557 }
558