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: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
14: diff --git a/options.c b/options.c
15: --- a/options.c
16: +++ b/options.c
17: @@ -24,6 +24,7 @@
18: #include "ifuncs.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: @@ -754,6 +755,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: @@ -409,6 +409,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: @@ -3012,6 +3013,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: @@ -91,7 +93,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: @@ -220,6 +227,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: @@ -624,6 +633,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
107: diff -Nurp a/rsync.1 b/rsync.1
108: --- a/rsync.1
109: +++ b/rsync.1
110: @@ -485,6 +485,7 @@ detailed description below for a complet
111: --partial keep partially transferred files
112: --partial-dir=DIR put a partially transferred file into DIR
113: --delay-updates put all updated files into place at end
114: +--direct-io don't use buffer cache for xfer file I/O
115: --prune-empty-dirs, -m prune empty directory chains from file-list
116: --numeric-ids don't map uid/gid values by user/group name
117: --usermap=STRING custom username mapping
118: @@ -3073,6 +3074,18 @@ delayed updates will fail if they can't
119: See also the "atomic-rsync" perl script in the "support" subdir for an
120: update algorithm that is even more atomic (it uses \fB\-\-link-dest\fP and a
121: parallel hierarchy of files).
122: +.IP "\fB\-\-direct-io\fP"
123: +This option opens files with a direct-I/O flag that makes the file I/O
124: +avoid the buffer cache. The option only affects one side of the transfer
125: +(unless the transfer is local). If you want it to affect both sides, use
126: +the \fB\-\-remote-option\fP (\fB\-M\fP) option to specify it for the remote side. For
127: +instance, this specifies it for both sides:
128: +.RS 4
129: +.IP
130: +.nf
131: +rsync -av {,-M}--direct-io /src/ host:/dest/
132: +.fi
133: +.RE
134: .IP "\fB\-\-prune-empty-dirs\fP, \fB\-m\fP"
135: This option tells the receiving rsync to get rid of empty directories from
136: the file-list, including nested directories that have no non-directory
137: diff -Nurp a/rsync.1.html b/rsync.1.html
138: --- a/rsync.1.html
139: +++ b/rsync.1.html
140: @@ -400,6 +400,7 @@ detailed description below for a complet
141: --partial keep partially transferred files
142: --partial-dir=DIR put a partially transferred file into DIR
143: --delay-updates put all updated files into place at end
144: +--direct-io don't use buffer cache for xfer file I/O
145: --prune-empty-dirs, -m prune empty directory chains from file-list
146: --numeric-ids don't map uid/gid values by user/group name
147: --usermap=STRING custom username mapping
148: @@ -2845,6 +2846,18 @@ update algorithm that is even more atomi
149: parallel hierarchy of files).</p>
150: </dd>
151:
152: +<dt><code>--direct-io</code></dt><dd>
153: +<p>This option opens files with a direct-I/O flag that makes the file I/O
154: +avoid the buffer cache. The option only affects one side of the transfer
155: +(unless the transfer is local). If you want it to affect both sides, use
156: +the <code>--remote-option</code> (<code>-M</code>) option to specify it for the remote side. For
157: +instance, this specifies it for both sides:</p>
158: +<blockquote>
159: +<pre><code>rsync -av {,-M}--direct-io /src/ host:/dest/
160: +</code></pre>
161: +</blockquote>
162: +</dd>
163: +
164: <dt><code>--prune-empty-dirs</code>, <code>-m</code></dt><dd>
165: <p>This option tells the receiving rsync to get rid of empty directories from
166: the file-list, including nested directories that have no non-directory
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>