[PATCH] D38295: Do not use posix_fallocate because it's slow.

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 27 20:36:03 PDT 2017


ruiu updated this revision to Diff 116921.
ruiu added a comment.
Herald added a subscriber: mgorny.

- Use fallocate(2) if available.


https://reviews.llvm.org/D38295

Files:
  llvm/cmake/config-ix.cmake
  llvm/include/llvm/Config/config.h.cmake
  llvm/lib/Support/Unix/Path.inc


Index: llvm/lib/Support/Unix/Path.inc
===================================================================
--- llvm/lib/Support/Unix/Path.inc
+++ llvm/lib/Support/Unix/Path.inc
@@ -422,19 +422,23 @@
 }
 
 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)) {
-    if (Err != EOPNOTSUPP)
-      return std::error_code(Err, std::generic_category());
-  }
+#ifdef HAVE_FALLOCATE
+  // We prefer fallocate over ftruncate because only the former system
+  // call can detect a "disk full" error. ftruncate creates a sparse
+  // file, so it succeeds even if sufficient disk space is not available.
+  //
+  // fallocate() is a Linux-only system call. POSIX defines posix_fallocate,
+  // but the function is very slow in some implementations (including glibc's)
+  // because it attempts to actually write zero bytes to each disk block.
+  // Thus, we do not want to use posix_fallocate.
+  if (fallocate(FD, 0, 0, Size) == 0)
+    return std::error_code();
+  if (errno == ENOSPC)
+    return std::error_code(errno, std::generic_category());
 #endif
-  // 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());
-
   return std::error_code();
 }
 
Index: llvm/include/llvm/Config/config.h.cmake
===================================================================
--- llvm/include/llvm/Config/config.h.cmake
+++ llvm/include/llvm/Config/config.h.cmake
@@ -59,6 +59,9 @@
 /* Define to 1 if you have the <errno.h> header file. */
 #cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
 
+/* Define to 1 if you have the `fallocate' function. */
+#cmakedefine HAVE_FALLOCATE ${HAVE_FALLOCATE}
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H}
 
Index: llvm/cmake/config-ix.cmake
===================================================================
--- llvm/cmake/config-ix.cmake
+++ llvm/cmake/config-ix.cmake
@@ -197,6 +197,11 @@
 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)
+
+set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
+check_symbol_exists(fallocate fcntl.h HAVE_FALLOCATE)
+set(CMAKE_REQUIRED_DEFINITIONS "")
+
 # AddressSanitizer conflicts with lib/Support/Unix/Signals.inc
 # Avoid sigaltstack on Apple platforms, where backtrace() cannot handle it
 # (rdar://7089625) and _Unwind_Backtrace is unusable because it cannot unwind


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38295.116921.patch
Type: text/x-patch
Size: 2765 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170928/01f11eaf/attachment.bin>


More information about the llvm-commits mailing list