[libc-commits] [libc] [libc] add statvfs/fstatvfs (PR #86169)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Mon Mar 25 06:58:32 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 slightly prefer the "return value" approach, as there are not two references being passed into the same function whose aliasing may concern the compiler (although it should not matter too much for an internal inlined function). 

https://github.com/llvm/llvm-project/pull/86169


More information about the libc-commits mailing list