X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/d8aeda1e5000b7caa1e6faadf0a78275ae2bdf01..1618c9e6d179fc46285cf556c5bb090ed0e9e503:/io.c diff --git a/io.c b/io.c index ba71098d..475ac40f 100644 --- a/io.c +++ b/io.c @@ -41,7 +41,6 @@ extern int bwlimit; extern size_t bwlimit_writemax; -extern int verbose; extern int io_timeout; extern int allowed_lull; extern int am_server; @@ -105,6 +104,8 @@ static char io_filesfrom_lastchar; static int io_filesfrom_buflen; static size_t contiguous_write_len = 0; static int select_timeout = SELECT_TIMEOUT; +static int active_filecnt = 0; +static OFF_T active_bytecnt = 0; static void read_loop(int fd, char *buf, size_t len); @@ -279,6 +280,8 @@ static void read_msg_fd(void) exit_cleanup(RERR_STREAMIO); } read_loop(fd, buf, 4); + if (remove_sent_files) + decrement_active_files(IVAL(buf,0)); flist_ndx_push(&redo_list, IVAL(buf,0)); break; case MSG_DELETED: @@ -295,11 +298,20 @@ static void read_msg_fd(void) exit_cleanup(RERR_STREAMIO); } read_loop(fd, buf, len); - if (remove_sent_files) + if (remove_sent_files) { + decrement_active_files(IVAL(buf,0)); io_multiplex_write(MSG_SUCCESS, buf, len); + } if (preserve_hard_links) flist_ndx_push(&hlink_list, IVAL(buf,0)); break; + case MSG_SOCKERR: + if (!am_generator) { + rprintf(FERROR, "invalid message %d:%d\n", tag, len); + exit_cleanup(RERR_STREAMIO); + } + close_multiplexing_out(); + /* FALL THROUGH */ case MSG_INFO: case MSG_ERROR: case MSG_LOG: @@ -320,6 +332,28 @@ static void read_msg_fd(void) msg_fd_in = fd; } +/* This is used by the generator to limit how many file transfers can + * be active at once when --remove-sent-files is specified. Without + * this, sender-side deletions were mostly happening at the end. */ +void increment_active_files(int ndx, int itemizing, enum logcode code) +{ + /* TODO: tune these limits? */ + while (active_filecnt >= (active_bytecnt >= 128*1024 ? 10 : 50)) { + if (hlink_list.head) + check_for_finished_hlinks(itemizing, code); + read_msg_fd(); + } + + active_filecnt++; + active_bytecnt += the_file_list->files[ndx]->length; +} + +void decrement_active_files(int ndx) +{ + active_filecnt--; + active_bytecnt -= the_file_list->files[ndx]->length; +} + /* Try to push messages off the list onto the wire. If we leave with more * to do, return 0. On error, return -1. If everything flushed, return 1. * This is only active in the receiver. */ @@ -580,9 +614,11 @@ static int read_timeout(int fd, char *buf, size_t len) continue; /* Don't write errors on a dead socket. */ - if (fd == sock_f_in) + if (fd == sock_f_in) { close_multiplexing_out(); - rsyserr(FERROR, errno, "read error"); + rsyserr(FSOCKERR, errno, "read error"); + } else + rsyserr(FERROR, errno, "read error"); exit_cleanup(RERR_STREAMIO); } @@ -765,12 +801,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) if (msg_bytes >= sizeof line) goto overflow; read_loop(fd, line, msg_bytes); - line[msg_bytes] = '\0'; /* A directory name was sent with the trailing null */ if (msg_bytes > 0 && !line[msg_bytes-1]) log_delete(line, S_IFDIR); - else + else { + line[msg_bytes] = '\0'; log_delete(line, S_IFREG); + } break; case MSG_SUCCESS: if (msg_bytes != 4) { @@ -911,6 +948,11 @@ int read_vstring(int f, char *buf, int bufsize) void read_sum_head(int f, struct sum_struct *sum) { sum->count = read_int(f); + if (sum->count < 0) { + rprintf(FERROR, "Invalid checksum count %ld [%s]\n", + (long)sum->count, who_am_i()); + exit_cleanup(RERR_PROTOCOL); + } sum->blength = read_int(f); if (sum->blength < 0 || sum->blength > MAX_BLOCK_SIZE) { rprintf(FERROR, "Invalid block length %ld [%s]\n", @@ -973,7 +1015,7 @@ static void sleep_for_bwlimit(int bytes_written) #define ONE_SEC 1000000L /* # of microseconds in a second */ - if (!bwlimit) + if (!bwlimit_writemax) return; total_written += bytes_written; @@ -1053,7 +1095,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) continue; n = len - total; - if (bwlimit && n > bwlimit_writemax) + if (bwlimit_writemax && n > bwlimit_writemax) n = bwlimit_writemax; cnt = write(fd, buf + total, n); @@ -1102,7 +1144,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) **/ static void mplex_write(enum msgcode code, char *buf, size_t len) { - char buffer[BIGPATHBUFLEN]; + char buffer[1024]; size_t n = len; SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len); @@ -1115,9 +1157,10 @@ static void mplex_write(enum msgcode code, char *buf, size_t len) contiguous_write_len = len + 4; if (n > sizeof buffer - 4) - n = sizeof buffer - 4; + n = 0; + else + memcpy(buffer + 4, buf, n); - memcpy(&buffer[4], buf, n); writefd_unbuffered(sock_f_out, buffer, n+4); len -= n;