Updated to apply cleanly.
[rsync/rsync-patches.git] / inplace.diff
CommitLineData
a2d23604
WD
1Patch from Mark Curtis to implement the --inplace option.
2
7b675ff5 3--- match.c 21 May 2004 08:27:04 -0000 1.62
8cec1ead 4+++ match.c 30 Jun 2004 00:09:37 -0000
7b675ff5 5@@ -23,6 +23,7 @@ extern int verbose;
a2d23604
WD
6 extern int am_server;
7 extern int do_progress;
7b675ff5 8 extern int checksum_seed;
a2d23604
WD
9+extern int inplace;
10
11 typedef unsigned short tag;
12
7b675ff5 13@@ -200,6 +201,10 @@ static void hash_search(int f,struct sum
a2d23604 14 if (l != s->sums[i].len)
a2d23604
WD
15 continue;
16
7b675ff5
WD
17+ /* if inplace, make sure the offset is greater than where we are */
18+ if (inplace && offset > s->sums[i].offset)
19+ continue;
20+
a2d23604 21 if (verbose > 3)
7b675ff5
WD
22 rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
23 (double)offset,(double)j,(double)i,sum);
8cec1ead
WD
24--- options.c 20 Jun 2004 19:47:05 -0000 1.157
25+++ options.c 30 Jun 2004 00:09:38 -0000
125d7fca 26@@ -94,6 +94,7 @@ int ignore_errors = 0;
a2d23604
WD
27 int modify_window = 0;
28 int blocking_io = -1;
29 int checksum_seed = 0;
30+int inplace = 0;
31 unsigned int block_size = 0;
32
33
125d7fca 34@@ -234,6 +235,7 @@ void usage(enum logcode F)
a2d23604
WD
35 rprintf(F," --backup-dir make backups into this directory\n");
36 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
37 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
38+ rprintf(F," --inplace update the destination file inplace *SEE MAN PAGE*\n");
125d7fca 39 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
a2d23604
WD
40 rprintf(F," -l, --links copy symlinks as symlinks\n");
41 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
125d7fca
WD
42@@ -341,6 +343,7 @@ static struct poptOption long_options[]
43 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
44 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
45 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
a2d23604 46+ {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
125d7fca
WD
47 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
48 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
49 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
7628f156 50@@ -739,6 +742,9 @@ int parse_arguments(int *argc, const cha
78114162
WD
51 bwlimit_writemax = 512;
52 }
a2d23604
WD
53
54+ if (inplace && keep_partial)
55+ keep_partial = 0;
56+
57 if (files_from) {
58 char *colon;
59 if (*argc != 2 && !(am_server && am_sender && *argc == 1)) {
7628f156 60@@ -963,6 +969,9 @@ void server_options(char **args,int *arg
a2d23604
WD
61 if (opt_ignore_existing && am_sender)
62 args[ac++] = "--ignore-existing";
7b675ff5 63
a2d23604
WD
64+ if (inplace)
65+ args[ac++] = "--inplace";
7b675ff5 66+
a2d23604
WD
67 if (tmpdir) {
68 args[ac++] = "--temp-dir";
7b675ff5 69 args[ac++] = tmpdir;
8cec1ead
WD
70--- receiver.c 29 Jun 2004 15:12:01 -0000 1.83
71+++ receiver.c 30 Jun 2004 00:09:38 -0000
7628f156 72@@ -48,6 +48,7 @@ extern int ignore_errors;
a2d23604 73 extern int orig_umask;
7f2baf27 74 extern int keep_partial;
7b675ff5 75 extern int checksum_seed;
a2d23604
WD
76+extern int inplace;
77
78 static void delete_one(char *fn, int is_dir)
79 {
7628f156 80@@ -257,16 +258,28 @@ static int receive_data(int f_in,struct
a2d23604
WD
81 sum_update(map,len);
82 }
83
84- if (fd != -1 && write_file(fd,map,len) != (int) len) {
fe6407b5
WD
85- rsyserr(FERROR, errno, "write failed on %s",
86- full_fname(fname));
a2d23604
WD
87- exit_cleanup(RERR_FILEIO);
88+ if (!inplace || offset != offset2) {
89+ if (fd != -1 && write_file(fd,map,len) != (int) len) {
fe6407b5
WD
90+ rsyserr(FERROR, errno, "write failed on %s",
91+ full_fname(fname));
a2d23604
WD
92+ exit_cleanup(RERR_FILEIO);
93+ }
94+ } else {
95+ flush_write_file(fd);
96+ if (do_lseek(fd,(OFF_T)len,SEEK_CUR) != offset+len) {
97+ rprintf(FERROR, "lseek failed on %s: %s, %lli, %lli, %i\n",
98+ full_fname(fname), strerror(errno), do_lseek(fd,0,SEEK_CUR), (offset+len), i);
99+ exit_cleanup(RERR_FILEIO);
100+ }
101 }
102 offset += len;
103 }
104
105 flush_write_file(fd);
106
107+ if (inplace)
108+ ftruncate(fd, offset);
109+
110 if (do_progress)
111 end_progress(total_size);
112
8cec1ead 113@@ -420,37 +433,50 @@ int recv_files(int f_in,struct file_list
a2d23604
WD
114 } else
115 mapbuf = NULL;
116
117- if (!get_tmpname(fnametmp,fname)) {
118- if (mapbuf) unmap_file(mapbuf);
119- if (fd1 != -1) close(fd1);
120- continue;
121- }
122+ /* We now check to see if we are writing file "inplace" */
123+ if (inplace) {
124+ fd2 = do_open(fnamecmp, O_WRONLY|O_CREAT, 0);
125+ if (fd2 == -1) {
fe6407b5
WD
126+ rsyserr(FERROR, errno, "open %s failed",
127+ full_fname(fnametmp));
a2d23604
WD
128+ receive_data(f_in,mapbuf,-1,NULL,file->length);
129+ if (mapbuf) unmap_file(mapbuf);
130+ if (fd1 != -1) close(fd1);
131+ continue;
132+ }
133+ } else {
134+ if (!get_tmpname(fnametmp,fname)) {
135+ if (mapbuf) unmap_file(mapbuf);
136+ if (fd1 != -1) close(fd1);
137+ continue;
138+ }
139
140- strlcpy(template, fnametmp, sizeof template);
141+ strlcpy(template, fnametmp, sizeof template);
142
143- /* we initially set the perms without the
144- * setuid/setgid bits to ensure that there is no race
145- * condition. They are then correctly updated after
146- * the lchown. Thanks to snabb@epipe.fi for pointing
147- * this out. We also set it initially without group
148- * access because of a similar race condition. */
149- fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
150-
151- /* in most cases parent directories will already exist
152- * because their information should have been previously
153- * transferred, but that may not be the case with -R */
154- if (fd2 == -1 && relative_paths && errno == ENOENT &&
155- create_directory_path(fnametmp, orig_umask) == 0) {
156- strlcpy(fnametmp, template, sizeof fnametmp);
157+ /* we initially set the perms without the
158+ * setuid/setgid bits to ensure that there is no race
159+ * condition. They are then correctly updated after
160+ * the lchown. Thanks to snabb@epipe.fi for pointing
161+ * this out. We also set it initially without group
162+ * access because of a similar race condition. */
163 fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
164- }
165- if (fd2 == -1) {
fe6407b5
WD
166- rsyserr(FERROR, errno, "mkstemp %s failed",
167- full_fname(fnametmp));
a2d23604
WD
168- receive_data(f_in,mapbuf,-1,NULL,file->length);
169- if (mapbuf) unmap_file(mapbuf);
170- if (fd1 != -1) close(fd1);
171- continue;
172+
173+ /* in most cases parent directories will already exist
174+ * because their information should have been previously
175+ * transferred, but that may not be the case with -R */
176+ if (fd2 == -1 && relative_paths && errno == ENOENT
177+ && create_directory_path(fnametmp, orig_umask) == 0) {
178+ strlcpy(fnametmp, template, sizeof fnametmp);
179+ fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
180+ }
181+ if (fd2 == -1) {
fe6407b5
WD
182+ rsyserr(FERROR, errno, "mkstemp %s failed",
183+ full_fname(fnametmp));
a2d23604
WD
184+ receive_data(f_in,mapbuf,-1,NULL,file->length);
185+ if (mapbuf) unmap_file(mapbuf);
186+ if (fd1 != -1) close(fd1);
187+ continue;
188+ }
189 }
190
191 cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2);
7628f156 192--- rsync.c 11 Jun 2004 07:40:45 -0000 1.141
8cec1ead 193+++ rsync.c 30 Jun 2004 00:09:38 -0000
7b675ff5
WD
194@@ -34,6 +34,7 @@ extern int force_delete;
195 extern int recurse;
a2d23604 196 extern int make_backups;
7b675ff5 197 extern char *backup_dir;
a2d23604
WD
198+extern int inplace;
199
200
201 /*
7b675ff5 202@@ -239,6 +240,11 @@ void finish_transfer(char *fname, char *
a2d23604
WD
203 if (make_backups && !make_backup(fname))
204 return;
7b675ff5 205
a2d23604
WD
206+ if (inplace) {
207+ set_perms(fname,file,NULL,0);
208+ return;
209+ }
7b675ff5 210+
a2d23604
WD
211 /* move tmp file over real file */
212 ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
7b675ff5 213 if (ret < 0) {
125d7fca 214--- rsync.yo 5 Jun 2004 16:16:30 -0000 1.171
8cec1ead 215+++ rsync.yo 30 Jun 2004 00:09:39 -0000
a2d23604
WD
216@@ -289,6 +289,7 @@ verb(
217 --backup-dir make backups into this directory
218 --suffix=SUFFIX backup suffix (default ~ w/o --backup-dir)
219 -u, --update update only (don't overwrite newer files)
220+ --inplace update the destination file inplace
125d7fca 221 -K, --keep-dirlinks treat symlinked dir on receiver as dir
a2d23604
WD
222 -l, --links copy symlinks as symlinks
223 -L, --copy-links copy the referent of all symlinks
125d7fca
WD
224@@ -484,6 +485,17 @@ dit(bf(-K, --keep-dirlinks)) On the rece
225 pointing to a directory, it will be treated as matching a directory
226 from the sender.
7b675ff5 227
a2d23604
WD
228+dit(bf(--inplace)) This causes rsync not to create a new copy of the file
229+and then move it into place. Instead rsync will overwrite the existing
230+file, meaning that the rsync algorithm can't extract the full ammount of
231+network reduction it might otherwise.
232+
233+This option is useful for transfer of large files with block based changes
234+and also on systems that are disk bound not network bound.
235+
236+WARNING: If the transfer is interrupted, you will have an inconsistent file
237+and the transfer should be run again.
7b675ff5 238+
a2d23604
WD
239 dit(bf(-l, --links)) When symlinks are encountered, recreate the
240 symlink on the destination.
7b675ff5 241