File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / rsync / patches / direct-io.diff
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:32:36 2021 UTC (3 years, 3 months ago) by misho
Branches: rsync, MAIN
CVS tags: v3_2_3, HEAD
rsync 3.2.3

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: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
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;
@@ -754,6 +755,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
@@ -409,6 +409,7 @@ detailed description below for a complete description.
 --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
@@ -3012,6 +3013,16 @@ your home directory (remove the '=' for that).
     update algorithm that is even more atomic (it uses `--link-dest` 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` (`-M`) option to specify it for the remote side.  For
+    instance, this specifies it for both sides:
+
+    >     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
@@ -91,7 +93,12 @@ int do_symlink(const char *lnk, const char *fname)
 	 * and write the lnk into it. */
 	if (am_root < 0) {
 		int ok, len = strlen(lnk);
-		int fd = open(fname, 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(fname, flags, S_IWUSR|S_IRUSR);
 		if (fd < 0)
 			return -1;
 		ok = write(fd, lnk, len) == len;
@@ -220,6 +227,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);
 }
@@ -624,6 +633,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
diff -Nurp a/rsync.1 b/rsync.1
--- a/rsync.1
+++ b/rsync.1
@@ -485,6 +485,7 @@ detailed description below for a complet
 --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
@@ -3073,6 +3074,18 @@ delayed updates will fail if they can't
 See also the "atomic-rsync" perl script in the "support" subdir for an
 update algorithm that is even more atomic (it uses \fB\-\-link-dest\fP and a
 parallel hierarchy of files).
+.IP "\fB\-\-direct-io\fP"
+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 \fB\-\-remote-option\fP (\fB\-M\fP) option to specify it for the remote side.  For
+instance, this specifies it for both sides:
+.RS 4
+.IP
+.nf
+rsync -av {,-M}--direct-io /src/ host:/dest/
+.fi
+.RE
 .IP "\fB\-\-prune-empty-dirs\fP, \fB\-m\fP"
 This option tells the receiving rsync to get rid of empty directories from
 the file-list, including nested directories that have no non-directory
diff -Nurp a/rsync.1.html b/rsync.1.html
--- a/rsync.1.html
+++ b/rsync.1.html
@@ -400,6 +400,7 @@ detailed description below for a complet
 --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
@@ -2845,6 +2846,18 @@ update algorithm that is even more atomi
 parallel hierarchy of files).</p>
 </dd>
 
+<dt><code>--direct-io</code></dt><dd>
+<p>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 <code>--remote-option</code> (<code>-M</code>) option to specify it for the remote side.  For
+instance, this specifies it for both sides:</p>
+<blockquote>
+<pre><code>rsync -av {,-M}--direct-io /src/ host:/dest/
+</code></pre>
+</blockquote>
+</dd>
+
 <dt><code>--prune-empty-dirs</code>, <code>-m</code></dt><dd>
 <p>This option tells the receiving rsync to get rid of empty directories from
 the file-list, including nested directories that have no non-directory

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>