Bootstrapped and regtested on x86_64-pc-linux-gnu, and also on x86_64-unknown-freebsd13.3 by Gerald ([1], see also the discussion on the PR); OK for trunk?
[1]: https://gcc.gnu.org/pipermail/gcc-testresults/2024-December/833487.html -- >8 -- 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> --- 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 b9cf16433b5..9ad587ebd6a 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -1905,13 +1905,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) @@ -1919,7 +1929,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) @@ -1929,7 +1939,6 @@ elf_out::create_mapping (unsigned ext, bool extending) ext = 0; } } -#undef posix_fallocate hdr.buffer = (char *)mapping; extent = ext; } -- 2.47.0