From 8bd77e7098d9863f258070fb2274e324a446adbd Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 23 Jun 2008 08:02:46 -0700 Subject: [PATCH] Fixed the sending of large files with older rsync versions by handling the old block-size limit for protocols < 29. --- NEWS | 5 ++++- generator.c | 5 +++-- io.c | 3 ++- rsync.h | 3 +++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 556cec76..e6d13325 100644 --- 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. diff --git a/generator.c b/generator.c index 1fcdb4c2..9b371e85 100644 --- a/generator.c +++ b/generator.c @@ -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 60062f90..6a91ffd5 100644 --- 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 a600152d..77f9b3a7 100644 --- a/rsync.h +++ b/rsync.h @@ -129,6 +129,9 @@ #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) -- 2.34.1