Fix merge conflict.
[rsync-patches.git] / direct-io.diff
1 This patch adds the --direct-io option, which opens files with O_DIRECT.
2
3 TODO: we probably need to make our I/O aligned on 512-byte boundaries.
4
5 Written by: Dag Wieers
6
7 To use this patch, run these commands for a successful build:
8
9     patch -p1 <patches/direct-io.diff
10     ./configure                         (optional if already run)
11     make
12
13 based-on: 194cee671d5e178f20c4494f41911fa8db942935
14 diff --git a/options.c b/options.c
15 --- a/options.c
16 +++ b/options.c
17 @@ -25,6 +25,7 @@
18  #include "latest-year.h"
19  #include <popt.h>
20  
21 +extern int direct_io;
22  extern int module_id;
23  extern int local_server;
24  extern int sanitize_paths;
25 @@ -953,6 +954,8 @@ static struct poptOption long_options[] = {
26    {"partial-dir",      0,  POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
27    {"delay-updates",    0,  POPT_ARG_VAL,    &delay_updates, 1, 0, 0 },
28    {"no-delay-updates", 0,  POPT_ARG_VAL,    &delay_updates, 0, 0, 0 },
29 +  {"direct-io",       'n', POPT_ARG_VAL,    &direct_io, 1, 0, 0 },
30 +  {"no-direct-io",     0,  POPT_ARG_VAL,    &direct_io, 0, 0, 0 },
31    {"prune-empty-dirs",'m', POPT_ARG_VAL,    &prune_empty_dirs, 1, 0, 0 },
32    {"no-prune-empty-dirs",0,POPT_ARG_VAL,    &prune_empty_dirs, 0, 0, 0 },
33    {"no-m",             0,  POPT_ARG_VAL,    &prune_empty_dirs, 0, 0, 0 },
34 diff --git a/rsync.1.md b/rsync.1.md
35 --- a/rsync.1.md
36 +++ b/rsync.1.md
37 @@ -407,6 +407,7 @@ detailed description below for a complete description.
38  --partial                keep partially transferred files
39  --partial-dir=DIR        put a partially transferred file into DIR
40  --delay-updates          put all updated files into place at end
41 +--direct-io              don't use buffer cache for xfer file I/O
42  --prune-empty-dirs, -m   prune empty directory chains from file-list
43  --numeric-ids            don't map uid/gid values by user/group name
44  --usermap=STRING         custom username mapping
45 @@ -2918,6 +2919,16 @@ your home directory (remove the '=' for that).
46      update algorithm that is even more atomic (it uses `--link-dest` and a
47      parallel hierarchy of files).
48  
49 +0.  `--direct-io`
50 +
51 +    This option opens files with a direct-I/O flag that makes the file I/O
52 +    avoid the buffer cache.  The option only affects one side of the transfer
53 +    (unless the transfer is local).  If you want it to affect both sides, use
54 +    the `--remote-option` (`-M`) option to specify it for the remote side.  For
55 +    instance, this specifies it for both sides:
56 +
57 +    >     rsync -av {,-M}--direct-io /src/ host:/dest/
58 +
59  0.  `--prune-empty-dirs`, `-m`
60  
61      This option tells the receiving rsync to get rid of empty directories from
62 diff --git a/syscall.c b/syscall.c
63 --- a/syscall.c
64 +++ b/syscall.c
65 @@ -44,6 +44,8 @@ extern int preserve_perms;
66  extern int preserve_executability;
67  extern int open_noatime;
68  
69 +int direct_io = 0;
70 +
71  #ifndef S_BLKSIZE
72  # if defined hpux || defined __hpux__ || defined __hpux
73  #  define S_BLKSIZE 1024
74 @@ -82,7 +84,12 @@ int do_symlink(const char *lnk, const char *fname)
75          * and write the lnk into it. */
76         if (am_root < 0) {
77                 int ok, len = strlen(lnk);
78 -               int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
79 +               int flags = O_WRONLY|O_CREAT|O_TRUNC;
80 +
81 +               if (direct_io)
82 +                       flags |= O_DIRECT;
83 +
84 +               int fd = open(fname, flags, S_IWUSR|S_IRUSR);
85                 if (fd < 0)
86                         return -1;
87                 ok = write(fd, lnk, len) == len;
88 @@ -207,6 +214,8 @@ int do_open(const char *pathname, int flags, mode_t mode)
89         if (open_noatime)
90                 flags |= O_NOATIME;
91  #endif
92 +       if (direct_io)
93 +               flags |= O_DIRECT;
94  
95         return open(pathname, flags | O_BINARY, mode);
96  }
97 @@ -575,6 +584,9 @@ int do_open_nofollow(const char *pathname, int flags)
98  #endif
99         }
100  
101 +       if (direct_io)
102 +               flags |= O_DIRECT;
103 +
104  #ifdef O_NOFOLLOW
105         fd = open(pathname, flags|O_NOFOLLOW);
106  #else