summaryrefslogtreecommitdiff
path: root/src/AbstractDiskWriter.cc
diff options
context:
space:
mode:
authorNils Maier <maierman@web.de>2014-05-08 01:04:02 +0200
committerNils Maier <maierman@web.de>2014-05-08 16:40:09 +0200
commit5c07f0109e6f84691a6ce25bd3cdd0e4c08c9648 (patch)
treee690b963cbdd5696d445908ba8cf0eb72c5b42fc /src/AbstractDiskWriter.cc
parent1dd7409c4e83082e15d0c7d5966435e231c000dd (diff)
Fix F_PREALLOC based allocation on some OSX versions
Diffstat (limited to 'src/AbstractDiskWriter.cc')
-rw-r--r--src/AbstractDiskWriter.cc16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index 7cd7765b..25a2d620 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -476,19 +476,27 @@ void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse)
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};
+ while (toalloc > 0) {
+ fstore_t fstore = {
+ F_ALLOCATECONTIG | F_ALLOCATEALL,
+ F_PEOFPOSMODE,
+ 0,
+ // Allocate in 1GB chunks or else some OSX versions may choke.
+ std::min(toalloc, (int64_t)1<<30),
+ 0
+ };
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()),
+ fmt("fcntl(F_PREALLOCATE) of %" PRId64 " failed. cause: %s",
+ fstore.fst_length, util::safeStrerror(err).c_str()),
error_code::FILE_IO_ERROR);
}
}
+ toalloc -= fstore.fst_bytesalloc;
}
// This forces the allocation on disk.
ftruncate(fd_, offset + length);