From 6e83d8007b844f1d0d68ad235015a154da8050c4 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 22 May 2010 22:09:51 +0300 Subject: [PATCH] Fix bug #6237. w32.c (sys_write): Break writes into chunks smaller than 32MB. --- src/ChangeLog | 5 +++++ src/w32.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 489505f3cf3..540a85a6b1d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2010-05-22 Eli Zaretskii + + * w32.c (sys_write): Break writes into chunks smaller than 32MB. + (Bug#6237) + 2010-05-22 Chong Yidong * image.c (Fimage_flush): Rename from image-refresh. diff --git a/src/w32.c b/src/w32.c index 0f2d8b54e6b..0560ce4a6b8 100644 --- a/src/w32.c +++ b/src/w32.c @@ -5700,7 +5700,34 @@ sys_write (int fd, const void * buffer, unsigned int count) } else #endif - nchars = _write (fd, buffer, count); + { + /* Some networked filesystems don't like too large writes, so + break them into smaller chunks. See the Comments section of + the MSDN documentation of WriteFile for details behind the + choice of the value of CHUNK below. See also the thread + http://thread.gmane.org/gmane.comp.version-control.git/145294 + in the git mailing list. */ + const unsigned char *p = buffer; + const unsigned chunk = 30 * 1024 * 1024; + + nchars = 0; + while (count > 0) + { + unsigned this_chunk = count < chunk ? count : chunk; + int n = _write (fd, p, this_chunk); + + nchars += n; + if (n < 0) + { + nchars = n; + break; + } + else if (n < this_chunk) + break; + count -= n; + p += n; + } + } return nchars; } -- 2.39.2