1 This patch adds the --direct-io option, which opens files with O_DIRECT.
3 TODO: we probably need to make our I/O aligned on 512-byte boundaries.
7 To use this patch, run these commands for a successful build:
9 patch -p1 <patches/direct-io.diff
10 ./configure (optional if already run)
13 based-on: 2ac35b45071c7bfd8be6be41bfd45326f1f57bce
14 diff --git a/options.c b/options.c
21 +extern int direct_io;
23 extern int local_server;
24 extern int sanitize_paths;
25 @@ -747,6 +748,7 @@ void usage(enum logcode F)
26 rprintf(F," --partial keep partially transferred files\n");
27 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
28 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
29 + rprintf(F," --direct-io don't use buffer cache for xfer file I/O\n");
30 rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n");
31 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
32 rprintf(F," --usermap=STRING custom username mapping\n");
33 @@ -981,6 +983,8 @@ static struct poptOption long_options[] = {
34 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
35 {"delay-updates", 0, POPT_ARG_VAL, &delay_updates, 1, 0, 0 },
36 {"no-delay-updates", 0, POPT_ARG_VAL, &delay_updates, 0, 0, 0 },
37 + {"direct-io", 'n', POPT_ARG_VAL, &direct_io, 1, 0, 0 },
38 + {"no-direct-io", 0, POPT_ARG_VAL, &direct_io, 0, 0, 0 },
39 {"prune-empty-dirs",'m', POPT_ARG_VAL, &prune_empty_dirs, 1, 0, 0 },
40 {"no-prune-empty-dirs",0,POPT_ARG_VAL, &prune_empty_dirs, 0, 0, 0 },
41 {"no-m", 0, POPT_ARG_VAL, &prune_empty_dirs, 0, 0, 0 },
42 diff --git a/rsync.yo b/rsync.yo
45 @@ -404,6 +404,7 @@ to the detailed description below for a complete description. verb(
46 --partial keep partially transferred files
47 --partial-dir=DIR put a partially transferred file into DIR
48 --delay-updates put all updated files into place at end
49 + --direct-io don't use buffer cache for xfer file I/O
50 -m, --prune-empty-dirs prune empty directory chains from file-list
51 --numeric-ids don't map uid/gid values by user/group name
52 --usermap=STRING custom username mapping
53 @@ -2367,6 +2368,14 @@ See also the "atomic-rsync" perl script in the "support" subdir for an
54 update algorithm that is even more atomic (it uses bf(--link-dest) and a
55 parallel hierarchy of files).
57 +dit(bf(--direct-io)) This option opens files with a direct-I/O flag that
58 +makes the file I/O avoid the buffer cache. The option only affects one
59 +side of the transfer (unless the transfer is local). If you want it to
60 +affect both sides, use the bf(--remote-option) (bf(-M)) option to specify
61 +it for the remote side. For instance, this specifies it for both sides:
63 +quote(tt( rsync -av {,-M}--direct-io /src/ host:/dest/))
65 dit(bf(-m, --prune-empty-dirs)) This option tells the receiving rsync to get
66 rid of empty directories from the file-list, including nested directories
67 that have no non-directory children. This is useful for avoiding the
68 diff --git a/syscall.c b/syscall.c
71 @@ -41,6 +41,8 @@ extern int list_only;
72 extern int preserve_perms;
73 extern int preserve_executability;
77 #define RETURN_ERROR_IF(x,e) \
80 @@ -69,7 +71,12 @@ int do_symlink(const char *lnk, const char *fname)
81 * and write the lnk into it. */
83 int ok, len = strlen(lnk);
84 - int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
85 + int flags = O_WRONLY|O_CREAT|O_TRUNC;
90 + int fd = open(fname, flags, S_IWUSR|S_IRUSR);
93 ok = write(fd, lnk, len) == len;
94 @@ -190,6 +197,9 @@ int do_open(const char *pathname, int flags, mode_t mode)
95 RETURN_ERROR_IF_RO_OR_LO;
101 return open(pathname, flags | O_BINARY, mode);
104 @@ -461,6 +471,9 @@ int do_open_nofollow(const char *pathname, int flags)
112 fd = open(pathname, flags|O_NOFOLLOW);