summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/posix.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/posix.c b/src/posix.c
index 242fda8c6..b5dfac56d 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -159,6 +159,20 @@ int p_fallocate(int fd, off_t offset, off_t len)
{
#ifdef __APPLE__
fstore_t prealloc;
+ struct stat st;
+ size_t newsize;
+ int error;
+
+ if ((error = p_fstat(fd, &st)) < 0)
+ return error;
+
+ if (git__add_sizet_overflow(&newsize, offset, len)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (newsize < (unsigned long long)st.st_size)
+ return 0;
memset(&prealloc, 0, sizeof(prealloc));
prealloc.fst_flags = F_ALLOCATEALL;
@@ -166,7 +180,14 @@ int p_fallocate(int fd, off_t offset, off_t len)
prealloc.fst_offset = offset;
prealloc.fst_length = len;
- return fcntl(fd, F_PREALLOCATE, &prealloc);
+ /*
+ * fcntl will often error when the file already exists; ignore
+ * this error since ftruncate will also resize the file (although
+ * likely slower).
+ */
+ fcntl(fd, F_PREALLOCATE, &prealloc);
+
+ return ftruncate(fd, (offset + len));
#else
return posix_fallocate(fd, offset, len);
#endif