summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-08-07 16:21:35 +0200
committerJim Meyering <meyering@redhat.com>2009-08-07 16:21:35 +0200
commitff159a605e5bc10fe871109f66cba5ee410c9138 (patch)
tree16b57d86da49edf8d7b74673ec960e4b19128e41
parentc5c15884dfef11379720bf360599b11a33d49ac0 (diff)
downloadcoreutils-ff159a605e5bc10fe871109f66cba5ee410c9138.tar.xz
dd: preserve semantics of O_DIRECT even for final block
* src/dd.c: Include "ignore-value.h" (iwrite): When disabling O_DIRECT, try to compensate via POSIX_FADV_DONTNEED and fsync. Suggested by Eric Sandeen.
-rw-r--r--src/dd.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/dd.c b/src/dd.c
index 43ad7189f..d9e4c85b8 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -29,6 +29,7 @@
#include "fd-reopen.h"
#include "gethrxtime.h"
#include "human.h"
+#include "ignore-value.h"
#include "long-options.h"
#include "quote.h"
#include "quotearg.h"
@@ -843,6 +844,22 @@ iwrite (int fd, char const *buf, size_t size)
if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0)
error (0, errno, _("failed to turn off O_DIRECT: %s"),
quote (output_file));
+
+ /* Since we have just turned off O_DIRECT for the final write,
+ here we try to preserve some of its semantics. First, use
+ posix_fadvise to tell the system not to pollute the buffer
+ cache with this data. Don't bother to diagnose lseek or
+ posix_fadvise failure. */
+#ifdef POSIX_FADV_DONTNEED
+ off_t off = lseek (STDOUT_FILENO, 0, SEEK_CUR);
+ if (0 <= off)
+ ignore_value (posix_fadvise (STDOUT_FILENO,
+ off, 0, POSIX_FADV_DONTNEED));
+#endif
+
+ /* Attempt to ensure that that final block is committed
+ to disk as quickly as possible. */
+ conversions_mask |= C_FSYNC;
}
while (total_written < size)