diff options
author | Jim Meyering <meyering@redhat.com> | 2009-08-07 16:21:35 +0200 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-08-07 16:21:35 +0200 |
commit | ff159a605e5bc10fe871109f66cba5ee410c9138 (patch) | |
tree | 16b57d86da49edf8d7b74673ec960e4b19128e41 | |
parent | c5c15884dfef11379720bf360599b11a33d49ac0 (diff) | |
download | coreutils-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.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -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) |