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