Patch from Mark Curtis to implement the --inplace option.
Improved by Wayne Davison.

Run these commands after applying the patch:

    autoconf
    autoheader
    ./configure
    make

Optional:

    make rsync.1

--- orig/configure.in	2004-04-30 18:04:07
+++ configure.in	2004-07-03 20:19:54
@@ -442,7 +442,7 @@ dnl AC_FUNC_MEMCMP
 AC_FUNC_UTIME_NULL
 AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo \
-    fchmod fstat strchr readlink link utime utimes strftime mtrace \
+    fchmod fstat strchr readlink link utime utimes strftime mtrace ftruncate \
     memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk \
     strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid)
 
--- orig/match.c	2004-07-15 02:21:10
+++ match.c	2004-07-16 19:39:08
@@ -23,6 +23,7 @@ extern int verbose;
 extern int am_server;
 extern int do_progress;
 extern int checksum_seed;
+extern int inplace;
 
 typedef unsigned short tag;
 
@@ -200,6 +201,12 @@ static void hash_search(int f,struct sum
 			if (l != s->sums[i].len)
 				continue;
 
+			/* inplace: ensure chunk's offset is either >= our
+			 * offset or that the data didn't move. */
+			if (inplace && s->sums[i].offset < offset
+			    && !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
+				continue;
+
 			if (verbose > 3)
 				rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
 					(double)offset,(double)j,(double)i,sum);
@@ -215,15 +222,41 @@ static void hash_search(int f,struct sum
 				continue;
 			}
 
+			/* If inplace is enabled, the best possible match is
+			 * one with an identical offset, so we prefer that over
+			 * the following want_i optimization. */
+			if (inplace) {
+				do {
+					size_t i2 = targets[j].i;
+					if (s->sums[i2].offset != offset)
+						continue;
+					if (i2 != i) {
+						if (sum != s->sums[i2].sum1)
+							break;
+						if (memcmp(sum2, s->sums[i2].sum2,
+							   s->s2length) != 0)
+							break;
+						i = i2;
+					}
+					/* This chunk was at the same offset on
+					 * both the sender and the receiver. */
+					s->sums[i].flags |= SUMFLG_SAME_OFFSET;
+					goto set_want_i;
+				} while (++j < s->count && targets[j].t == t);
+			}
+
 			/* we've found a match, but now check to see
 			 * if want_i can hint at a better match. */
 			if (i != want_i && want_i < s->count
+			    && (!inplace || s->sums[want_i].offset >= offset
+			     || s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
 			    && sum == s->sums[want_i].sum1
 			    && memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) {
 				/* we've found an adjacent match - the RLL coder
 				 * will be happy */
 				i = want_i;
 			}
+		    set_want_i:
 			want_i = i + 1;
 
 			matched(f,s,buf,offset,i);
--- orig/options.c	2004-07-16 19:35:29
+++ options.c	2004-07-03 20:19:54
@@ -94,6 +94,7 @@ int ignore_errors = 0;
 int modify_window = 0;
 int blocking_io = -1;
 int checksum_seed = 0;
+int inplace = 0;
 unsigned int block_size = 0;
 
 
@@ -148,6 +149,7 @@ char *bind_address;
 static void print_rsync_version(enum logcode f)
 {
 	char const *got_socketpair = "no ";
+	char const *have_inplace = "no ";
 	char const *hardlinks = "no ";
 	char const *links = "no ";
 	char const *ipv6 = "no ";
@@ -157,6 +159,10 @@ static void print_rsync_version(enum log
 	got_socketpair = "";
 #endif
 
+#if HAVE_FTRUNCATE
+	have_inplace = "";
+#endif
+
 #if SUPPORT_HARD_LINKS
 	hardlinks = "";
 #endif
@@ -182,8 +188,8 @@ static void print_rsync_version(enum log
 	/* Note that this field may not have type ino_t.  It depends
 	 * on the complicated interaction between largefile feature
 	 * macros. */
-	rprintf(f, "              %sIPv6, %d-bit system inums, %d-bit internal inums\n",
-		ipv6,
+	rprintf(f, "              %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
+		have_inplace, ipv6,
 		(int) (sizeof dumstat->st_ino * 8),
 		(int) (sizeof (uint64) * 8));
 #ifdef MAINTAINER_MODE
@@ -233,6 +239,7 @@ void usage(enum logcode F)
   rprintf(F,"     --backup-dir            make backups into this directory\n");
   rprintf(F,"     --suffix=SUFFIX         backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
   rprintf(F," -u, --update                update only (don't overwrite newer files)\n");
+  rprintf(F,"     --inplace               update the destination file inplace (see man page)\n");
   rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
   rprintf(F," -l, --links                 copy symlinks as symlinks\n");
   rprintf(F," -L, --copy-links            copy the referent of all symlinks\n");
@@ -340,6 +347,7 @@ static struct poptOption long_options[] 
   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
+  {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
   {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
   {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
@@ -754,6 +762,18 @@ int parse_arguments(int *argc, const cha
 			bwlimit_writemax = 512;
 	}
 
+	if (inplace) {
+#if HAVE_FTRUNCATE
+		if (keep_partial)
+			keep_partial = 0;
+#else
+		snprintf(err_buf, sizeof err_buf,
+			 "inplace is not supported on this %s\n",
+			 am_server ? "server" : "client");
+		return 0;
+#endif
+	}
+
 	if (files_from) {
 		char *colon;
 		if (*argc != 2 && !(am_server && am_sender && *argc == 1)) {
@@ -971,6 +991,9 @@ void server_options(char **args,int *arg
 	if (opt_ignore_existing && am_sender)
 		args[ac++] = "--ignore-existing";
 
+	if (inplace)
+		args[ac++] = "--inplace";
+
 	if (tmpdir) {
 		args[ac++] = "--temp-dir";
 		args[ac++] = tmpdir;
--- orig/receiver.c	2004-07-14 17:12:06
+++ receiver.c	2004-07-03 20:19:54
@@ -48,6 +48,7 @@ extern int ignore_errors;
 extern int orig_umask;
 extern int keep_partial;
 extern int checksum_seed;
+extern int inplace;
 
 static void delete_one(char *fn, int is_dir)
 {
@@ -255,16 +256,30 @@ static int receive_data(int f_in,struct 
 			sum_update(map,len);
 		}
 
-		if (fd != -1 && write_file(fd, map, len) != (int)len) {
-			rsyserr(FERROR, errno, "write failed on %s",
-				full_fname(fname));
-			exit_cleanup(RERR_FILEIO);
+		if (!inplace || offset != offset2) {
+			if (fd != -1 && write_file(fd, map, len) != (int)len) {
+				rsyserr(FERROR, errno, "write failed on %s",
+					full_fname(fname));
+				exit_cleanup(RERR_FILEIO);
+			}
+		} else {
+			flush_write_file(fd);
+			if (do_lseek(fd,(OFF_T)len,SEEK_CUR) != offset+len) {
+				rprintf(FERROR, "lseek failed on %s: %s, %lli, %lli, %i\n",
+					full_fname(fname), strerror(errno), do_lseek(fd,0,SEEK_CUR), (offset+len), i);
+				exit_cleanup(RERR_FILEIO);
+			}
 		}
 		offset += len;
 	}
 
 	flush_write_file(fd);
 
+#ifdef HAVE_FTRUNCATE
+	if (inplace)
+		ftruncate(fd, offset);
+#endif
+
 	if (do_progress)
 		end_progress(total_size);
 
@@ -414,44 +429,59 @@ int recv_files(int f_in, struct file_lis
 		} else
 			mapbuf = NULL;
 
-		if (!get_tmpname(fnametmp,fname)) {
-			if (mapbuf)
-				unmap_file(mapbuf);
-			if (fd1 != -1)
-				close(fd1);
-			continue;
-		}
+		/* We now check to see if we are writing file "inplace" */
+		if (inplace)  {
+			fd2 = do_open(fnamecmp, O_WRONLY|O_CREAT, 0);
+			if (fd2 == -1) {
+				rsyserr(FERROR, errno, "open %s failed",
+					full_fname(fnamecmp));
+				receive_data(f_in,mapbuf,-1,NULL,file->length);
+				if (mapbuf)
+					unmap_file(mapbuf);
+				if (fd1 != -1)
+					close(fd1);
+				continue;
+			}
+		} else {
+			if (!get_tmpname(fnametmp,fname)) {
+				if (mapbuf)
+					unmap_file(mapbuf);
+				if (fd1 != -1)
+					close(fd1);
+				continue;
+			}
 
-		strlcpy(template, fnametmp, sizeof template);
+			strlcpy(template, fnametmp, sizeof template);
 
-		/* we initially set the perms without the
-		 * setuid/setgid bits to ensure that there is no race
-		 * condition. They are then correctly updated after
-		 * the lchown. Thanks to snabb@epipe.fi for pointing
-		 * this out.  We also set it initially without group
-		 * access because of a similar race condition. */
-		fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
-
-		/* in most cases parent directories will already exist
-		 * because their information should have been previously
-		 * transferred, but that may not be the case with -R */
-		if (fd2 == -1 && relative_paths && errno == ENOENT &&
-		    create_directory_path(fnametmp, orig_umask) == 0) {
-			strlcpy(fnametmp, template, sizeof fnametmp);
+			/* we initially set the perms without the
+			 * setuid/setgid bits to ensure that there is no race
+			 * condition. They are then correctly updated after
+			 * the lchown. Thanks to snabb@epipe.fi for pointing
+			 * this out.  We also set it initially without group
+			 * access because of a similar race condition. */
 			fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
-		}
-		if (fd2 == -1) {
-			rsyserr(FERROR, errno, "mkstemp %s failed",
-				full_fname(fnametmp));
-			receive_data(f_in,mapbuf,-1,NULL,file->length);
-			if (mapbuf)
-				unmap_file(mapbuf);
-			if (fd1 != -1)
-				close(fd1);
-			continue;
-		}
 
-		cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2);
+			/* in most cases parent directories will already exist
+			 * because their information should have been previously
+			 * transferred, but that may not be the case with -R */
+			if (fd2 == -1 && relative_paths && errno == ENOENT
+			    && create_directory_path(fnametmp, orig_umask) == 0) {
+				strlcpy(fnametmp, template, sizeof fnametmp);
+				fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
+			}
+			if (fd2 == -1) {
+				rsyserr(FERROR, errno, "mkstemp %s failed",
+					full_fname(fnametmp));
+				receive_data(f_in,mapbuf,-1,NULL,file->length);
+				if (mapbuf)
+					unmap_file(mapbuf);
+				if (fd1 != -1)
+					close(fd1);
+				continue;
+			}
+
+			cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2);
+		}
 
 		if (!am_server && verbose)
 			rprintf(FINFO, "%s\n", fname);
--- orig/rsync.c	2004-07-02 18:06:32
+++ rsync.c	2004-07-03 20:19:54
@@ -34,6 +34,7 @@ extern int force_delete;
 extern int recurse;
 extern int make_backups;
 extern char *backup_dir;
+extern int inplace;
 
 
 /*
@@ -239,6 +240,13 @@ void finish_transfer(char *fname, char *
 	if (make_backups && !make_backup(fname))
 		return;
 
+	if (inplace) {
+		if (verbose > 2)
+			rprintf(FINFO, "finishing %s\n", fname);
+		set_perms(fname, file, NULL, 0);
+		return;
+	}
+
 	/* move tmp file over real file */
 	if (verbose > 2)
 		rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
--- orig/rsync.h	2004-07-07 08:27:00
+++ rsync.h	2004-07-16 19:36:20
@@ -458,11 +458,13 @@ struct file_list {
 	struct file_struct **files;
 };
 
+#define SUMFLG_SAME_OFFSET	(1<<0)
+
 struct sum_buf {
 	OFF_T offset;		/**< offset in file of this chunk */
 	unsigned int len;	/**< length of chunk of file */
-	int i;			/**< index of this chunk */
 	uint32 sum1;	        /**< simple checksum */
+	short flags;		/**< flag bits */
 	char sum2[SUM_LENGTH];	/**< checksum  */
 };
 
--- orig/rsync.yo	2004-07-16 19:35:29
+++ rsync.yo	2004-07-03 20:19:55
@@ -289,6 +289,7 @@ verb(
      --backup-dir            make backups into this directory
      --suffix=SUFFIX         backup suffix (default ~ w/o --backup-dir)
  -u, --update                update only (don't overwrite newer files)
+     --inplace               update the destination file inplace
  -K, --keep-dirlinks         treat symlinked dir on receiver as dir
  -l, --links                 copy symlinks as symlinks
  -L, --copy-links            copy the referent of all symlinks
@@ -484,6 +485,17 @@ dit(bf(-K, --keep-dirlinks)) On the rece
 pointing to a directory, it will be treated as matching a directory
 from the sender.
 
+dit(bf(--inplace)) This causes rsync not to create a new copy of the file
+and then move it into place.  Instead rsync will overwrite the existing
+file, meaning that the rsync algorithm can't extract the full ammount of
+network reduction it might otherwise.
+
+This option is useful for transfer of large files with block based changes
+and also on systems that are disk bound not network bound.
+
+WARNING: If the transfer is interrupted, you will have an inconsistent file
+and the transfer should be run again.
+
 dit(bf(-l, --links)) When symlinks are encountered, recreate the
 symlink on the destination.
 
--- orig/sender.c	2004-07-15 02:21:11
+++ sender.c	2004-07-16 19:40:59
@@ -85,7 +85,7 @@ static struct sum_struct *receive_sums(i
 		read_buf(f, s->sums[i].sum2, s->s2length);
 
 		s->sums[i].offset = offset;
-		s->sums[i].i = i;
+		s->sums[i].flags = 0;
 
 		if (i == (int) s->count-1 && s->remainder != 0) {
 			s->sums[i].len = s->remainder;
