Fix checkout of large files to network shares on Windows XP
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Thu, 20 May 2010 18:57:53 +0000 (20:57 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 May 2010 23:12:13 +0000 (16:12 -0700)
Bigger writes to network drives on Windows XP fail.  Cap them at 31MB to
allow them to succeed.  Callers need to be prepared for write() calls
that do less work than requested anyway.

On local drives, write() calls are translated to WriteFile() calls with
a cap of 64KB on Windows XP and 256KB on Vista.  Thus a cap of 31MB won't
affect the number of WriteFile() calls which do the actual work.  There's
still room for some other version of Windows to use a chunk size of 1MB
without increasing the number of system calls.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
compat/mingw.c
compat/mingw.h
t/t5705-clone-2gb.sh

index f90a114b021d32c2ee1976bf51a82e87a81ea1cb..9a8e3365827d303c6513475726113a3952fe0040 100644 (file)
@@ -140,6 +140,23 @@ int mingw_open (const char *filename, int oflags, ...)
        return fd;
 }
 
+#undef write
+ssize_t mingw_write(int fd, const void *buf, size_t count)
+{
+       /*
+        * While write() calls to a file on a local disk are translated
+        * into WriteFile() calls with a maximum size of 64KB on Windows
+        * XP and 256KB on Vista, no such cap is placed on writes to
+        * files over the network on Windows XP.  Unfortunately, there
+        * seems to be a limit of 32MB-28KB on X64 and 64MB-32KB on x86;
+        * bigger writes fail on Windows XP.
+        * So we cap to a nice 31MB here to avoid write failures over
+        * the net without changing the number of WriteFile() calls in
+        * the local case.
+        */
+       return write(fd, buf, min(count, 31 * 1024 * 1024));
+}
+
 #undef fopen
 FILE *mingw_fopen (const char *filename, const char *otype)
 {
index 7c2ab64cb4eb7532c2495383ab0e7eefb329bcf9..0e3e74304138ab2f279c74599ee934ade72ae37d 100644 (file)
@@ -170,6 +170,9 @@ int link(const char *oldpath, const char *newpath);
 int mingw_open (const char *filename, int oflags, ...);
 #define open mingw_open
 
+ssize_t mingw_write(int fd, const void *buf, size_t count);
+#define write mingw_write
+
 FILE *mingw_fopen (const char *filename, const char *otype);
 #define fopen mingw_fopen
 
index adfaae8c5b453835eeeac3e3794950971e6dd6d8..8afbdd4de2146be763f7454af66a15986490fe60 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success 'setup' '
 
        git config pack.compression 0 &&
        git config pack.depth 0 &&
-       blobsize=$((20*1024*1024)) &&
+       blobsize=$((100*1024*1024)) &&
        blobcount=$((2*1024*1024*1024/$blobsize+1)) &&
        i=1 &&
        (while test $i -le $blobcount
@@ -36,9 +36,15 @@ test_expect_success 'setup' '
 
 '
 
-test_expect_success 'clone' '
+test_expect_success 'clone - bare' '
 
-       git clone --bare --no-hardlinks . clone
+       git clone --bare --no-hardlinks . clone-bare
+
+'
+
+test_expect_success 'clone - with worktree, file:// protocol' '
+
+       git clone file://. clone-wt
 
 '