From 6c5f1057c2b2230d02cedbbe9a3c6f1b84e501f3 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 21 Feb 2019 02:19:51 +0000 Subject: [PATCH] copyfile-146.250.1.tar.gz --- copyfile.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/copyfile.c b/copyfile.c index 885bd4d..99e6d42 100644 --- a/copyfile.c +++ b/copyfile.c @@ -2424,14 +2424,27 @@ static int copyfile_data(copyfile_state_t s) /* If supported, do preallocation for Xsan / HFS / apfs volumes */ #ifdef F_PREALLOCATE { - fstore_t fst; - - fst.fst_flags = 0; - fst.fst_posmode = F_PEOFPOSMODE; - fst.fst_offset = 0; - fst.fst_length = s->sb.st_size; - /* Ignore errors; this is merely advisory. */ - (void)fcntl(s->dst_fd, F_PREALLOCATE, &fst); + off_t dst_bytes_allocated = 0; + struct stat dst_sb; + + if (fstat(s->dst_fd, &dst_sb) == 0) { + // The destination may already have + // preallocated space we can use. + dst_bytes_allocated = dst_sb.st_blocks * S_BLKSIZE; + } + + if (dst_bytes_allocated < s->sb.st_size) { + fstore_t fst; + + fst.fst_flags = 0; + fst.fst_posmode = F_PEOFPOSMODE; + fst.fst_offset = 0; + fst.fst_length = s->sb.st_size - dst_bytes_allocated; + + copyfile_debug(3, "preallocating %lld bytes on destination", fst.fst_length); + /* Ignore errors; this is merely advisory. */ + (void)fcntl(s->dst_fd, F_PREALLOCATE, &fst); + } } #endif -- 2.47.2