[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