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