Selaa lähdekoodia

Implement falloc equivalent in OSX

Nils Maier 11 vuotta sitten
vanhempi
commit
7600886d3d
2 muutettua tiedostoa jossa 20 lisäystä ja 1 poistoa
  1. 2 1
      configure.ac
  2. 18 0
      src/AbstractDiskWriter.cc

+ 2 - 1
configure.ac

@@ -799,13 +799,14 @@ AC_CHECK_FUNCS([posix_fallocate],[have_posix_fallocate=yes])
 ARIA2_CHECK_FALLOCATE
 if test "x$have_posix_fallocate" = "xyes" ||
    test "x$have_fallocate" = "xyes" ||
+   test "x$have_osx" = "xyes" ||
    test "x$win_build" = "xyes"; then
   AC_DEFINE([HAVE_SOME_FALLOCATE], [1],
             [Define to 1 if *_fallocate is available.])
 fi
 AM_CONDITIONAL([HAVE_SOME_FALLOCATE],
   [test "x$have_posix_fallocate" = "xyes" || test "x$have_fallocate" = "xyes" \
-  || test "x$win_build" = "xyes"])
+  || test "x$have_osx" = "xyes" || test "x$win_build" = "xyes"])
 
 
 AC_CHECK_FUNCS([asctime_r],

+ 18 - 0
src/AbstractDiskWriter.cc

@@ -483,6 +483,24 @@ void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse)
 #ifdef  HAVE_SOME_FALLOCATE
 # ifdef __MINGW32__
   truncate(offset+length);
+# elif defined(__APPLE__) && defined(__MACH__)
+  auto toalloc = offset + length - size();
+  if (toalloc > 0) {
+    fstore_t fstore = {F_ALLOCATECONTIG | F_ALLOCATEALL, F_PEOFPOSMODE, 0, toalloc};
+    if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
+      // Retry non-contig.
+      fstore.fst_flags = F_ALLOCATEALL;
+      if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
+        int err = errno;
+        throw DL_ABORT_EX3(err,
+                          fmt("fcntl(F_PREALLOCATE failed. cause: %s",
+                              util::safeStrerror(err).c_str()),
+                          error_code::FILE_IO_ERROR);
+      }
+    }
+  }
+  // This forces the allocation on disk.
+  ftruncate(fd_, offset + length);
 # elif HAVE_FALLOCATE
   // For linux, we use fallocate to detect file system supports
   // fallocate or not.