[libc-commits] [libc] [libc] add statvfs/fstatvfs (PR #86169)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Sun Mar 24 12:39:15 PDT 2024
================
@@ -0,0 +1,85 @@
+//===-- Convert Statfs to Statvfs -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
+#define LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
+
+#include "llvm-libc-types/struct_statvfs.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/macros/attributes.h"
+#include "src/errno/libc_errno.h"
+#include <asm/statfs.h>
+#include <sys/syscall.h>
+namespace LIBC_NAMESPACE {
+
+namespace statfs_utils {
+#ifdef SYS_statfs64
+using LinuxStatFs = statfs64;
+#else
+using LinuxStatFs = statfs;
+#endif
+
+LIBC_INLINE cpp::optional<LinuxStatFs> linux_statfs(const char *path) {
+#ifdef __clang__
+ // Disable pattern filling for result buffer: this struct is to be populated
+ // by the syscall.
+ [[clang::uninitialized]]
+#endif
+ LinuxStatFs result;
+ // On 32-bit platforms, original statfs cannot handle large file systems.
+ // In such cases, SYS_statfs64 is defined and should be used.
+#ifdef SYS_statfs64
+ int ret = syscall_impl<int>(SYS_statfs64, path, sizeof(result), &result);
+#else
+ int ret = syscall_impl<int>(SYS_statfs, path, &result);
+#endif
+ if (ret < 0) {
+ libc_errno = -ret;
+ return cpp::nullopt;
+ }
+ return result;
+}
+
+LIBC_INLINE cpp::optional<LinuxStatFs> linux_fstatfs(int fd) {
+ LinuxStatFs result;
+ // On 32-bit platforms, original fstatfs cannot handle large file systems.
+ // In such cases, SYS_fstatfs64 is defined and should be used.
+#ifdef SYS_fstatfs64
+ int ret = syscall_impl<int>(SYS_fstatfs64, fd, sizeof(result), &result);
+#else
+ int ret = syscall_impl<int>(SYS_fstatfs, fd, &result);
+#endif
+ if (ret < 0) {
+ libc_errno = -ret;
+ return cpp::nullopt;
+ }
+ return result;
+}
+
+// use struct stat(v)fs to avoid conflicts with the function names.
+LIBC_INLINE struct statvfs statfs_to_statvfs(const LinuxStatFs &in) {
+ struct statvfs out;
----------------
SchrodingerZhu wrote:
I checked the codegen. NVRO is applied.
```c++
0000000000000000 <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)>:
0: 53 push %rbx
1: 48 81 ec 80 00 00 00 sub $0x80,%rsp
8: 48 89 f2 mov %rsi,%rdx
b: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
12: 00 00
14: 48 89 44 24 78 mov %rax,0x78(%rsp)
19: 48 b8 aa aa aa aa aa movabs $0xaaaaaaaaaaaaaaaa,%rax
20: aa aa aa
23: 48 89 44 24 70 mov %rax,0x70(%rsp)
28: 0f 28 05 00 00 00 00 movaps 0x0(%rip),%xmm0 # 2f <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0x2f>
2f: 0f 29 44 24 60 movaps %xmm0,0x60(%rsp)
34: 0f 29 44 24 50 movaps %xmm0,0x50(%rsp)
39: 0f 29 44 24 40 movaps %xmm0,0x40(%rsp)
3e: 0f 29 44 24 30 movaps %xmm0,0x30(%rsp)
43: 0f 29 44 24 20 movaps %xmm0,0x20(%rsp)
48: 0f 29 44 24 10 movaps %xmm0,0x10(%rsp)
4d: 0f 29 04 24 movaps %xmm0,(%rsp)
51: 48 89 e6 mov %rsp,%rsi
54: b8 89 00 00 00 mov $0x89,%eax
59: 0f 05 syscall
5b: 48 89 c3 mov %rax,%rbx
5e: 85 db test %ebx,%ebx
60: 78 5d js bf <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xbf>
62: 48 8b 44 24 50 mov 0x50(%rsp),%rax
67: 48 83 e0 df and $0xffffffffffffffdf,%rax
6b: 48 8b 4c 24 08 mov 0x8(%rsp),%rcx
70: 48 8b 74 24 30 mov 0x30(%rsp),%rsi
75: 48 63 7c 24 38 movslq 0x38(%rsp),%rdi
7a: 4c 8b 44 24 40 mov 0x40(%rsp),%r8
7f: 4c 8b 4c 24 48 mov 0x48(%rsp),%r9
84: 44 8b 54 24 3c mov 0x3c(%rsp),%r10d
89: 49 c1 e2 20 shl $0x20,%r10
8d: 49 09 fa or %rdi,%r10
90: 0f 28 44 24 10 movaps 0x10(%rsp),%xmm0
95: 0f 28 4c 24 20 movaps 0x20(%rsp),%xmm1
9a: 48 89 0a mov %rcx,(%rdx)
9d: 4c 89 4a 08 mov %r9,0x8(%rdx)
a1: 0f 11 42 10 movups %xmm0,0x10(%rdx)
a5: 0f 11 4a 20 movups %xmm1,0x20(%rdx)
a9: 48 89 72 30 mov %rsi,0x30(%rdx)
ad: 48 89 72 38 mov %rsi,0x38(%rdx)
b1: 4c 89 52 40 mov %r10,0x40(%rdx)
b5: 48 89 42 48 mov %rax,0x48(%rdx)
b9: 4c 89 42 50 mov %r8,0x50(%rdx)
bd: eb 10 jmp cf <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xcf>
bf: 89 de mov %ebx,%esi
c1: f7 de neg %esi
c3: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # ca <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xca>
ca: e8 00 00 00 00 call cf <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xcf>
cf: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
d6: 00 00
d8: 48 3b 44 24 78 cmp 0x78(%rsp),%rax
dd: 75 0e jne ed <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xed>
df: c1 fb 1f sar $0x1f,%ebx
e2: 89 d8 mov %ebx,%eax
e4: 48 81 c4 80 00 00 00 add $0x80,%rsp
eb: 5b pop %rbx
ec: c3 ret
ed: e8 00 00 00 00 call f2 <__llvm_libc_19_0_0_git::statvfs(char const*, statvfs*)+0xf2>
```
I also checked that the passing two references generate the identical code with slightly different debug annotation.
https://github.com/llvm/llvm-project/pull/86169
More information about the libc-commits
mailing list