Fixed the sending of large files with older rsync versions by
authorWayne Davison <wayned@samba.org>
Mon, 23 Jun 2008 15:02:46 +0000 (08:02 -0700)
committerWayne Davison <wayned@samba.org>
Mon, 23 Jun 2008 16:17:55 +0000 (09:17 -0700)
handling the old block-size limit for protocols < 29.

NEWS
generator.c
io.c
rsync.h

diff --git a/NEWS b/NEWS
index 556cec769d08fe1fc2a31e1fb38474ef5430de70..e6d1332586612bc3c85e4fe9c038691fa417f149 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -39,11 +39,14 @@ Changes since 3.0.2:
     - Fixed a problem with how a destination path with a trailing slash or
       a trailing dot-dir was compared against the daemon excludes.
 
+    - Fixed the sending of large (size > 16GB) files when talking to an older
+      rsync (protocols < 30):  we now use a compatible block size limit.
+
     - If a file's length is so huge that we overflow a checksum buffer count
       (i.e. several hundred TB), warn the user and avoid sending an invalid
       checksum struct over the wire.
 
-    - If an source arg is excluded, --relative no longer adds the excluded
+    - If a source arg is excluded, --relative no longer adds the excluded
       arg's implied dirs to the transfer.  This fix also made the exclude
       check happen in the better place in the sending code.
 
index 1fcdb4c29e6edfe7a2982e52b28eabef7b82cb03..9b371e85f381d933b17d5fa50911c93249af3883 100644 (file)
@@ -763,11 +763,12 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
        else if (len <= BLOCK_SIZE * BLOCK_SIZE)
                blength = BLOCK_SIZE;
        else {
+               int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
                int32 c;
                int cnt;
                for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
-               if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
-                       blength = MAX_BLOCK_SIZE;
+               if (c < 0 || c >= max_blength)
+                       blength = max_blength;
                else {
                    blength = 0;
                    do {
diff --git a/io.c b/io.c
index 60062f9083d66f24e80a390e3dd26f6b0e57056b..6a91ffd570598cb9cd55e2b7600cd7cd47fb7727 100644 (file)
--- a/io.c
+++ b/io.c
@@ -1354,6 +1354,7 @@ int read_vstring(int f, char *buf, int bufsize)
  * called by both the sender and the receiver. */
 void read_sum_head(int f, struct sum_struct *sum)
 {
+       int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
        sum->count = read_int(f);
        if (sum->count < 0) {
                rprintf(FERROR, "Invalid checksum count %ld [%s]\n",
@@ -1361,7 +1362,7 @@ void read_sum_head(int f, struct sum_struct *sum)
                exit_cleanup(RERR_PROTOCOL);
        }
        sum->blength = read_int(f);
-       if (sum->blength < 0 || sum->blength > MAX_BLOCK_SIZE) {
+       if (sum->blength < 0 || sum->blength > max_blength) {
                rprintf(FERROR, "Invalid block length %ld [%s]\n",
                        (long)sum->blength, who_am_i());
                exit_cleanup(RERR_PROTOCOL);
diff --git a/rsync.h b/rsync.h
index a600152d3a57ae399b660590848813fea6602b52..77f9b3a7d4ba4d081f6a3040883b2d3518134671 100644 (file)
--- a/rsync.h
+++ b/rsync.h
 #define IO_BUFFER_SIZE (4092)
 #define MAX_BLOCK_SIZE ((int32)1 << 17)
 
+/* For compatibility with older rsyncs */
+#define OLD_MAX_BLOCK_SIZE ((int32)1 << 29)
+
 #define IOERR_GENERAL  (1<<0) /* For backward compatibility, this must == 1 */
 #define IOERR_VANISHED (1<<1)
 #define IOERR_DEL_LIMIT (1<<2)