Updated patches to work with the current trunk.
[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 index e7c6c61..44ad60e 100644
12 --- a/options.c
13 +++ b/options.c
14 @@ -48,6 +48,7 @@ int append_mode = 0;
15  int keep_dirlinks = 0;
16  int copy_dirlinks = 0;
17  int copy_links = 0;
18 +int do_fsync = 0;
19  int preserve_links = 0;
20  int preserve_hard_links = 0;
21  int preserve_acls = 0;
22 @@ -730,6 +731,7 @@ void usage(enum logcode F)
23    rprintf(F,"     --partial-dir=DIR       put a partially transferred file into DIR\n");
24    rprintf(F,"     --delay-updates         put all updated files into place at transfer's end\n");
25    rprintf(F," -m, --prune-empty-dirs      prune empty directory chains from the file-list\n");
26 +  rprintf(F,"     --fsync                 fsync every written file\n");
27    rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
28    rprintf(F,"     --usermap=STRING        custom username mapping\n");
29    rprintf(F,"     --groupmap=STRING       custom groupname mapping\n");
30 @@ -988,6 +990,7 @@ static struct poptOption long_options[] = {
31    {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
32    {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
33    {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
34 +  {"fsync",            0,  POPT_ARG_NONE,   &do_fsync, 0, 0, 0 },
35    {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
36    {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
37    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
38 @@ -2555,6 +2558,9 @@ void server_options(char **args, int *argc_p)
39                         args[ac++] = tmpdir;
40                 }
41  
42 +               if (do_fsync)
43 +                       args[ac++] = "--fsync";
44 +
45                 if (basis_dir[0]) {
46                         /* the server only needs this option if it is not the sender,
47                          *   and it may be an older version that doesn't know this
48 diff --git a/receiver.c b/receiver.c
49 index 4325e30..1523977 100644
50 --- a/receiver.c
51 +++ b/receiver.c
52 @@ -38,6 +38,7 @@ extern int relative_paths;
53  extern int preserve_hard_links;
54  extern int preserve_perms;
55  extern int preserve_xattrs;
56 +extern int do_fsync;
57  extern int basis_dir_cnt;
58  extern int make_backups;
59  extern int cleanup_got_literal;
60 @@ -305,6 +306,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
61         if (sum_end(file_sum1) != checksum_len)
62                 overflow_exit("checksum_len"); /* Impossible... */
63  
64 +       if (do_fsync && fd != -1 && fsync(fd) != 0) {
65 +               rsyserr(FERROR, errno, "fsync failed on %s",
66 +                       full_fname(fname));
67 +               exit_cleanup(RERR_FILEIO);
68 +       }
69 +
70         if (mapbuf)
71                 unmap_file(mapbuf);
72  
73 diff --git a/t_stub.c b/t_stub.c
74 index 02cfa69..fb61480 100644
75 --- a/t_stub.c
76 +++ b/t_stub.c
77 @@ -21,6 +21,7 @@
78  
79  #include "rsync.h"
80  
81 +int do_fsync = 0;
82  int modify_window = 0;
83  int module_id = -1;
84  int relative_paths = 0;
85 diff --git a/util.c b/util.c
86 index 0cafed6..88b3521 100644
87 --- a/util.c
88 +++ b/util.c
89 @@ -27,6 +27,7 @@
90  
91  extern int dry_run;
92  extern int module_id;
93 +extern int do_fsync;
94  extern int modify_window;
95  extern int relative_paths;
96  extern int preserve_xattrs;
97 @@ -334,6 +335,13 @@ int copy_file(const char *source, const char *dest, int ofd,
98                         full_fname(source));
99         }
100  
101 +       if (do_fsync && fsync(ofd) < 0) {
102 +               rsyserr(FERROR, errno, "fsync failed on %s",
103 +                       full_fname(dest));
104 +               close(ofd);
105 +               return -1;
106 +       }
107 +
108         if (close(ofd) < 0) {
109                 int save_errno = errno;
110                 rsyserr(FERROR_XFER, errno, "close failed on %s",