Adding filter-attribute-mods patch; updating patches.
[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 based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
11 diff --git a/options.c b/options.c
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 @@ -2572,6 +2575,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 --- a/receiver.c
50 +++ b/receiver.c
51 @@ -38,6 +38,7 @@ extern int relative_paths;
52  extern int preserve_hard_links;
53  extern int preserve_perms;
54  extern int preserve_xattrs;
55 +extern int do_fsync;
56  extern int basis_dir_cnt;
57  extern int make_backups;
58  extern int cleanup_got_literal;
59 @@ -305,6 +306,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
60         if (sum_end(file_sum1) != checksum_len)
61                 overflow_exit("checksum_len"); /* Impossible... */
62  
63 +       if (do_fsync && fd != -1 && fsync(fd) != 0) {
64 +               rsyserr(FERROR, errno, "fsync failed on %s",
65 +                       full_fname(fname));
66 +               exit_cleanup(RERR_FILEIO);
67 +       }
68 +
69         if (mapbuf)
70                 unmap_file(mapbuf);
71  
72 diff --git a/t_stub.c b/t_stub.c
73 --- a/t_stub.c
74 +++ b/t_stub.c
75 @@ -21,6 +21,7 @@
76  
77  #include "rsync.h"
78  
79 +int do_fsync = 0;
80  int modify_window = 0;
81  int module_id = -1;
82  int relative_paths = 0;
83 diff --git a/util.c b/util.c
84 --- a/util.c
85 +++ b/util.c
86 @@ -27,6 +27,7 @@
87  
88  extern int dry_run;
89  extern int module_id;
90 +extern int do_fsync;
91  extern int modify_window;
92  extern int relative_paths;
93  extern int preserve_xattrs;
94 @@ -374,6 +375,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
95                         full_fname(source));
96         }
97  
98 +       if (do_fsync && fsync(ofd) < 0) {
99 +               rsyserr(FERROR, errno, "fsync failed on %s",
100 +                       full_fname(dest));
101 +               close(ofd);
102 +               return -1;
103 +       }
104 +
105         if (close(ofd) < 0) {
106                 int save_errno = errno;
107                 rsyserr(FERROR_XFER, errno, "close failed on %s",