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 556cec7..e6d1332 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 1fcdb4c..9b371e8 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 60062f9..6a91ffd 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 a600152..77f9b3a 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)