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: 109dbc0b7535e8f8094802182f9067bfdc88dfc9
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 @@ -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
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 @@ -3028,6 +3029,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).
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:
57 + > rsync -av {,-M}--direct-io /src/ host:/dest/
59 0. `--prune-empty-dirs`, `-m`
61 This option tells the receiving rsync to get rid of empty directories from
62 diff --git a/syscall.c b/syscall.c
65 @@ -44,6 +44,8 @@ extern int preserve_perms;
66 extern int preserve_executability;
67 extern int open_noatime;
72 # if defined hpux || defined __hpux__ || defined __hpux
73 # define S_BLKSIZE 1024
74 @@ -95,7 +97,12 @@ int do_symlink(const char *lnk, const char *fname)
75 * and write the lnk into it. */
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;
84 + int fd = open(fname, flags, S_IWUSR|S_IRUSR);
87 ok = write(fd, lnk, len) == len;
88 @@ -224,6 +231,8 @@ int do_open(const char *pathname, int flags, mode_t mode)
95 return open(pathname, flags | O_BINARY, mode);
97 @@ -664,6 +673,9 @@ int do_open_nofollow(const char *pathname, int flags)
105 fd = open(pathname, flags|O_NOFOLLOW);