Fix alignment issue on 64-bit. Solution from Steve Ortiz.
[rsync/rsync-patches.git] / detect-renamed-lax.diff
CommitLineData
9ff55583
WD
1This patch adds the options --detect-renamed-lax and --detect-moved.
2These modify the --detect-renamed algorithm to adopt a matching file
3without verifying that the content is as expected. The former blindly
4accepts a file that matches in size and modified time. The latter
5requires that the filename also match (ignoring any renamed files).
6
7This patch is EXPERIMENTAL, though it did work correctly in my light
8testing.
9
10To use this patch, run these commands for a successful build:
11
12 patch -p1 <patches/detect-renamed.diff
13 patch -p1 <patches/detect-renamed-lax.diff
14 ./configure (optional if already run)
15 make
16
17FIXME: If a run with --detect-renamed-lax stages a different-basename
18destination file and then gets interrupted, a subsequent run that
19switches to --detect-moved blindly accepts the staged file.
20
21-- Matt McCutchen <hashproduct+rsync@gmail.com>
22
c1ff70aa 23based-on: patch/master/detect-renamed
cc3e685d
WD
24diff --git a/generator.c b/generator.c
25--- a/generator.c
26+++ b/generator.c
c1ff70aa 27@@ -468,7 +468,9 @@ static int fattr_find(struct file_struct *f, char *fname)
9ff55583
WD
28 continue;
29 }
30 }
31- ok_match = mid;
32+ /* --detect-moved doesn't allow non-basename matches */
33+ if (detect_renamed != 3)
34+ ok_match = mid;
35 diff = u_strcmp(fmid->basename, f->basename);
36 if (diff == 0) {
37 good_match = mid;
c1ff70aa 38@@ -1783,6 +1785,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
9ff55583
WD
39 fnamecmp = partialptr;
40 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
41 statret = 0;
42+ if (detect_renamed > 1 && unchanged_file(fnamecmp, file, &sx.st)) {
43+ /* Adopt the partial file. */
44+ finish_transfer(fname, fnamecmp, NULL, NULL, file, 1, 1);
45+ handle_partial_dir(partialptr, PDIR_DELETE);
46+ if (itemizing)
47+ itemize(fnamecmp, file, ndx, -1, &sx,
48+ ITEM_LOCAL_CHANGE, fnamecmp_type, NULL);
49+#ifdef SUPPORT_HARD_LINKS
50+ if (preserve_hard_links && F_IS_HLINKED(file))
51+ finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
52+#endif
53+ if (remove_source_files == 1)
54+ goto return_with_success;
55+ goto cleanup;
56+ }
57 }
58
59 if (!do_xfers)
cc3e685d
WD
60diff --git a/options.c b/options.c
61--- a/options.c
62+++ b/options.c
72e5645e 63@@ -745,6 +745,8 @@ void usage(enum logcode F)
9ff55583
WD
64 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
65 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
66 rprintf(F," --detect-renamed try to find renamed files to speed up the transfer\n");
67+ rprintf(F," --detect-renamed-lax ... and assume identical to source files (risky!)\n");
68+ rprintf(F," --detect-moved ... only if basenames match (less risky)\n");
69 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
70 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
71 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
72e5645e 72@@ -940,7 +942,9 @@ static struct poptOption long_options[] = {
9ff55583
WD
73 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
74 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
75 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
76- {"detect-renamed", 0, POPT_ARG_NONE, &detect_renamed, 0, 0, 0 },
77+ {"detect-renamed", 0, POPT_ARG_VAL, &detect_renamed, 1, 0, 0 },
78+ {"detect-renamed-lax",0, POPT_ARG_VAL, &detect_renamed, 2, 0, 0 },
79+ {"detect-moved", 0, POPT_ARG_VAL, &detect_renamed, 3, 0, 0 },
c0c7984e
WD
80 {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 },
81 {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
82 {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
c1ff70aa 83@@ -2532,8 +2536,14 @@ void server_options(char **args, int *argc_p)
7c4c2959
WD
84 args[ac++] = "--super";
85 if (size_only)
86 args[ac++] = "--size-only";
87- if (detect_renamed)
88- args[ac++] = "--detect-renamed";
89+ if (detect_renamed) {
90+ if (detect_renamed == 1)
91+ args[ac++] = "--detect-renamed";
92+ else if (detect_renamed == 2)
93+ args[ac++] = "--detect-renamed-lax";
94+ else
95+ args[ac++] = "--detect-moved";
96+ }
fc557362
WD
97 if (do_stats)
98 args[ac++] = "--stats";
7c4c2959 99 } else {
cc3e685d
WD
100diff --git a/rsync.yo b/rsync.yo
101--- a/rsync.yo
102+++ b/rsync.yo
fc557362 103@@ -398,6 +398,8 @@ to the detailed description below for a complete description. verb(
9ff55583
WD
104 -T, --temp-dir=DIR create temporary files in directory DIR
105 -y, --fuzzy find similar file for basis if no dest file
106 --detect-renamed try to find renamed files to speed the xfer
107+ --detect-renamed-lax ...& assume identical to src files (risky!)
108+ --detect-moved ... only if basenames match (less risky)
109 --compare-dest=DIR also compare received files relative to DIR
110 --copy-dest=DIR ... and include copies of unchanged files
111 --link-dest=DIR hardlink to files in DIR when unchanged
c1ff70aa 112@@ -1656,6 +1658,17 @@ the bf(--partial-dir) option, that directory will be used instead. These
9ff55583
WD
113 potential alternate-basis files will be removed as the transfer progresses.
114 This option conflicts with bf(--inplace) and bf(--append).
115
116+dit(bf(--detect-renamed-lax)) This version of bf(--detect-renamed)
117+makes rsync hard-link em(dest/D) to em(dest/S) without verifying that
118+em(src/S) and em(dest/S) have the same data. This poses a significant risk
119+of corrupting the destination by representing a new source file by an
120+unrelated destination file that coincidentally passes the quick check with the
121+source file. Use this option only if you accept the risk and disk I/O is a
122+bottleneck.
123+
124+dit(bf(--detect-moved)) A less risky variant of bf(--detect-renamed-lax) that
125+only uses a destination file that has the same basename as the new source file.
126+
127 dit(bf(--compare-dest=DIR)) This option instructs rsync to use em(DIR) on
128 the destination machine as an additional hierarchy to compare destination
129 files against doing transfers (if the files are missing in the destination