File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / rsync / patches / fsync.diff
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:32:36 2021 UTC (3 years, 3 months ago) by misho
Branches: rsync, MAIN
CVS tags: v3_2_3, HEAD
rsync 3.2.3

This patch from Sami Farin lets you specify --fsync if you want fsync()
to be called on every file we write.

To use this patch, run these commands for a successful build:

    patch -p1 <patches/fsync.diff
    ./configure                         (optional if already run)
    make

based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
@@ -66,6 +66,7 @@ int open_noatime = 0;
 int cvs_exclude = 0;
 int dry_run = 0;
 int do_xfers = 1;
+int do_fsync = 0;
 int ignore_times = 0;
 int delete_mode = 0;
 int delete_during = 0;
@@ -789,6 +790,7 @@ static struct poptOption long_options[] = {
   {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
   {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
   {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
+  {"fsync",            0,  POPT_ARG_NONE,   &do_fsync, 0, 0, 0 },
   {"stop-after",       0,  POPT_ARG_STRING, 0, OPT_STOP_AFTER, 0, 0 },
   {"time-limit",       0,  POPT_ARG_STRING, 0, OPT_STOP_AFTER, 0, 0 }, /* earlier stop-after name */
   {"stop-at",          0,  POPT_ARG_STRING, 0, OPT_STOP_AT, 0, 0 },
@@ -2845,6 +2847,9 @@ void server_options(char **args, int *argc_p)
 			args[ac++] = tmpdir;
 		}
 
+		if (do_fsync)
+			args[ac++] = "--fsync";
+
 		if (basis_dir[0]) {
 			/* the server only needs this option if it is not the sender,
 			 *   and it may be an older version that doesn't know this
diff --git a/receiver.c b/receiver.c
--- a/receiver.c
+++ b/receiver.c
@@ -41,6 +41,7 @@ extern int preserve_hard_links;
 extern int preserve_perms;
 extern int write_devices;
 extern int preserve_xattrs;
+extern int do_fsync;
 extern int basis_dir_cnt;
 extern int make_backups;
 extern int cleanup_got_literal;
@@ -394,6 +395,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
 
 	sum_len = sum_end(file_sum1);
 
+	if (do_fsync && fd != -1 && fsync(fd) != 0) {
+		rsyserr(FERROR, errno, "fsync failed on %s",
+			full_fname(fname));
+		exit_cleanup(RERR_FILEIO);
+	}
+
 	if (mapbuf)
 		unmap_file(mapbuf);
 
diff --git a/rsync.1.md b/rsync.1.md
--- a/rsync.1.md
+++ b/rsync.1.md
@@ -410,6 +410,7 @@ detailed description below for a complete description.
 --partial-dir=DIR        put a partially transferred file into DIR
 --delay-updates          put all updated files into place at end
 --prune-empty-dirs, -m   prune empty directory chains from file-list
+--fsync                  fsync every written file
 --numeric-ids            don't map uid/gid values by user/group name
 --usermap=STRING         custom username mapping
 --groupmap=STRING        custom groupname mapping
diff --git a/t_stub.c b/t_stub.c
--- a/t_stub.c
+++ b/t_stub.c
@@ -21,6 +21,7 @@
 
 #include "rsync.h"
 
+int do_fsync = 0;
 int inplace = 0;
 int modify_window = 0;
 int preallocate_files = 0;
diff --git a/util.c b/util.c
--- a/util.c
+++ b/util.c
@@ -27,6 +27,7 @@
 
 extern int dry_run;
 extern int module_id;
+extern int do_fsync;
 extern int protect_args;
 extern int modify_window;
 extern int relative_paths;
@@ -412,6 +413,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
 		rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest));
 	}
 
+	if (do_fsync && fsync(ofd) < 0) {
+		rsyserr(FERROR, errno, "fsync failed on %s",
+			full_fname(dest));
+		close(ofd);
+		return -1;
+	}
+
 	if (close(ofd) < 0) {
 		int save_errno = errno;
 		rsyserr(FERROR_XFER, errno, "close failed on %s",
diff -Nurp a/rsync.1 b/rsync.1
--- a/rsync.1
+++ b/rsync.1
@@ -486,6 +486,7 @@ detailed description below for a complet
 --partial-dir=DIR        put a partially transferred file into DIR
 --delay-updates          put all updated files into place at end
 --prune-empty-dirs, -m   prune empty directory chains from file-list
+--fsync                  fsync every written file
 --numeric-ids            don't map uid/gid values by user/group name
 --usermap=STRING         custom username mapping
 --groupmap=STRING        custom groupname mapping
diff -Nurp a/rsync.1.html b/rsync.1.html
--- a/rsync.1.html
+++ b/rsync.1.html
@@ -401,6 +401,7 @@ detailed description below for a complet
 --partial-dir=DIR        put a partially transferred file into DIR
 --delay-updates          put all updated files into place at end
 --prune-empty-dirs, -m   prune empty directory chains from file-list
+--fsync                  fsync every written file
 --numeric-ids            don't map uid/gid values by user/group name
 --usermap=STRING         custom username mapping
 --groupmap=STRING        custom groupname mapping

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>