1 This patch adds a --trust-append option that, in combination with --append,
2 makes rsync exclude the portion of a transferred file that was already on the
3 receiver from the post-transfer checksum. In my limited testing, it seems to
6 -- Matt McCutchen <hashproduct@gmail.com>
10 @@ -25,6 +25,7 @@ extern int verbose;
11 extern int do_progress;
12 extern int checksum_seed;
13 extern int append_mode;
14 +extern int trust_append;
16 int updating_basis_file;
18 @@ -315,21 +316,23 @@ void match_sums(int f, struct sum_struct
19 sum_init(checksum_seed);
21 if (append_mode > 0) {
23 - for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
24 - if (buf && do_progress)
25 - show_progress(last_match, buf->file_size);
26 - sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
30 - if (last_match < s->flength) {
31 - int32 n = (int32)(s->flength - last_match);
32 - if (buf && do_progress)
33 - show_progress(last_match, buf->file_size);
34 - sum_update(map_ptr(buf, last_match, n), n);
35 - last_match = s->flength;
36 + if (!trust_append) {
38 + for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
39 + if (buf && do_progress)
40 + show_progress(last_match, buf->file_size);
41 + sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
45 + if (last_match < s->flength) {
46 + int32 n = (int32)(s->flength - last_match);
47 + if (buf && do_progress)
48 + show_progress(last_match, buf->file_size);
49 + sum_update(map_ptr(buf, last_match, n), n);
52 + last_match = s->flength;
58 @@ -41,6 +41,7 @@ int make_backups = 0;
62 +int trust_append = 0;
63 int keep_dirlinks = 0;
64 int copy_dirlinks = 0;
66 @@ -313,6 +314,7 @@ void usage(enum logcode F)
67 rprintf(F," -u, --update skip files that are newer on the receiver\n");
68 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
69 rprintf(F," --append append data onto shorter files\n");
70 + rprintf(F," --trust-append ... and don't checksum portion already on dest\n");
71 rprintf(F," -d, --dirs transfer directories without recursing\n");
72 rprintf(F," -l, --links copy symlinks as symlinks\n");
73 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
74 @@ -517,6 +519,7 @@ static struct poptOption long_options[]
75 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
76 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
77 {"append", 0, POPT_ARG_VAL, &append_mode, 1, 0, 0 },
78 + {"trust-append", 0, POPT_ARG_NONE, &trust_append, 0, 0, 0 },
79 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
80 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
81 {"delete-before", 0, POPT_ARG_NONE, &delete_before, 0, 0, 0 },
82 @@ -1898,9 +1901,11 @@ void server_options(char **args,int *arg
88 args[ac++] = "--append";
91 + args[ac++] = "--trust-append";
93 args[ac++] = "--inplace";
95 if (files_from && (!am_sender || filesfrom_host)) {
98 @@ -44,6 +44,7 @@ extern int make_backups;
99 extern int cleanup_got_literal;
100 extern int remove_source_files;
101 extern int append_mode;
102 +extern int trust_append;
103 extern int sparse_files;
104 extern int keep_partial;
105 extern int checksum_seed;
106 @@ -157,20 +158,22 @@ static int receive_data(int f_in, char *
107 sum.flength = (OFF_T)sum.count * sum.blength;
109 sum.flength -= sum.blength - sum.remainder;
110 - for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
112 - show_progress(offset, total_size);
113 - sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
117 - if (offset < sum.flength) {
118 - int32 len = (int32)(sum.flength - offset);
120 - show_progress(offset, total_size);
121 - sum_update(map_ptr(mapbuf, offset, len), len);
122 - offset = sum.flength;
123 + if (!trust_append) {
124 + for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
126 + show_progress(offset, total_size);
127 + sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
131 + if (offset < sum.flength) {
132 + int32 len = (int32)(sum.flength - offset);
134 + show_progress(offset, total_size);
135 + sum_update(map_ptr(mapbuf, offset, len), len);
138 + offset = sum.flength;
139 if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
140 rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f",
141 full_fname(fname), (double)j, (double)offset);
144 @@ -318,6 +318,7 @@ to the detailed description below for a
145 -u, --update skip files that are newer on the receiver
146 --inplace update destination files in-place
147 --append append data onto shorter files
148 + --trust-append ... and don't checksum portion already on dest
149 -d, --dirs transfer directories without recursing
150 -l, --links copy symlinks as symlinks
151 -L, --copy-links transform symlink into referent file/dir
152 @@ -709,6 +710,12 @@ Implies bf(--inplace), but does not conf
153 bf(--sparse) option will be auto-disabled if a resend of the already-existing
156 +dit(bf(--trust-append)) In combination with bf(--append), this option excludes
157 +the portion of a transferred file that was already on the receiver from the
158 +post-transfer checksum. You can use this option to improve performance if you
159 +are certain that the receiver's file is identical to the start of the sender's
162 dit(bf(-d, --dirs)) Tell the sending side to include any directories that
163 are encountered. Unlike bf(--recursive), a directory's contents are not copied
164 unless the directory name specified is "." or ends with a trailing slash