Fixed failing hunks.
[rsync/rsync-patches.git] / early-checksum.diff
CommitLineData
2d2150f6
WD
1This patch changes the way the --checksum option works by having the
2receiving side perform a checksum-read of every file in the file list
d47d38c7 3as the list is received (if the sizes are equal), marking non-matching
2d2150f6
WD
4items with a flag. The idea is that the checksum pass on the sender and
5the receiver can then happen in parallel instead of having the reciever
6to its checksum pass during its normal find-the-different-files pass.
7
d47d38c7
WD
8I have benchmarked this a little, and it appears to slow things down
9for a local copy, so the old algorithm is used for local copies.
2d2150f6 10
0ca6aebe 11--- orig/flist.c 2006-01-21 21:02:30
2d2150f6
WD
12+++ flist.c 2005-09-16 16:41:25
13@@ -36,6 +36,7 @@ extern int am_daemon;
14 extern int am_sender;
15 extern int do_progress;
16 extern int always_checksum;
17+extern int pre_checksum;
18 extern int module_id;
19 extern int ignore_errors;
20 extern int numeric_ids;
0ca6aebe 21@@ -708,6 +709,16 @@ static struct file_struct *receive_file_
2d2150f6
WD
22 sum = empty_sum;
23 }
d57e621e 24 read_buf(f, sum, checksum_len);
2d2150f6
WD
25+ if (pre_checksum) {
26+ char sum2[MD4_SUM_LENGTH];
27+ STRUCT_STAT st;
bd68c3c2 28+ char *fname = f_name(file, NULL);
2d2150f6
WD
29+ if (stat(fname, &st) == 0 && st.st_size == file_length) {
30+ file_checksum(fname, sum2, st.st_size);
d57e621e 31+ if (memcmp(sum, sum2, checksum_len) != 0)
2d2150f6
WD
32+ file->flags |= FLAG_SUM_DIFFERS;
33+ }
34+ }
35 }
36
37 if (!preserve_perms) {
0ca6aebe 38--- orig/generator.c 2006-01-21 21:02:30
f20eb450 39+++ generator.c 2005-12-15 23:16:48
2d2150f6
WD
40@@ -69,6 +69,7 @@ extern int ignore_timeout;
41 extern int protocol_version;
42 extern int fuzzy_basis;
43 extern int always_checksum;
44+extern int pre_checksum;
d57e621e 45 extern int checksum_len;
2d2150f6
WD
46 extern char *partial_dir;
47 extern char *basis_dir[];
0ca6aebe 48@@ -377,7 +378,8 @@ void itemize(struct file_struct *file, i
2d2150f6
WD
49
50
51 /* Perform our quick-check heuristic for determining if a file is unchanged. */
f20eb450
WD
52-int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
53+int unchanged_file(char *fn, int fnamecmp_type, struct file_struct *file,
54+ STRUCT_STAT *st)
2d2150f6
WD
55 {
56 if (st->st_size != file->length)
57 return 0;
0ca6aebe 58@@ -386,6 +388,8 @@ int unchanged_file(char *fn, struct file
2d2150f6
WD
59 of the file time to determine whether to sync */
60 if (always_checksum && S_ISREG(st->st_mode)) {
61 char sum[MD4_SUM_LENGTH];
62+ if (pre_checksum && fnamecmp_type == FNAMECMP_FNAME)
63+ return !(file->flags & FLAG_SUM_DIFFERS);
64 file_checksum(fn, sum, st->st_size);
d57e621e
WD
65 return memcmp(sum, file->u.sum, checksum_len) == 0;
66 }
0ca6aebe 67@@ -623,7 +627,7 @@ static int try_dests_reg(struct file_str
f20eb450
WD
68 match_level = 1;
69 /* FALL THROUGH */
70 case 1:
71- if (!unchanged_file(cmpbuf, file, stp))
72+ if (!unchanged_file(cmpbuf, 0, file, stp))
73 continue;
74 best_match = j;
75 match_level = 2;
0ca6aebe 76@@ -1145,7 +1149,7 @@ static void recv_generator(char *fname,
2d2150f6
WD
77 ;
78 else if (fnamecmp_type == FNAMECMP_FUZZY)
79 ;
80- else if (unchanged_file(fnamecmp, file, &st)) {
81+ else if (unchanged_file(fnamecmp, fnamecmp_type, file, &st)) {
d57e621e
WD
82 if (partialptr) {
83 do_unlink(partialptr);
84 handle_partial_dir(partialptr, PDIR_DELETE);
bd68c3c2 85--- orig/hlink.c 2006-01-14 20:27:09
f20eb450
WD
86+++ hlink.c 2005-12-15 23:17:31
87@@ -210,7 +210,7 @@ int hard_link_check(struct file_struct *
88 itemizing = code = 0;
89 break;
90 }
91- if (!unchanged_file(cmpbuf, file, &st3))
92+ if (!unchanged_file(cmpbuf, 0, file, &st3))
93 continue;
94 statret = 1;
95 st = &st3;
bd68c3c2 96--- orig/main.c 2006-01-15 14:46:15
d47d38c7 97+++ main.c 2005-11-07 05:00:49
2d2150f6
WD
98@@ -45,6 +45,7 @@ extern int copy_links;
99 extern int keep_dirlinks;
100 extern int preserve_hard_links;
101 extern int protocol_version;
102+extern int always_checksum;
103 extern int recurse;
104 extern int relative_paths;
105 extern int rsync_port;
106@@ -60,8 +61,10 @@ extern char *filesfrom_host;
107 extern char *rsync_path;
108 extern char *shell_cmd;
109 extern char *batch_name;
110+extern char curr_dir[MAXPATHLEN];
111
112 int local_server = 0;
113+int pre_checksum = 0;
114 struct file_list *the_file_list;
115
116 /* There's probably never more than at most 2 outstanding child processes,
bd68c3c2 117@@ -710,6 +713,7 @@ static void do_server_recv(int f_in, int
2d2150f6
WD
118 struct file_list *flist;
119 char *local_name = NULL;
120 char *dir = NULL;
121+ char olddir[sizeof curr_dir];
122 int save_verbose = verbose;
123
124 if (filesfrom_fd >= 0) {
bd68c3c2 125@@ -753,6 +757,10 @@ static void do_server_recv(int f_in, int
2d2150f6
WD
126 filesfrom_fd = -1;
127 }
128
129+ strlcpy(olddir, curr_dir, sizeof olddir);
d47d38c7 130+ if (always_checksum && !local_server && argc > 0)
2d2150f6
WD
131+ pre_checksum = push_dir(argv[0]);
132+
133 flist = recv_file_list(f_in);
134 verbose = save_verbose;
135 if (!flist) {
bd68c3c2 136@@ -761,6 +769,9 @@ static void do_server_recv(int f_in, int
2d2150f6
WD
137 }
138 the_file_list = flist;
139
140+ if (pre_checksum)
141+ pop_dir(olddir);
142+
143 if (argc > 0)
144 local_name = get_local_name(flist,argv[0]);
145
bd68c3c2 146@@ -809,6 +820,7 @@ int client_run(int f_in, int f_out, pid_
2d2150f6
WD
147 {
148 struct file_list *flist = NULL;
149 int exit_code = 0, exit_code2 = 0;
150+ char olddir[sizeof curr_dir];
151 char *local_name = NULL;
152
153 cleanup_child_pid = pid;
bd68c3c2 154@@ -880,11 +892,18 @@ int client_run(int f_in, int f_out, pid_
2d2150f6
WD
155 filesfrom_fd = -1;
156 }
157
158+ strlcpy(olddir, curr_dir, sizeof olddir);
d47d38c7 159+ if (always_checksum && !local_server)
2d2150f6
WD
160+ pre_checksum = push_dir(argv[0]);
161+
162 if (write_batch && !am_server)
163 start_write_batch(f_in);
164 flist = recv_file_list(f_in);
165 the_file_list = flist;
166
167+ if (pre_checksum)
168+ pop_dir(olddir);
169+
170 if (flist && flist->count > 0) {
171 local_name = get_local_name(flist, argv[0]);
172
0ca6aebe
WD
173--- orig/rsync.h 2006-01-21 21:02:30
174+++ rsync.h 2006-01-21 21:08:49
2d2150f6
WD
175@@ -64,6 +64,7 @@
176 #define FLAG_DEL_HERE (1<<3) /* receiver/generator */
2d2150f6 177 #define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
0ca6aebe
WD
178 #define FLAG_NO_FUZZY (1<<5) /* generator */
179+#define FLAG_SUM_DIFFERS (1<<6) /* receiver/generator */
2d2150f6
WD
180
181 /* update this if you make incompatible changes */
182 #define PROTOCOL_VERSION 29