https://gcc.gnu.org/g:1c3dee768a9f7aa384150e4e4a584d6aa1db5e97
commit r14-11125-g1c3dee768a9f7aa384150e4e4a584d6aa1db5e97 Author: Nathaniel Shead <nathanielosh...@gmail.com> Date: Sat Dec 21 23:42:28 2024 +1100 c++/modules: Fallback to ftruncate if posix_fallocate fails [PR115008] Depending on the libc and filesystem, in cases where posix_fallocate cannot do an efficient preallocation it may return EINVAL. In such a case we should fall back to ftruncate instead. Apparently, depending on the system the use of posix_fallocate can have a noticeable speedup over ftruncate in general (depending on the system) so it probably isn't worth it to use ftruncate in all cases. PR c++/100358 PR c++/115008 gcc/cp/ChangeLog: * module.cc (elf_out::create_mapping): Fallback to ftruncate if posix_fallocate fails. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> (cherry picked from commit 84aa7065deec49bab9fb0b085cd0a0dcc42cc479) Diff: --- gcc/cp/module.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index fb10537d3e34..60638aabee28 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -1883,13 +1883,23 @@ elf_in::begin (location_t loc) void elf_out::create_mapping (unsigned ext, bool extending) { -#ifndef HAVE_POSIX_FALLOCATE -#define posix_fallocate(fd,off,len) ftruncate (fd, off + len) + /* A wrapper around posix_fallocate, falling back to ftruncate + if the underlying filesystem does not support the operation. */ + auto allocate = [](int fd, off_t offset, off_t length) + { +#ifdef HAVE_POSIX_FALLOCATE + int result = posix_fallocate (fd, offset, length); + if (result != EINVAL) + return result == 0; + /* Not supported by the underlying filesystem, fallback to ftruncate. */ #endif + return ftruncate (fd, offset + length) == 0; + }; + void *mapping = MAP_FAILED; if (extending && ext < 1024 * 1024) { - if (!posix_fallocate (fd, offset, ext * 2)) + if (allocate (fd, offset, ext * 2)) mapping = mmap (NULL, ext * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); if (mapping != MAP_FAILED) @@ -1897,7 +1907,7 @@ elf_out::create_mapping (unsigned ext, bool extending) } if (mapping == MAP_FAILED) { - if (!extending || !posix_fallocate (fd, offset, ext)) + if (!extending || allocate (fd, offset, ext)) mapping = mmap (NULL, ext, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); if (mapping == MAP_FAILED) @@ -1907,7 +1917,6 @@ elf_out::create_mapping (unsigned ext, bool extending) ext = 0; } } -#undef posix_fallocate hdr.buffer = (char *)mapping; extent = ext; }