From 75cca7a0983c857852d7660d5b3d4a02f0859722 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 19 Jul 2016 20:19:56 +0000 Subject: [PATCH] Use posix_fallocate instead of ftruncate. This makes sure that space is actually available. With this change running lld on a full file system causes it to exit with failed to open foo: No space left on device instead of crashing with a sigbus. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276017 91177308-0d34-0410-b5e6-96231b3b80d8 --- cmake/config-ix.cmake | 1 + include/llvm/Config/config.h.cmake | 2 ++ lib/Support/Unix/Path.inc | 9 +++++++++ 3 files changed, 12 insertions(+) diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index b363a357c58..25cf23ad4bf 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -162,6 +162,7 @@ check_symbol_exists(setrlimit sys/resource.h HAVE_SETRLIMIT) check_symbol_exists(isatty unistd.h HAVE_ISATTY) check_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS) check_symbol_exists(futimes sys/time.h HAVE_FUTIMES) +check_symbol_exists(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE) if( HAVE_SETJMP_H ) check_symbol_exists(longjmp setjmp.h HAVE_LONGJMP) check_symbol_exists(setjmp setjmp.h HAVE_SETJMP) diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 45b30d9171d..efc3cacd59a 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -585,4 +585,6 @@ /* Define to 1 if you have the `_chsize_s' function. */ #cmakedefine HAVE__CHSIZE_S ${HAVE__CHSIZE_S} +#cmakedefine HAVE_POSIX_FALLOCATE ${HAVE_POSIX_FALLOCATE} + #endif diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index 84aafcb70d7..ea439c6b79d 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -329,8 +329,17 @@ std::error_code rename(const Twine &from, const Twine &to) { } std::error_code resize_file(int FD, uint64_t Size) { +#if defined(HAVE_POSIX_FALLOCATE) + // If we have posix_fallocate use it. Unlike ftruncate it always allocates + // space, so we get an error if the disk is full. + if (int Err = ::posix_fallocate(FD, 0, Size)) + return std::error_code(Err, std::generic_category()); +#else + // Use ftruncate as a fallback. It may or may not allocate space. At least on + // OS X with HFS+ it does. if (::ftruncate(FD, Size) == -1) return std::error_code(errno, std::generic_category()); +#endif return std::error_code(); } -- 2.11.0