Fixed two failing hunks.
[rsync/rsync-patches.git] / delay-renames.diff
CommitLineData
372bd02a
WD
1Delay the renaming of all the temp files until the end of the transfer.
2
d37913ac
WD
3--- orig/options.c 2005-01-25 03:26:51
4+++ options.c 2005-01-25 03:28:41
b76d92e6 5@@ -101,6 +101,7 @@ int modify_window = 0;
372bd02a
WD
6 int blocking_io = -1;
7 int checksum_seed = 0;
8 int inplace = 0;
9+int delay_renames = 0;
10 long block_size = 0; /* "long" because popt can't set an int32. */
11
12
d37913ac
WD
13@@ -288,6 +289,7 @@ void usage(enum logcode F)
14 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
15 rprintf(F," --partial keep partially transferred files\n");
16 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
372bd02a 17+ rprintf(F," --delay-renames renames transferred files into place at end\n");
d37913ac
WD
18 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
19 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
20 rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
21@@ -407,6 +409,7 @@ static struct poptOption long_options[]
372bd02a
WD
22 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
23 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
24 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
25+ {"delay-renames", 0, POPT_ARG_NONE, &delay_renames, 0, 0, 0 },
26 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
27 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
28 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
d37913ac 29@@ -995,11 +998,15 @@ int parse_arguments(int *argc, const cha
372bd02a
WD
30 bwlimit_writemax = 512;
31 }
32
33+ if (delay_renames && !partial_dir)
34+ partial_dir = ".~tmp~";
35+
36 if (inplace) {
37 #if HAVE_FTRUNCATE
0f626034
WD
38- if (partial_dir) {
39+ if (partial_dir || delay_renames) {
372bd02a
WD
40 snprintf(err_buf, sizeof err_buf,
41- "--inplace cannot be used with --partial-dir\n");
42+ "--inplace cannot be used with --%s\n",
43+ delay_renames ? "delay-renames" : "partial-dir");
44 return 0;
45 }
46 keep_partial = 0;
d37913ac 47@@ -1236,6 +1243,8 @@ void server_options(char **args,int *arg
372bd02a
WD
48 if (partial_dir && am_sender) {
49 args[ac++] = "--partial-dir";
50 args[ac++] = partial_dir;
51+ if (delay_renames)
52+ args[ac++] = "--delay-renames";
53 } else if (keep_partial)
54 args[ac++] = "--partial";
55
b76d92e6 56--- orig/receiver.c 2005-01-24 01:43:10
0f626034 57+++ receiver.c 2005-01-10 10:16:54
b76d92e6 58@@ -48,6 +48,7 @@ extern int orig_umask;
372bd02a
WD
59 extern int keep_partial;
60 extern int checksum_seed;
61 extern int inplace;
62+extern int delay_renames;
63
64 extern struct exclude_list_struct server_exclude_list;
65
b76d92e6 66@@ -272,6 +273,7 @@ int recv_files(int f_in, struct file_lis
372bd02a
WD
67 char fnametmp[MAXPATHLEN];
68 char *fnamecmp, *partialptr;
69 char fnamecmpbuf[MAXPATHLEN];
70+ uchar *delayed_bits = NULL;
71 struct file_struct *file;
72 struct stats initial_stats;
73 int save_make_backups = make_backups;
b76d92e6 74@@ -285,6 +287,12 @@ int recv_files(int f_in, struct file_lis
372bd02a
WD
75 flist->hlink_pool = NULL;
76 }
77
78+ if (delay_renames) {
79+ if (!(delayed_bits = new_array(char, (flist->count + 7) / 8)))
80+ out_of_memory("recv_files");
81+ memset(delayed_bits, 0, (flist->count + 7) / 8);
82+ }
83+
84 while (1) {
85 cleanup_disable();
86
b76d92e6 87@@ -499,7 +507,7 @@ int recv_files(int f_in, struct file_lis
372bd02a
WD
88 exit_cleanup(RERR_FILEIO);
89 }
90
91- if (recv_ok || inplace) {
92+ if ((recv_ok && !delay_renames) || inplace) {
93 finish_transfer(fname, fnametmp, file, recv_ok, 1);
94 if (partialptr != fname && fnamecmp == partialptr) {
95 do_unlink(partialptr);
b76d92e6 96@@ -509,6 +517,8 @@ int recv_files(int f_in, struct file_lis
372bd02a
WD
97 && handle_partial_dir(partialptr, PDIR_CREATE)) {
98 finish_transfer(partialptr, fnametmp, file, recv_ok,
99 !partial_dir);
100+ if (delay_renames && recv_ok)
101+ delayed_bits[i/8] |= 1 << (i % 8);
102 } else {
103 partialptr = NULL;
104 do_unlink(fnametmp);
b76d92e6 105@@ -548,6 +558,33 @@ int recv_files(int f_in, struct file_lis
372bd02a
WD
106 }
107 make_backups = save_make_backups;
108
109+ if (delay_renames) {
110+ for (i = 0; i < flist->count; i++) {
111+ struct file_struct *file = flist->files[i];
112+ if (!file->basename
113+ || !(delayed_bits[i/8] & (1 << (i % 8))))
114+ continue;
115+ fname = local_name ? local_name : f_name(file);
116+ partialptr = partial_dir_fname(fname);
117+ if (partialptr) {
118+ if (make_backups && !make_backup(fname))
119+ continue;
120+ if (verbose > 2) {
121+ rprintf(FINFO, "renaming %s to %s\n",
122+ partialptr, fname);
123+ }
124+ if (do_rename(partialptr, fname) < 0) {
125+ rsyserr(FERROR, errno,
126+ "rename failed for %s (from %s)",
127+ fname, partialptr);
128+ } else {
129+ handle_partial_dir(partialptr,
130+ PDIR_DELETE);
131+ }
132+ }
133+ }
134+ }
135+
136 if (delete_after && recurse && !local_name && flist->count > 0)
137 delete_files(flist);
138
d37913ac
WD
139--- orig/rsync.yo 2005-01-25 03:26:51
140+++ rsync.yo 2005-01-25 03:28:30
141@@ -353,6 +353,7 @@ verb(
142 --max-size=SIZE don't transfer any file larger than SIZE
143 --partial keep partially transferred files
144 --partial-dir=DIR put a partially transferred file into DIR
372bd02a 145+ --delay-renames renames transferred files into place at end
d37913ac
WD
146 --numeric-ids don't map uid/gid values by user/group name
147 --timeout=TIME set I/O timeout in seconds
148 -I, --ignore-times turn off mod time & file size quick check
149@@ -549,9 +550,9 @@ or appended data, and also on systems th
372bd02a
WD
150 bound.
151
152 The option implies --partial (since an interrupted transfer does not delete
0f626034
WD
153-the file), but conflicts with --partial-dir. Prior to rsync 2.6.4
154---inplace was also incompatible with --compare-dest, --copy-dest, and
155---link-dest.
156+the file), but conflicts with --partial-dir and --delay-renames.
157+Prior to rsync 2.6.4 --inplace was also incompatible with --compare-dest,
158+--copy-dest, and --link-dest.
372bd02a
WD
159
160 WARNING: The file's data will be in an inconsistent state during the
161 transfer (and possibly afterward if the transfer gets interrupted), so you
d37913ac 162@@ -1036,6 +1037,17 @@ environment and then just use the -P opt
372bd02a
WD
163 does not look for this environment value is when --inplace was also
164 specified (since --inplace conflicts with --partial-dir).
165
166+dit(bf(--delay-renames)) This option puts the temporary file from each
167+updated file into the file's partial-dir (see above) until the end of the
168+transfer, at which time all the files are renamed into place in rapid
169+succession. This attempts to make the updating of the files a little more
170+atomic. If you don't specify the --partial-dir option, this option will
171+cause it to default to ".~tmp~" (RSYNC_PARTIAL_DIR is not consulted for
172+this value). Conflicts with --inplace.
173+
174+See also the "atomic-rsync" perl script in the "support" subdir for an
175+update algorithm that is even more atomic (it uses --link-dest).
176+
177 dit(bf(--progress)) This option tells rsync to print information
178 showing the progress of the transfer. This gives a bored user
179 something to watch.