Commit | Line | Data |
---|---|---|
24d21c7b WD |
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 | |
4 | work. | |
e1d5c853 WD |
5 | |
6 | -- Matt McCutchen <hashproduct@gmail.com> | |
7 | ||
8 | --- old/match.c | |
9 | +++ new/match.c | |
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; | |
15 | ||
16 | int updating_basis_file; | |
17 | ||
18 | @@ -315,21 +316,23 @@ void match_sums(int f, struct sum_struct | |
19 | sum_init(checksum_seed); | |
20 | ||
21 | if (append_mode > 0) { | |
22 | - OFF_T j = 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), | |
27 | - CHUNK_SIZE); | |
28 | - last_match = j; | |
29 | - } | |
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) { | |
37 | + OFF_T j = 0; | |
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), | |
42 | + CHUNK_SIZE); | |
43 | + last_match = j; | |
44 | + } | |
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); | |
50 | + } | |
51 | } | |
52 | + last_match = s->flength; | |
53 | s->count = 0; | |
54 | } | |
55 | ||
56 | --- old/options.c | |
57 | +++ new/options.c | |
58 | @@ -41,6 +41,7 @@ int make_backups = 0; | |
59 | int whole_file = -1; | |
60 | ||
61 | int append_mode = 0; | |
62 | +int trust_append = 0; | |
63 | int keep_dirlinks = 0; | |
64 | int copy_dirlinks = 0; | |
65 | int copy_links = 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 | |
83 | } | |
84 | } | |
85 | ||
86 | - if (append_mode) | |
87 | + if (append_mode) { | |
88 | args[ac++] = "--append"; | |
89 | - else if (inplace) | |
90 | + if (trust_append) | |
91 | + args[ac++] = "--trust-append"; | |
92 | + } else if (inplace) | |
93 | args[ac++] = "--inplace"; | |
94 | ||
95 | if (files_from && (!am_sender || filesfrom_host)) { | |
96 | --- old/receiver.c | |
97 | +++ new/receiver.c | |
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; | |
108 | if (sum.remainder) | |
109 | sum.flength -= sum.blength - sum.remainder; | |
110 | - for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) { | |
111 | - if (do_progress) | |
112 | - show_progress(offset, total_size); | |
113 | - sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE), | |
114 | - CHUNK_SIZE); | |
115 | - offset = j; | |
116 | - } | |
117 | - if (offset < sum.flength) { | |
118 | - int32 len = (int32)(sum.flength - offset); | |
119 | - if (do_progress) | |
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) { | |
125 | + if (do_progress) | |
126 | + show_progress(offset, total_size); | |
127 | + sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE), | |
128 | + CHUNK_SIZE); | |
129 | + offset = j; | |
130 | + } | |
131 | + if (offset < sum.flength) { | |
132 | + int32 len = (int32)(sum.flength - offset); | |
133 | + if (do_progress) | |
134 | + show_progress(offset, total_size); | |
135 | + sum_update(map_ptr(mapbuf, offset, len), len); | |
136 | + } | |
137 | } | |
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); | |
142 | --- old/rsync.yo | |
143 | +++ new/rsync.yo | |
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 | |
154 | data is required). | |
155 | ||
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 | |
160 | +file. | |
161 | + | |
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 |