The patches for 3.0.1pre1.
[rsync-patches.git] / fsync.diff
1 This patch from Sami Farin lets you specify --fsync if you want fsync()
2 to be called on every file we write.
3
4 To use this patch, run these commands for a successful build:
5
6     patch -p1 <patches/fsync.diff
7     ./configure                         (optional if already run)
8     make
9
10 diff --git a/options.c b/options.c
11 --- a/options.c
12 +++ b/options.c
13 @@ -48,6 +48,7 @@ int append_mode = 0;
14  int keep_dirlinks = 0;
15  int copy_dirlinks = 0;
16  int copy_links = 0;
17 +int do_fsync = 0;
18  int preserve_links = 0;
19  int preserve_hard_links = 0;
20  int preserve_acls = 0;
21 @@ -383,6 +384,7 @@ void usage(enum logcode F)
22    rprintf(F,"     --partial-dir=DIR       put a partially transferred file into DIR\n");
23    rprintf(F,"     --delay-updates         put all updated files into place at transfer's end\n");
24    rprintf(F," -m, --prune-empty-dirs      prune empty directory chains from the file-list\n");
25 +  rprintf(F,"     --fsync                 fsync every written file\n");
26    rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
27    rprintf(F,"     --timeout=SECONDS       set I/O timeout in seconds\n");
28    rprintf(F,"     --contimeout=SECONDS    set daemon connection timeout in seconds\n");
29 @@ -626,6 +628,7 @@ static struct poptOption long_options[] = {
30    {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
31    {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
32    {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
33 +  {"fsync",            0,  POPT_ARG_NONE,   &do_fsync, 0, 0, 0 },
34    {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
35    {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
36    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
37 @@ -2003,6 +2006,9 @@ void server_options(char **args, int *argc_p)
38                         args[ac++] = tmpdir;
39                 }
40  
41 +               if (do_fsync)
42 +                       args[ac++] = "--fsync";
43 +
44                 if (basis_dir[0]) {
45                         /* the server only needs this option if it is not the sender,
46                          *   and it may be an older version that doesn't know this
47 diff --git a/receiver.c b/receiver.c
48 --- a/receiver.c
49 +++ b/receiver.c
50 @@ -39,6 +39,7 @@ extern int relative_paths;
51  extern int preserve_hard_links;
52  extern int preserve_perms;
53  extern int preserve_xattrs;
54 +extern int do_fsync;
55  extern int basis_dir_cnt;
56  extern int make_backups;
57  extern int cleanup_got_literal;
58 @@ -298,6 +299,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
59                 exit_cleanup(RERR_FILEIO);
60         }
61  
62 +       if (do_fsync && fd != -1 && fsync(fd) != 0) {
63 +               rsyserr(FERROR, errno, "fsync failed on %s",
64 +                       full_fname(fname));
65 +               exit_cleanup(RERR_FILEIO);
66 +       }
67 +
68         sum_len = sum_end(file_sum1);
69  
70         if (mapbuf)
71 diff --git a/t_stub.c b/t_stub.c
72 --- a/t_stub.c
73 +++ b/t_stub.c
74 @@ -21,6 +21,7 @@
75  
76  #include "rsync.h"
77  
78 +int do_fsync = 0;
79  int modify_window = 0;
80  int module_id = -1;
81  int relative_paths = 0;
82 diff --git a/util.c b/util.c
83 --- a/util.c
84 +++ b/util.c
85 @@ -26,6 +26,7 @@
86  extern int verbose;
87  extern int dry_run;
88  extern int module_id;
89 +extern int do_fsync;
90  extern int modify_window;
91  extern int relative_paths;
92  extern int human_readable;
93 @@ -315,6 +316,13 @@ int copy_file(const char *source, const char *dest, int ofd,
94                         full_fname(source));
95         }
96  
97 +       if (do_fsync && fsync(ofd) < 0) {
98 +               rsyserr(FERROR, errno, "fsync failed on %s",
99 +                       full_fname(dest));
100 +               close(ofd);
101 +               return -1;
102 +       }
103 +
104         if (close(ofd) < 0) {
105                 rsyserr(FERROR_XFER, errno, "close failed on %s",
106                         full_fname(dest));