1#[repr(C)]
5struct kernel_statfs {
6 f_type: c_ulong,
7 f_bsize: c_ulong,
8 f_blocks: u64,
9 f_bfree: u64,
10 f_bavail: u64,
11 f_files: u64,
12 f_ffree: u64,
13 f_fsid: [c_int; 2],
14 f_namelen: c_ulong,
15 f_frsize: c_ulong,
16 f_flags: c_ulong,
17 f_spare: [c_ulong; 4],
18}
19
20#[repr(C)]
21pub struct statvfs {
22 pub f_bsize: c_ulong,
23 pub f_frsize: c_ulong,
24 pub f_blocks: u64,
25 pub f_bfree: u64,
26 pub f_bavail: u64,
27 pub f_files: u64,
28 pub f_ffree: u64,
29 pub f_favail: u64,
30 pub f_fsid: c_ulong,
31 pub f_flag: c_ulong,
32 pub f_namemax: c_ulong,
33 pub f_type: c_uint,
34 __reserved: [c_int; 5],
35}
36
37pub const ST_RDONLY: c_ulong = 1;
38pub const ST_NOSUID: c_ulong = 2;
39pub const ST_NODEV: c_ulong = 4;
40pub const ST_NOEXEC: c_ulong = 8;
41pub const ST_SYNCHRONOUS: c_ulong = 16;
42pub const ST_MANDLOCK: c_ulong = 64;
43pub const ST_WRITE: c_ulong = 128;
44pub const ST_APPEND: c_ulong = 256;
45pub const ST_IMMUTABLE: c_ulong = 512;
46pub const ST_NOATIME: c_ulong = 1024;
47pub const ST_NODIRATIME: c_ulong = 2048;
48pub const ST_RELATIME: c_ulong = 4096;
49
50#[inline]
52unsafe fn sys_statfs(path: *const c_char, buf: *mut kernel_statfs) -> i64 {
53 <Arch as Syscalls>::syscall2(SYS_STATFS, path as i64, buf as i64)
54}
55
56#[inline]
57unsafe fn sys_fstatfs(fd: c_int, buf: *mut kernel_statfs) -> i64 {
58 <Arch as Syscalls>::syscall2(SYS_FSTATFS, fd as i64, buf as i64)
59}
60
61unsafe fn fixup(out: *mut statvfs, kbuf: *const kernel_statfs) {
62 core::ptr::write_bytes(out, 0, 1);
63 (*out).f_bsize = (*kbuf).f_bsize;
64 (*out).f_frsize = if (*kbuf).f_frsize != 0 { (*kbuf).f_frsize } else { (*kbuf).f_bsize };
65 (*out).f_blocks = (*kbuf).f_blocks;
66 (*out).f_bfree = (*kbuf).f_bfree;
67 (*out).f_bavail = (*kbuf).f_bavail;
68 (*out).f_files = (*kbuf).f_files;
69 (*out).f_ffree = (*kbuf).f_ffree;
70 (*out).f_favail = (*kbuf).f_ffree;
71 (*out).f_fsid = (*kbuf).f_fsid[0] as c_ulong;
72 (*out).f_flag = (*kbuf).f_flags;
73 (*out).f_namemax = (*kbuf).f_namelen;
74 (*out).f_type = (*kbuf).f_type as c_uint;
75}
76
77#[no_mangle]
78pub unsafe extern "C" fn statvfs(path: *const c_char, buf: *mut statvfs) -> c_int {
79 let mut kbuf: kernel_statfs = core::mem::zeroed();
80 let r = sys_statfs(path, &mut kbuf);
81 if r < 0 {
82 ERRNO!() = (-r) as c_int;
83 return -1;
84 }
85 fixup(buf, &kbuf);
86 0
87}
88
89#[no_mangle]
90pub unsafe extern "C" fn fstatvfs(fd: c_int, buf: *mut statvfs) -> c_int {
91 let mut kbuf: kernel_statfs = core::mem::zeroed();
92 let r = sys_fstatfs(fd, &mut kbuf);
93 if r < 0 {
94 ERRNO!() = (-r) as c_int;
95 return -1;
96 }
97 fixup(buf, &kbuf);
98 0
99}