From: Wayne Davison Date: Mon, 27 Sep 2021 17:30:00 +0000 (-0700) Subject: Add --fsync option (promoted from patches). X-Git-Tag: v3.2.4pre1~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82f023d7e3cca126d264ebb81b19feaf8731ad9a;p=thirdparty%2Frsync.git Add --fsync option (promoted from patches). --- diff --git a/options.c b/options.c index 54998661..98676d17 100644 --- 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 }, @@ -2806,6 +2808,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 index b5020d07..091fcd6f 100644 --- 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,11 @@ 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 index 72026dfd..9bfda865 100644 --- a/rsync.1.md +++ b/rsync.1.md @@ -461,6 +461,7 @@ detailed description below for a complete description. --bwlimit=RATE limit socket I/O bandwidth --stop-after=MINS Stop rsync after MINS minutes have elapsed --stop-at=y-m-dTh:m Stop rsync at the specified point in time +--fsync fsync every written file --write-batch=FILE write a batched update to FILE --only-write-batch=FILE like --write-batch but w/o updating dest --read-batch=FILE read a batched update from FILE @@ -3257,6 +3258,12 @@ your home directory (remove the '=' for that). mind that the remote host may have a different default timezone than your local host. +0. `--fsync` + + Cause the receiving side to fsync each finished file. This may slow down + the transfer, but can help to provide peace of mind when updating critical + files. + 0. `--write-batch=FILE` Record a file that can later be applied to another identical destination diff --git a/t_stub.c b/t_stub.c index 1e1e4046..ea2013d3 100644 --- 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/util1.c b/util1.c index ef78a82d..1cff973f 100644 --- a/util1.c +++ b/util1.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; @@ -417,10 +418,17 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode) #endif } + if (do_fsync && fsync(ofd) < 0) { + int save_errno = errno; + rsyserr(FERROR, errno, "fsync failed on %s", full_fname(dest)); + close(ofd); + errno = save_errno; + return -1; + } + if (close(ofd) < 0) { int save_errno = errno; - rsyserr(FERROR_XFER, errno, "close failed on %s", - full_fname(dest)); + rsyserr(FERROR_XFER, errno, "close failed on %s", full_fname(dest)); errno = save_errno; return -1; }