[libc-commits] [libc] [libc] Implement fallocate (PR #222843)
via libc-commits
libc-commits at lists.llvm.org
Wed Sep 16 19:20:30 PDT 2026
https://github.com/afnrow updated https://github.com/llvm/llvm-project/pull/222843
>From c5212f15f759b7ed2724136207628458d0fb6c30 Mon Sep 17 00:00:00 2001
From: yahia ahmed <yahia.a.abdrabou at gmail.com>
Date: Fri, 11 Sep 2026 08:12:28 +0300
Subject: [PATCH 1/5] [libc] Implement fallocate
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/include/fcntl.yaml | 9 +++
.../llvm-libc-macros/linux/fcntl-macros.h | 8 +++
.../linux/syscall_wrappers/CMakeLists.txt | 14 +++++
.../OSUtil/linux/syscall_wrappers/fallocate.h | 42 +++++++++++++
libc/src/fcntl/fallocate.h | 26 ++++++++
libc/src/fcntl/linux/CMakeLists.txt | 12 ++++
libc/src/fcntl/linux/fallocate.cpp | 32 ++++++++++
libc/test/src/fcntl/CMakeLists.txt | 16 +++++
libc/test/src/fcntl/fallocate_test.cpp | 59 +++++++++++++++++++
libc/utils/docgen/fcntl.yaml | 2 +
12 files changed, 222 insertions(+)
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
create mode 100644 libc/src/fcntl/fallocate.h
create mode 100644 libc/src/fcntl/linux/fallocate.cpp
create mode 100644 libc/test/src/fcntl/fallocate_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a63d6ad6282c1f..b8d40e5744547d 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -38,6 +38,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# fcntl.h entrypoints
libc.src.fcntl.creat
+ libc.src.fcntl.fallocate
libc.src.fcntl.fcntl
libc.src.fcntl.open
libc.src.fcntl.openat
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3f4e563e543595..711849cc2bb1f8 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -49,6 +49,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# fcntl.h entrypoints
libc.src.fcntl.creat
+ libc.src.fcntl.fallocate
libc.src.fcntl.fcntl
libc.src.fcntl.open
libc.src.fcntl.openat
diff --git a/libc/include/fcntl.yaml b/libc/include/fcntl.yaml
index 2b73c8da1e989e..49aac448e7076f 100644
--- a/libc/include/fcntl.yaml
+++ b/libc/include/fcntl.yaml
@@ -40,6 +40,15 @@ functions:
arguments:
- type: const char *
- type: mode_t
+ - name: fallocate
+ standards:
+ - linux
+ return_type: int
+ arguments:
+ - type: int
+ - type: int
+ - type: off_t
+ - type: off_t
- name: fcntl
standards:
- posix
diff --git a/libc/include/llvm-libc-macros/linux/fcntl-macros.h b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
index 648c4a9ec00da6..dc7be0b9045f99 100644
--- a/libc/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -24,6 +24,14 @@
#define O_SYNC 004010000
#define O_TRUNC 000001000
+#define FALLOC_FL_KEEP_SIZE 0x01
+#define FALLOC_FL_PUNCH_HOLE 0x02
+#define FALLOC_FL_NO_HIDE_STALE 0x04
+#define FALLOC_FL_COLLAPSE_RANGE 0x08
+#define FALLOC_FL_ZERO_RANGE 0x10
+#define FALLOC_FL_INSERT_RANGE 0x20
+#define FALLOC_FL_UNSHARE_RANGE 0x40
+
#ifdef __aarch64__
#define O_DIRECT 000200000
#define O_DIRECTORY 000040000
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 17665f87dfcd84..c24bec607ba52c 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -1303,3 +1303,17 @@ add_header_library(
libc.src.__support.macros.config
libc.src.__support.OSUtil.osutil
)
+
+add_header_library(
+ fallocate
+ HDRS
+ fallocate.h
+ DEPENDS
+ libc.src.__support.macros.config
+ libc.src.__support.common
+ libc.src.__support.OSUtil.osutil
+ libc.include.sys_syscall
+ libc.hdr.types.off_t
+ libc.hdr.errno_macros
+ libc.src.__support.error_or
+)
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
new file mode 100644
index 00000000000000..88cf78cd345d1a
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// This file contains the declaration of the fallocate, which is the
+/// base syscall wrapper for all fallocate dependent calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FALLOCATE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FALLOCATE_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/types/off_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> fallocate(int fd, int mode, off_t offset, off_t size) {
+#ifdef SYS_fallocate
+#if !__SIZEOF__POINTER == 8 // 64 bit machines
+ /* TODO: Add support for 32 bits */
+ return Error(ENOSYS);
+#else
+ return syscall_checked<int>(SYS_fallocate, fd, mode, offset, size);
+#endif
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+#endif
diff --git a/libc/src/fcntl/fallocate.h b/libc/src/fcntl/fallocate.h
new file mode 100644
index 00000000000000..bfc5605fe8251c
--- /dev/null
+++ b/libc/src/fcntl/fallocate.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 fallocate
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_FCNTL_FALLOCATE_H
+#define LLVM_LIBC_SRC_FCNTL_FALLOCATE_H
+
+#include "src/__support/macros/config.h"
+#include "hdr/types/off_t.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+ int fallocate(int fd, int mode, off_t offset, off_t size);
+
+}
+
+#endif
diff --git a/libc/src/fcntl/linux/CMakeLists.txt b/libc/src/fcntl/linux/CMakeLists.txt
index e50cc45c9ea7a1..9e20d9947acd6b 100644
--- a/libc/src/fcntl/linux/CMakeLists.txt
+++ b/libc/src/fcntl/linux/CMakeLists.txt
@@ -74,3 +74,15 @@ add_entrypoint_object(
libc.src.__support.common
libc.src.__support.macros.config
)
+
+add_entrypoint_object(
+ fallocate
+ SRCS
+ fallocate.cpp
+ HDRS
+ ../fallocate.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.OSUtil.linux.syscall_wrappers.fallocate
+ libc.hdr.types.off_t
+)
diff --git a/libc/src/fcntl/linux/fallocate.cpp b/libc/src/fcntl/linux/fallocate.cpp
new file mode 100644
index 00000000000000..9237428f017e18
--- /dev/null
+++ b/libc/src/fcntl/linux/fallocate.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// This file contains the declaration of the fallocate, which is the
+/// fcntl fallocate function for linux.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/fcntl/fallocate.h"
+
+#include "src/__support/OSUtil/linux/syscall_wrappers/fallocate.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/libc_errno.h"
+#include "hdr/types/off_t.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+ LLVM_LIBC_FUNCTION(int, fallocate, (int fd, int mode, off_t offset, off_t size)) {
+ auto result = linux_syscalls::fallocate(fd, mode, offset, size);
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return 0;
+ }
+}
diff --git a/libc/test/src/fcntl/CMakeLists.txt b/libc/test/src/fcntl/CMakeLists.txt
index 6a2acd9578697d..1d952c435468ae 100644
--- a/libc/test/src/fcntl/CMakeLists.txt
+++ b/libc/test/src/fcntl/CMakeLists.txt
@@ -99,3 +99,19 @@ add_libc_test(
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)
+
+add_libc_test(
+ fallocate_test
+ SUITE
+ libc_fcntl_unittests
+ SRCS
+ fallocate_test.cpp
+ DEPENDS
+ libc.include.fcntl
+ libc.src.fcntl.fallocate
+ libc.src.fcntl.open
+ libc.src.unistd.close
+ libc.src.unistd.unlink
+ libc.src.sys.stat.fstat
+ libc.src.__support.libc_errno
+)
diff --git a/libc/test/src/fcntl/fallocate_test.cpp b/libc/test/src/fcntl/fallocate_test.cpp
new file mode 100644
index 00000000000000..62b2258ccdcbe9
--- /dev/null
+++ b/libc/test/src/fcntl/fallocate_test.cpp
@@ -0,0 +1,59 @@
+//===-- Unittests for fallocate -------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/fcntl/fallocate.h"
+#include "src/fcntl/open.h"
+#include "src/sys/stat/fstat.h"
+#include "src/unistd/close.h"
+#include "src/unistd/unlink.h"
+#include "src/__support/libc_errno.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(LlvmLibcFallocateTest, BasicAllocate) {
+ constexpr char TEST_FILE[] = "testdata/fallocate_basic.test";
+
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+ ASSERT_GT(fd, 0);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Mode 0: expand file size to offset + len (4096 bytes)
+ ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, 0, 0, 4096), Succeeds(0));
+
+ struct stat st;
+ ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
+ ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(4096));
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+}
+
+TEST(LlvmLibcFallocateTest, KeepSize) {
+ constexpr char TEST_FILE[] = "testdata/fallocate_keep_size.test";
+
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+ ASSERT_GT(fd, 0);
+
+ // Pre-allocate space at offset 8192, length 4096, but keep file size at 0
+ ASSERT_THAT(
+ LIBC_NAMESPACE::fallocate(fd, FALLOC_FL_KEEP_SIZE, 8192, 4096),
+ Succeeds(0));
+
+ struct stat st;
+ ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
+ ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(0));
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+}
diff --git a/libc/utils/docgen/fcntl.yaml b/libc/utils/docgen/fcntl.yaml
index 7a6b656cc0a802..f9a9a0fd37e13e 100644
--- a/libc/utils/docgen/fcntl.yaml
+++ b/libc/utils/docgen/fcntl.yaml
@@ -11,6 +11,8 @@ functions:
in-latest-posix: ''
posix_fallocate:
in-latest-posix: ''
+ fallocate:
+ in-latest-posix: ''
macros:
AT_EACCESS:
>From 7d00dd05a9e3c06894580d727a4dd2d802b530d5 Mon Sep 17 00:00:00 2001
From: yahia ahmed <yahia.a.abdrabou at gmail.com>
Date: Fri, 11 Sep 2026 16:36:12 +0300
Subject: [PATCH 2/5] Fix style issues and address comments
---
.../llvm-libc-macros/linux/fcntl-macros.h | 8 -------
.../linux/syscall_wrappers/CMakeLists.txt | 2 ++
.../OSUtil/linux/syscall_wrappers/fallocate.h | 22 ++++++++++++-------
libc/src/fcntl/fallocate.h | 5 ++---
libc/src/fcntl/linux/fallocate.cpp | 19 ++++++++--------
libc/test/src/fcntl/fallocate_test.cpp | 21 +++++++++---------
libc/utils/docgen/fcntl.yaml | 2 +-
7 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/libc/include/llvm-libc-macros/linux/fcntl-macros.h b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
index dc7be0b9045f99..648c4a9ec00da6 100644
--- a/libc/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -24,14 +24,6 @@
#define O_SYNC 004010000
#define O_TRUNC 000001000
-#define FALLOC_FL_KEEP_SIZE 0x01
-#define FALLOC_FL_PUNCH_HOLE 0x02
-#define FALLOC_FL_NO_HIDE_STALE 0x04
-#define FALLOC_FL_COLLAPSE_RANGE 0x08
-#define FALLOC_FL_ZERO_RANGE 0x10
-#define FALLOC_FL_INSERT_RANGE 0x20
-#define FALLOC_FL_UNSHARE_RANGE 0x40
-
#ifdef __aarch64__
#define O_DIRECT 000200000
#define O_DIRECTORY 000040000
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index c24bec607ba52c..4ec311a93e586b 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -1315,5 +1315,7 @@ add_header_library(
libc.include.sys_syscall
libc.hdr.types.off_t
libc.hdr.errno_macros
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.bit
libc.src.__support.error_or
)
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
index 88cf78cd345d1a..cce4d819aacf4a 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
@@ -17,6 +17,8 @@
#include "hdr/errno_macros.h"
#include "hdr/types/off_t.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h"
#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
#include "src/__support/common.h"
#include "src/__support/error_or.h"
@@ -27,14 +29,18 @@ namespace LIBC_NAMESPACE_DECL {
namespace linux_syscalls {
LIBC_INLINE ErrorOr<int> fallocate(int fd, int mode, off_t offset, off_t size) {
-#ifdef SYS_fallocate
-#if !__SIZEOF__POINTER == 8 // 64 bit machines
- /* TODO: Add support for 32 bits */
- return Error(ENOSYS);
-#else
- return syscall_checked<int>(SYS_fallocate, fd, mode, offset, size);
-#endif
-#endif
+ if constexpr (sizeof(long) == sizeof(uint32_t) &&
+ sizeof(off_t) == sizeof(uint64_t)) {
+ uint64_t offset_bits = cpp::bit_cast<uint64_t>(offset);
+ long offset_low = static_cast<long>(offset_bits & UINT32_MAX);
+ long offset_high = static_cast<long>(offset_bits >> 32);
+ uint64_t len_bits = cpp::bit_cast<uint64_t>(size);
+ long len_low = static_cast<long>(len_bits & UINT32_MAX);
+ long len_high = static_cast<long>(len_bits >> 32);
+ return syscall_checked<int>(SYS_fallocate, fd, mode, offset_low,
+ offset_high, len_low, len_high);
+ } else
+ return syscall_checked<int>(SYS_fallocate, fd, mode, offset, size);
}
} // namespace linux_syscalls
diff --git a/libc/src/fcntl/fallocate.h b/libc/src/fcntl/fallocate.h
index bfc5605fe8251c..7dcdc560c37514 100644
--- a/libc/src/fcntl/fallocate.h
+++ b/libc/src/fcntl/fallocate.h
@@ -14,13 +14,12 @@
#ifndef LLVM_LIBC_SRC_FCNTL_FALLOCATE_H
#define LLVM_LIBC_SRC_FCNTL_FALLOCATE_H
-#include "src/__support/macros/config.h"
#include "hdr/types/off_t.h"
+#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
- int fallocate(int fd, int mode, off_t offset, off_t size);
-
+int fallocate(int fd, int mode, off_t offset, off_t size);
}
#endif
diff --git a/libc/src/fcntl/linux/fallocate.cpp b/libc/src/fcntl/linux/fallocate.cpp
index 9237428f017e18..59361988848eb0 100644
--- a/libc/src/fcntl/linux/fallocate.cpp
+++ b/libc/src/fcntl/linux/fallocate.cpp
@@ -14,19 +14,20 @@
#include "src/fcntl/fallocate.h"
+#include "hdr/types/off_t.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/fallocate.h"
-#include "src/__support/macros/config.h"
#include "src/__support/libc_errno.h"
-#include "hdr/types/off_t.h"
+#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
- LLVM_LIBC_FUNCTION(int, fallocate, (int fd, int mode, off_t offset, off_t size)) {
- auto result = linux_syscalls::fallocate(fd, mode, offset, size);
- if (!result.has_value()) {
- libc_errno = result.error();
- return -1;
- }
- return 0;
+LLVM_LIBC_FUNCTION(int, fallocate,
+ (int fd, int mode, off_t offset, off_t size)) {
+ auto result = linux_syscalls::fallocate(fd, mode, offset, size);
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
}
+ return 0;
}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/fcntl/fallocate_test.cpp b/libc/test/src/fcntl/fallocate_test.cpp
index 62b2258ccdcbe9..64050dcc61d152 100644
--- a/libc/test/src/fcntl/fallocate_test.cpp
+++ b/libc/test/src/fcntl/fallocate_test.cpp
@@ -6,17 +6,18 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/fcntl_macros.h"
+#include "src/__support/CPP/scope.h"
+#include "src/__support/libc_errno.h"
#include "src/fcntl/fallocate.h"
#include "src/fcntl/open.h"
#include "src/sys/stat/fstat.h"
+#include "src/sys/stat/stat.h"
#include "src/unistd/close.h"
#include "src/unistd/unlink.h"
-#include "src/__support/libc_errno.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
-#include "test/UnitTest/ErrnoCheckingTest.h"
-#include <fcntl.h>
-#include <sys/stat.h>
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
@@ -27,6 +28,10 @@ TEST(LlvmLibcFallocateTest, BasicAllocate) {
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
ASSERT_GT(fd, 0);
ASSERT_ERRNO_SUCCESS();
+ LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] {
+ EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+ EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ });
// Mode 0: expand file size to offset + len (4096 bytes)
ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, 0, 0, 4096), Succeeds(0));
@@ -34,9 +39,6 @@ TEST(LlvmLibcFallocateTest, BasicAllocate) {
struct stat st;
ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(4096));
-
- ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
- ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
}
TEST(LlvmLibcFallocateTest, KeepSize) {
@@ -46,9 +48,8 @@ TEST(LlvmLibcFallocateTest, KeepSize) {
ASSERT_GT(fd, 0);
// Pre-allocate space at offset 8192, length 4096, but keep file size at 0
- ASSERT_THAT(
- LIBC_NAMESPACE::fallocate(fd, FALLOC_FL_KEEP_SIZE, 8192, 4096),
- Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, FALLOC_FL_KEEP_SIZE, 8192, 4096),
+ Succeeds(0));
struct stat st;
ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
diff --git a/libc/utils/docgen/fcntl.yaml b/libc/utils/docgen/fcntl.yaml
index f9a9a0fd37e13e..1053f357901d95 100644
--- a/libc/utils/docgen/fcntl.yaml
+++ b/libc/utils/docgen/fcntl.yaml
@@ -12,7 +12,7 @@ functions:
posix_fallocate:
in-latest-posix: ''
fallocate:
- in-latest-posix: ''
+ c-definition: ''
macros:
AT_EACCESS:
>From 09076301343f5dfd15258c5ec8147525d138c554 Mon Sep 17 00:00:00 2001
From: yahia ahmed <yahia.a.abdrabou at gmail.com>
Date: Mon, 14 Sep 2026 17:03:24 +0300
Subject: [PATCH 3/5] address comments
---
libc/config/linux/riscv/entrypoints.txt | 1 +
.../OSUtil/linux/syscall_wrappers/fallocate.h | 3 +-
libc/src/fcntl/fallocate.h | 1 +
libc/src/fcntl/linux/fallocate.cpp | 1 +
libc/test/src/fcntl/CMakeLists.txt | 18 ++-----
libc/test/src/fcntl/linux/CMakeLists.txt | 17 +++++++
.../src/fcntl/{ => linux}/fallocate_test.cpp | 48 ++++++++++++++++---
7 files changed, 66 insertions(+), 23 deletions(-)
create mode 100644 libc/test/src/fcntl/linux/CMakeLists.txt
rename libc/test/src/fcntl/{ => linux}/fallocate_test.cpp (53%)
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index e8180cbb0c70e7..0280725acae489 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -49,6 +49,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# fcntl.h entrypoints
libc.src.fcntl.creat
+ libc.src.fcntl.fallocate
libc.src.fcntl.fcntl
libc.src.fcntl.open
libc.src.fcntl.openat
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
index cce4d819aacf4a..2d80c7256dec06 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
@@ -39,8 +39,9 @@ LIBC_INLINE ErrorOr<int> fallocate(int fd, int mode, off_t offset, off_t size) {
long len_high = static_cast<long>(len_bits >> 32);
return syscall_checked<int>(SYS_fallocate, fd, mode, offset_low,
offset_high, len_low, len_high);
- } else
+ } else {
return syscall_checked<int>(SYS_fallocate, fd, mode, offset, size);
+ }
}
} // namespace linux_syscalls
diff --git a/libc/src/fcntl/fallocate.h b/libc/src/fcntl/fallocate.h
index 7dcdc560c37514..2924637c3a696c 100644
--- a/libc/src/fcntl/fallocate.h
+++ b/libc/src/fcntl/fallocate.h
@@ -20,6 +20,7 @@
namespace LIBC_NAMESPACE_DECL {
int fallocate(int fd, int mode, off_t offset, off_t size);
+
}
#endif
diff --git a/libc/src/fcntl/linux/fallocate.cpp b/libc/src/fcntl/linux/fallocate.cpp
index 59361988848eb0..21e9c276d500cd 100644
--- a/libc/src/fcntl/linux/fallocate.cpp
+++ b/libc/src/fcntl/linux/fallocate.cpp
@@ -30,4 +30,5 @@ LLVM_LIBC_FUNCTION(int, fallocate,
}
return 0;
}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/fcntl/CMakeLists.txt b/libc/test/src/fcntl/CMakeLists.txt
index 1d952c435468ae..085fda5762704a 100644
--- a/libc/test/src/fcntl/CMakeLists.txt
+++ b/libc/test/src/fcntl/CMakeLists.txt
@@ -100,18 +100,6 @@ add_libc_test(
libc.test.UnitTest.ErrnoSetterMatcher
)
-add_libc_test(
- fallocate_test
- SUITE
- libc_fcntl_unittests
- SRCS
- fallocate_test.cpp
- DEPENDS
- libc.include.fcntl
- libc.src.fcntl.fallocate
- libc.src.fcntl.open
- libc.src.unistd.close
- libc.src.unistd.unlink
- libc.src.sys.stat.fstat
- libc.src.__support.libc_errno
-)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/fcntl/linux/CMakeLists.txt b/libc/test/src/fcntl/linux/CMakeLists.txt
new file mode 100644
index 00000000000000..382f8a119d3d17
--- /dev/null
+++ b/libc/test/src/fcntl/linux/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_custom_target(libc_fallocate_unittests)
+
+add_libc_test(
+ fallocate_test
+ SUITE
+ libc_fcntl_unittests
+ SRCS
+ fallocate_test.cpp
+ DEPENDS
+ libc.include.fcntl
+ libc.src.fcntl.fallocate
+ libc.src.fcntl.open
+ libc.src.unistd.close
+ libc.src.unistd.unlink
+ libc.src.sys.stat.fstat
+ libc.src.__support.libc_errno
+)
diff --git a/libc/test/src/fcntl/fallocate_test.cpp b/libc/test/src/fcntl/linux/fallocate_test.cpp
similarity index 53%
rename from libc/test/src/fcntl/fallocate_test.cpp
rename to libc/test/src/fcntl/linux/fallocate_test.cpp
index 64050dcc61d152..4c0053faa9d797 100644
--- a/libc/test/src/fcntl/fallocate_test.cpp
+++ b/libc/test/src/fcntl/linux/fallocate_test.cpp
@@ -1,10 +1,15 @@
-//===-- Unittests for fallocate -------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// 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
+/// This file contains the tests for the fallocate POSIX functions
+///
+//===----------------------------------------------------------------------===//
#include "hdr/fcntl_macros.h"
#include "src/__support/CPP/scope.h"
@@ -19,22 +24,24 @@
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
+#include <linux/falloc.h>
+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcFallocateTest, BasicAllocate) {
- constexpr char TEST_FILE[] = "testdata/fallocate_basic.test";
+ constexpr char TEST_FILE[] = "fallocate_basic.test";
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
- ASSERT_GT(fd, 0);
ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] {
EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
});
// Mode 0: expand file size to offset + len (4096 bytes)
- ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, 0, 0, 4096), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, 0, 1024, 3072), Succeeds(0));
struct stat st;
ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
@@ -42,10 +49,15 @@ TEST(LlvmLibcFallocateTest, BasicAllocate) {
}
TEST(LlvmLibcFallocateTest, KeepSize) {
- constexpr char TEST_FILE[] = "testdata/fallocate_keep_size.test";
+ constexpr char TEST_FILE[] = "fallocate_keep_size.test";
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+ ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
+ LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] {
+ EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+ EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ });
// Pre-allocate space at offset 8192, length 4096, but keep file size at 0
ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, FALLOC_FL_KEEP_SIZE, 8192, 4096),
@@ -54,7 +66,29 @@ TEST(LlvmLibcFallocateTest, KeepSize) {
struct stat st;
ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0);
ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(0));
+}
+
+TEST(LlvmLibcFallocateTest, InvalidFd) {
+ // Passing an invalid file descriptor should fail with EBADF
+ ASSERT_THAT(LIBC_NAMESPACE::fallocate(-1, 0, 0, 4096), Fails(EBADF));
+}
+
+TEST(LlvmLibcFallocateTest, InvalidMode) {
+ constexpr char TEST_FILE[] = "fallocate_invalid_mode.test";
+
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+ LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] {
+ EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+ EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ });
- ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
- ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+ // FALLOC_FL_PUNCH_HOLE without FALLOC_FL_KEEP_SIZE must fail with EINVAL
+ ASSERT_EQ(LIBC_NAMESPACE::fallocate(fd, -1, 0, 4096), -1);
+ // Could be any one of those and potentially more depending on the file system
+ ASSERT_TRUE(libc_errno == EINVAL || libc_errno == ENOTSUP ||
+ libc_errno == EOPNOTSUPP);
+ // for the cleanup to work
+ libc_errno = 0;
}
>From 9143892cce97a74618afef7c9cfc1b3059d65695 Mon Sep 17 00:00:00 2001
From: yahia ahmed <yahia.a.abdrabou at gmail.com>
Date: Wed, 16 Sep 2026 18:35:13 +0300
Subject: [PATCH 4/5] remove extra comment and arrange entrypoints
---
libc/test/src/fcntl/linux/CMakeLists.txt | 2 --
libc/test/src/fcntl/linux/fallocate_test.cpp | 1 -
2 files changed, 3 deletions(-)
diff --git a/libc/test/src/fcntl/linux/CMakeLists.txt b/libc/test/src/fcntl/linux/CMakeLists.txt
index 382f8a119d3d17..a280fdbac652c4 100644
--- a/libc/test/src/fcntl/linux/CMakeLists.txt
+++ b/libc/test/src/fcntl/linux/CMakeLists.txt
@@ -1,5 +1,3 @@
-add_custom_target(libc_fallocate_unittests)
-
add_libc_test(
fallocate_test
SUITE
diff --git a/libc/test/src/fcntl/linux/fallocate_test.cpp b/libc/test/src/fcntl/linux/fallocate_test.cpp
index 4c0053faa9d797..a7cbb44d011d10 100644
--- a/libc/test/src/fcntl/linux/fallocate_test.cpp
+++ b/libc/test/src/fcntl/linux/fallocate_test.cpp
@@ -84,7 +84,6 @@ TEST(LlvmLibcFallocateTest, InvalidMode) {
EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
});
- // FALLOC_FL_PUNCH_HOLE without FALLOC_FL_KEEP_SIZE must fail with EINVAL
ASSERT_EQ(LIBC_NAMESPACE::fallocate(fd, -1, 0, 4096), -1);
// Could be any one of those and potentially more depending on the file system
ASSERT_TRUE(libc_errno == EINVAL || libc_errno == ENOTSUP ||
>From 8dbc0ad8cce641047794369d59f854535626c646 Mon Sep 17 00:00:00 2001
From: yahia ahmed <yahia.a.abdrabou at gmail.com>
Date: Thu, 17 Sep 2026 05:19:36 +0300
Subject: [PATCH 5/5] add fallocate to entrypoints
---
libc/src/fcntl/CMakeLists.txt | 7 +++++++
libc/src/fcntl/linux/CMakeLists.txt | 24 ++++++++++++------------
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/libc/src/fcntl/CMakeLists.txt b/libc/src/fcntl/CMakeLists.txt
index 09afab57b7aa51..99fb047cdc8c3d 100644
--- a/libc/src/fcntl/CMakeLists.txt
+++ b/libc/src/fcntl/CMakeLists.txt
@@ -16,6 +16,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.fcntl
)
+add_entrypoint_object(
+ fallocate
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.fallocate
+)
+
add_entrypoint_object(
open
ALIAS
diff --git a/libc/src/fcntl/linux/CMakeLists.txt b/libc/src/fcntl/linux/CMakeLists.txt
index 9e20d9947acd6b..fa41eeb1b2f1e8 100644
--- a/libc/src/fcntl/linux/CMakeLists.txt
+++ b/libc/src/fcntl/linux/CMakeLists.txt
@@ -11,6 +11,18 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ fallocate
+ SRCS
+ fallocate.cpp
+ HDRS
+ ../fallocate.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.OSUtil.linux.syscall_wrappers.fallocate
+ libc.hdr.types.off_t
+)
+
add_entrypoint_object(
fcntl
SRCS
@@ -74,15 +86,3 @@ add_entrypoint_object(
libc.src.__support.common
libc.src.__support.macros.config
)
-
-add_entrypoint_object(
- fallocate
- SRCS
- fallocate.cpp
- HDRS
- ../fallocate.h
- DEPENDS
- libc.src.errno.errno
- libc.src.__support.OSUtil.linux.syscall_wrappers.fallocate
- libc.hdr.types.off_t
-)
More information about the libc-commits
mailing list