[libc-commits] [libc] [libc] Add <sys/statfs.h> header and entrypoints. (PR #213108)

Alexey Samsonov via libc-commits libc-commits at lists.llvm.org
Fri Jul 31 07:21:41 PDT 2026


https://github.com/vonosmas updated https://github.com/llvm/llvm-project/pull/213108

>From 90a9f2fedfaa49cd459fa5915e14d1547506bdbf Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Thu, 30 Jul 2026 19:14:04 +0000
Subject: [PATCH 1/3] [libc] Add <sys/statfs.h> header and entrypoints.

---
 libc/config/linux/aarch64/entrypoints.txt     |  6 +-
 libc/config/linux/aarch64/headers.txt         |  1 +
 libc/config/linux/riscv/entrypoints.txt       |  6 +-
 libc/config/linux/riscv/headers.txt           |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  6 +-
 libc/config/linux/x86_64/headers.txt          |  1 +
 libc/include/CMakeLists.txt                   | 13 ++++
 libc/include/llvm-libc-macros/CMakeLists.txt  |  6 ++
 .../llvm-libc-macros/linux/CMakeLists.txt     |  6 ++
 .../linux/sys-statfs-macros.h                 | 21 ++++++
 .../llvm-libc-macros/sys-statfs-macros.h      | 21 ++++++
 libc/include/sys/statfs.yaml                  | 19 ++++++
 libc/src/sys/CMakeLists.txt                   |  1 +
 libc/src/sys/statfs/CMakeLists.txt            | 17 +++++
 libc/src/sys/statfs/fstatfs.h                 | 26 ++++++++
 libc/src/sys/statfs/linux/CMakeLists.txt      | 25 +++++++
 libc/src/sys/statfs/linux/fstatfs.cpp         | 33 ++++++++++
 libc/src/sys/statfs/linux/statfs.cpp          | 33 ++++++++++
 libc/src/sys/statfs/statfs.h                  | 26 ++++++++
 libc/test/src/sys/CMakeLists.txt              |  1 +
 libc/test/src/sys/statfs/CMakeLists.txt       |  3 +
 libc/test/src/sys/statfs/linux/CMakeLists.txt | 35 ++++++++++
 .../src/sys/statfs/linux/fstatfs_test.cpp     | 65 +++++++++++++++++++
 .../test/src/sys/statfs/linux/statfs_test.cpp | 56 ++++++++++++++++
 24 files changed, 425 insertions(+), 3 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/linux/sys-statfs-macros.h
 create mode 100644 libc/include/llvm-libc-macros/sys-statfs-macros.h
 create mode 100644 libc/include/sys/statfs.yaml
 create mode 100644 libc/src/sys/statfs/CMakeLists.txt
 create mode 100644 libc/src/sys/statfs/fstatfs.h
 create mode 100644 libc/src/sys/statfs/linux/CMakeLists.txt
 create mode 100644 libc/src/sys/statfs/linux/fstatfs.cpp
 create mode 100644 libc/src/sys/statfs/linux/statfs.cpp
 create mode 100644 libc/src/sys/statfs/statfs.h
 create mode 100644 libc/test/src/sys/statfs/CMakeLists.txt
 create mode 100644 libc/test/src/sys/statfs/linux/CMakeLists.txt
 create mode 100644 libc/test/src/sys/statfs/linux/fstatfs_test.cpp
 create mode 100644 libc/test/src/sys/statfs/linux/statfs_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 2cfbc1e2b69fc..1ccb6cf202cf7 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -334,7 +334,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.stat
     libc.src.sys.stat.utimensat
 
-    # sys/statvfs.h
+    # sys/statfs.h entrypoints
+    libc.src.sys.statfs.fstatfs
+    libc.src.sys.statfs.statfs
+
+    # sys/statvfs.h entrypoints
     libc.src.sys.statvfs.fstatvfs
     libc.src.sys.statvfs.statvfs
 
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 37d7ab9530c3b..7fa15ba303893 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -63,6 +63,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_socket
     libc.include.sys_stat
     libc.include.sys_statvfs
+    libc.include.sys_statfs
     libc.include.sys_syscall
     libc.include.sys_time
     libc.include.sys_types
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 256e3a7dc3a87..5083417b453be 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -365,7 +365,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.stat
     libc.src.sys.stat.utimensat
 
-    # sys/statvfs.h
+    # sys/statfs.h entrypoints
+    libc.src.sys.statfs.fstatfs
+    libc.src.sys.statfs.statfs
+
+    # sys/statvfs.h entrypoints
     libc.src.sys.statvfs.fstatvfs
     libc.src.sys.statvfs.statvfs
 
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index 7fb172f86b1db..e133e782021a0 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -64,6 +64,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_socket
     libc.include.sys_stat
     libc.include.sys_statvfs
+    libc.include.sys_statfs
     libc.include.sys_syscall
     libc.include.sys_time
     libc.include.sys_types
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 619fc9b85ae48..bf809e268f585 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -370,7 +370,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.stat
     libc.src.sys.stat.utimensat
 
-    # sys/statvfs.h
+    # sys/statfs.h entrypoints
+    libc.src.sys.statfs.fstatfs
+    libc.src.sys.statfs.statfs
+
+    # sys/statvfs.h entrypoints
     libc.src.sys.statvfs.fstatvfs
     libc.src.sys.statvfs.statvfs
 
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 5fd4039eda139..b8751f7810b30 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -65,6 +65,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_signal
     libc.include.sys_socket
     libc.include.sys_stat
+    libc.include.sys_statfs
     libc.include.sys_statvfs
     libc.include.sys_syscall
     libc.include.sys_time
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 941c9c748bc0c..b9b46c3762180 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -860,6 +860,19 @@ add_header_macro(
     .llvm-libc-types.struct_sockaddr_storage
 )
 
+add_header_macro(
+  sys_statfs
+  ../libc/include/sys/statfs.yaml
+  sys/statfs.h
+  DEPENDS
+    .llvm_libc_common_h
+    .llvm-libc-types.fsblkcnt_t
+    .llvm-libc-types.fsfilcnt_t
+    .llvm-libc-types.fsid_t
+    .llvm-libc-types.struct_statfs
+    .llvm-libc-macros.sys_statfs_macros
+)
+
 add_header_macro(
   sys_statvfs
   ../libc/include/sys/statvfs.yaml
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index f0f9dabb00433..45a1dbc851d2c 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -267,6 +267,12 @@ add_macro_header(
     sys-stat-macros.h
 )
 
+add_macro_header(
+  sys_statfs_macros
+  HDR
+    sys-statfs-macros.h
+)
+
 add_macro_header(
   sys_mman_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 2a400b1c80e2c..c07c6dee8c797 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -100,6 +100,12 @@ add_header(
     sys-stat-macros.h
 )
 
+add_header(
+  sys_statfs_macros
+  HDR
+    sys-statfs-macros.h
+)
+
 add_header(
   sys_time_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/sys-statfs-macros.h b/libc/include/llvm-libc-macros/linux/sys-statfs-macros.h
new file mode 100644
index 0000000000000..1e3dbc2cc453a
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/sys-statfs-macros.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux specific declarations of macros from sys/statfs.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
+
+// There are numerous possible values for f_type field, defined in
+// the Linux kernel header. Include it directly.
+#include <linux/magic.h>
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
diff --git a/libc/include/llvm-libc-macros/sys-statfs-macros.h b/libc/include/llvm-libc-macros/sys-statfs-macros.h
new file mode 100644
index 0000000000000..36dcec917ae8e
--- /dev/null
+++ b/libc/include/llvm-libc-macros/sys-statfs-macros.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Macros defined in sys/statfs.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-statfs-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
diff --git a/libc/include/sys/statfs.yaml b/libc/include/sys/statfs.yaml
new file mode 100644
index 0000000000000..337a3e33357f1
--- /dev/null
+++ b/libc/include/sys/statfs.yaml
@@ -0,0 +1,19 @@
+header: sys/statfs.h
+standards:
+  - linux
+macros:
+  - macro_name: ADFS_SUPER_MAGIC
+    macro_header: sys-statfs-macros.h
+types:
+  - type_name: struct_statfs
+functions:
+  - name: fstatfs
+    return_type: int
+    arguments:
+      - type: int
+      - type: struct statfs *
+  - name: statfs
+    return_type: int
+    arguments:
+      - type: const char *
+      - type: struct statfs *
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index 69e96c0e1705b..95334f0084f07 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -10,6 +10,7 @@ add_subdirectory(socket)
 add_subdirectory(sem)
 add_subdirectory(sendfile)
 add_subdirectory(stat)
+add_subdirectory(statfs)
 add_subdirectory(statvfs)
 add_subdirectory(time)
 add_subdirectory(utsname)
diff --git a/libc/src/sys/statfs/CMakeLists.txt b/libc/src/sys/statfs/CMakeLists.txt
new file mode 100644
index 0000000000000..7db6450b2aa31
--- /dev/null
+++ b/libc/src/sys/statfs/CMakeLists.txt
@@ -0,0 +1,17 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+  statfs
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.statfs
+)
+
+add_entrypoint_object(
+  fstatfs
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.fstatfs
+)
diff --git a/libc/src/sys/statfs/fstatfs.h b/libc/src/sys/statfs/fstatfs.h
new file mode 100644
index 0000000000000..8cfc945250e7d
--- /dev/null
+++ b/libc/src/sys/statfs/fstatfs.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for fstatfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_STATFS_FSTATFS_H
+#define LLVM_LIBC_SRC_SYS_STATFS_FSTATFS_H
+
+#include "hdr/types/struct_statfs.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int fstatfs(int fd, struct statfs *buf);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_STATFS_FSTATFS_H
diff --git a/libc/src/sys/statfs/linux/CMakeLists.txt b/libc/src/sys/statfs/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..01f4b3dfd08ae
--- /dev/null
+++ b/libc/src/sys/statfs/linux/CMakeLists.txt
@@ -0,0 +1,25 @@
+add_entrypoint_object(
+  statfs
+  SRCS
+    statfs.cpp
+  HDRS
+    ../statfs.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.__support.macros.null_check
+    libc.src.__support.OSUtil.linux.syscall_wrappers.statfs
+    libc.hdr.types.struct_statfs
+)
+
+add_entrypoint_object(
+  fstatfs
+  SRCS
+    fstatfs.cpp
+  HDRS
+    ../fstatfs.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.__support.macros.null_check
+    libc.src.__support.OSUtil.linux.syscall_wrappers.fstatfs
+    libc.hdr.types.struct_statfs
+)
diff --git a/libc/src/sys/statfs/linux/fstatfs.cpp b/libc/src/sys/statfs/linux/fstatfs.cpp
new file mode 100644
index 0000000000000..ebdcedf05b8f2
--- /dev/null
+++ b/libc/src/sys/statfs/linux/fstatfs.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of fstatfs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/statfs/fstatfs.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/fstatfs.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fstatfs, (int fd, struct statfs *buf)) {
+  LIBC_CRASH_ON_NULLPTR(buf);
+  auto error_or_ret = linux_syscalls::fstatfs(fd, buf);
+  if (!error_or_ret) {
+    libc_errno = error_or_ret.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/statfs/linux/statfs.cpp b/libc/src/sys/statfs/linux/statfs.cpp
new file mode 100644
index 0000000000000..cb3bebcc1b786
--- /dev/null
+++ b/libc/src/sys/statfs/linux/statfs.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/statfs/statfs.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/statfs.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, statfs, (const char *path, struct statfs *buf)) {
+  LIBC_CRASH_ON_NULLPTR(buf);
+  auto error_or_ret = linux_syscalls::statfs(path, buf);
+  if (!error_or_ret) {
+    libc_errno = error_or_ret.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/statfs/statfs.h b/libc/src/sys/statfs/statfs.h
new file mode 100644
index 0000000000000..59fd969010ca1
--- /dev/null
+++ b/libc/src/sys/statfs/statfs.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_STATFS_STATFS_H
+#define LLVM_LIBC_SRC_SYS_STATFS_STATFS_H
+
+#include "hdr/types/struct_statfs.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int statfs(const char *path, struct statfs *buf);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_STATFS_STATFS_H
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 9af889bffa46d..51a55497a162c 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -7,6 +7,7 @@ add_subdirectory(sendfile)
 add_subdirectory(socket)
 add_subdirectory(stat)
 add_subdirectory(statvfs)
+add_subdirectory(statfs)
 add_subdirectory(utsname)
 add_subdirectory(wait)
 add_subdirectory(prctl)
diff --git a/libc/test/src/sys/statfs/CMakeLists.txt b/libc/test/src/sys/statfs/CMakeLists.txt
new file mode 100644
index 0000000000000..b4bbe81c92ff2
--- /dev/null
+++ b/libc/test/src/sys/statfs/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/sys/statfs/linux/CMakeLists.txt b/libc/test/src/sys/statfs/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..6ba3f35148bdb
--- /dev/null
+++ b/libc/test/src/sys/statfs/linux/CMakeLists.txt
@@ -0,0 +1,35 @@
+add_custom_target(libc_sys_statfs_unittests)
+
+add_libc_unittest(
+  statfs_test
+  SUITE
+    libc_sys_statfs_unittests
+  SRCS
+    statfs_test.cpp
+  DEPENDS
+    libc.hdr.sys_stat_macros
+    libc.src.errno.errno
+    libc.src.sys.statfs.statfs
+    libc.src.sys.stat.mkdirat
+    libc.src.unistd.rmdir
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+add_libc_unittest(
+  fstatfs_test
+  SUITE
+    libc_sys_statfs_unittests
+  SRCS
+    fstatfs_test.cpp
+  DEPENDS
+    libc.hdr.sys_stat_macros
+    libc.src.errno.errno
+    libc.src.sys.statfs.fstatfs
+    libc.src.sys.stat.mkdirat
+    libc.src.unistd.rmdir
+    libc.src.fcntl.open
+    libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/statfs/linux/fstatfs_test.cpp b/libc/test/src/sys/statfs/linux/fstatfs_test.cpp
new file mode 100644
index 0000000000000..a89e506f1cf62
--- /dev/null
+++ b/libc/test/src/sys/statfs/linux/fstatfs_test.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for fstatfs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/fcntl/open.h"
+#include "src/sys/stat/mkdirat.h"
+#include "src/sys/statfs/fstatfs.h"
+#include "src/unistd/close.h"
+#include "src/unistd/rmdir.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcSysFStatfsTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSysFStatfsTest, FStatfsBasic) {
+  struct statfs buf;
+
+  int fd = LIBC_NAMESPACE::open("/", O_PATH);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+
+  // The root of the file directory must always exist
+  ASSERT_THAT(LIBC_NAMESPACE::fstatfs(fd, &buf), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
+
+TEST_F(LlvmLibcSysFStatfsTest, FStatfsInvalidPath) {
+  struct statfs buf;
+
+  constexpr const char *FILENAME = "fstatfs.testdir";
+  auto TEST_DIR = libc_make_test_file_path(FILENAME);
+
+  // Always delete the folder so that we start in a consistent state.
+  LIBC_NAMESPACE::rmdir(TEST_DIR);
+  libc_errno = 0; // Reset errno
+
+  ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
+              Succeeds(0));
+
+  int fd = LIBC_NAMESPACE::open(TEST_DIR, O_PATH);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+
+  ASSERT_THAT(LIBC_NAMESPACE::fstatfs(fd, &buf), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+
+  ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));
+
+  ASSERT_THAT(LIBC_NAMESPACE::fstatfs(fd, &buf), Fails(EBADF));
+}
diff --git a/libc/test/src/sys/statfs/linux/statfs_test.cpp b/libc/test/src/sys/statfs/linux/statfs_test.cpp
new file mode 100644
index 0000000000000..6868cd50c99bb
--- /dev/null
+++ b/libc/test/src/sys/statfs/linux/statfs_test.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/sys/stat/mkdirat.h"
+#include "src/sys/statfs/statfs.h"
+#include "src/unistd/rmdir.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcSysStatfsTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSysStatfsTest, StatfsBasic) {
+  struct statfs buf;
+  // The root of the file directory must always exist
+  ASSERT_THAT(LIBC_NAMESPACE::statfs("/", &buf), Succeeds());
+}
+
+TEST_F(LlvmLibcSysStatfsTest, StatfsInvalidPath) {
+  struct statfs buf;
+
+  ASSERT_THAT(LIBC_NAMESPACE::statfs("", &buf), Fails(ENOENT));
+
+  // create the file, assert it exists, then delete it and assert it doesn't
+  // exist anymore.
+  constexpr const char *FILENAME = "statfs.testdir";
+  auto TEST_DIR = libc_make_test_file_path(FILENAME);
+
+  // Always delete the folder so that we start in a consistent state.
+  LIBC_NAMESPACE::rmdir(TEST_DIR);
+  libc_errno = 0; // Reset errno
+
+  ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
+              Succeeds(0));
+
+  ASSERT_THAT(LIBC_NAMESPACE::statfs(TEST_DIR, &buf), Succeeds());
+
+  ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));
+
+  ASSERT_THAT(LIBC_NAMESPACE::statfs(TEST_DIR, &buf), Fails(ENOENT));
+}

>From 0cfa774d121c5cb30dd07dd2c6a5c25217698388 Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Thu, 30 Jul 2026 19:21:53 +0000
Subject: [PATCH 2/3] ordering/formatting

---
 libc/config/linux/aarch64/headers.txt | 2 +-
 libc/config/linux/riscv/headers.txt   | 2 +-
 libc/include/CMakeLists.txt           | 5 +----
 libc/test/src/sys/CMakeLists.txt      | 2 +-
 4 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 7fa15ba303893..5f8b9c2aeaf5b 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -62,8 +62,8 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_signal
     libc.include.sys_socket
     libc.include.sys_stat
-    libc.include.sys_statvfs
     libc.include.sys_statfs
+    libc.include.sys_statvfs
     libc.include.sys_syscall
     libc.include.sys_time
     libc.include.sys_types
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index e133e782021a0..0b1d7dc7dff34 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -63,8 +63,8 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_signal
     libc.include.sys_socket
     libc.include.sys_stat
-    libc.include.sys_statvfs
     libc.include.sys_statfs
+    libc.include.sys_statvfs
     libc.include.sys_syscall
     libc.include.sys_time
     libc.include.sys_types
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index b9b46c3762180..2081adc78e7b8 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -866,11 +866,8 @@ add_header_macro(
   sys/statfs.h
   DEPENDS
     .llvm_libc_common_h
-    .llvm-libc-types.fsblkcnt_t
-    .llvm-libc-types.fsfilcnt_t
-    .llvm-libc-types.fsid_t
-    .llvm-libc-types.struct_statfs
     .llvm-libc-macros.sys_statfs_macros
+    .llvm-libc-types.struct_statfs
 )
 
 add_header_macro(
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 51a55497a162c..85f702edcb14e 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -6,8 +6,8 @@ add_subdirectory(select)
 add_subdirectory(sendfile)
 add_subdirectory(socket)
 add_subdirectory(stat)
-add_subdirectory(statvfs)
 add_subdirectory(statfs)
+add_subdirectory(statvfs)
 add_subdirectory(utsname)
 add_subdirectory(wait)
 add_subdirectory(prctl)

>From f57962dbe2e33f43d88187e90efb5b8188a2d48e Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Fri, 31 Jul 2026 14:20:20 +0000
Subject: [PATCH 3/3] Remove explicit null checks.

---
 libc/src/sys/statfs/linux/CMakeLists.txt | 2 --
 libc/src/sys/statfs/linux/fstatfs.cpp    | 2 --
 libc/src/sys/statfs/linux/statfs.cpp     | 2 --
 3 files changed, 6 deletions(-)

diff --git a/libc/src/sys/statfs/linux/CMakeLists.txt b/libc/src/sys/statfs/linux/CMakeLists.txt
index 01f4b3dfd08ae..34cec1e37c0d2 100644
--- a/libc/src/sys/statfs/linux/CMakeLists.txt
+++ b/libc/src/sys/statfs/linux/CMakeLists.txt
@@ -6,7 +6,6 @@ add_entrypoint_object(
     ../statfs.h
   DEPENDS
     libc.src.errno.errno
-    libc.src.__support.macros.null_check
     libc.src.__support.OSUtil.linux.syscall_wrappers.statfs
     libc.hdr.types.struct_statfs
 )
@@ -19,7 +18,6 @@ add_entrypoint_object(
     ../fstatfs.h
   DEPENDS
     libc.src.errno.errno
-    libc.src.__support.macros.null_check
     libc.src.__support.OSUtil.linux.syscall_wrappers.fstatfs
     libc.hdr.types.struct_statfs
 )
diff --git a/libc/src/sys/statfs/linux/fstatfs.cpp b/libc/src/sys/statfs/linux/fstatfs.cpp
index ebdcedf05b8f2..ddfc482fd3014 100644
--- a/libc/src/sys/statfs/linux/fstatfs.cpp
+++ b/libc/src/sys/statfs/linux/fstatfs.cpp
@@ -16,12 +16,10 @@
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include "src/__support/macros/null_check.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fstatfs, (int fd, struct statfs *buf)) {
-  LIBC_CRASH_ON_NULLPTR(buf);
   auto error_or_ret = linux_syscalls::fstatfs(fd, buf);
   if (!error_or_ret) {
     libc_errno = error_or_ret.error();
diff --git a/libc/src/sys/statfs/linux/statfs.cpp b/libc/src/sys/statfs/linux/statfs.cpp
index cb3bebcc1b786..376bb42cfbf47 100644
--- a/libc/src/sys/statfs/linux/statfs.cpp
+++ b/libc/src/sys/statfs/linux/statfs.cpp
@@ -16,12 +16,10 @@
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include "src/__support/macros/null_check.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, statfs, (const char *path, struct statfs *buf)) {
-  LIBC_CRASH_ON_NULLPTR(buf);
   auto error_or_ret = linux_syscalls::statfs(path, buf);
   if (!error_or_ret) {
     libc_errno = error_or_ret.error();



More information about the libc-commits mailing list