darwin: fix fsync and fdatasync

Apple's fsync and fdatasync explicitly do NOT flush the drive write
cache to the drive platters. This is in contrast to Linux's fsync and
fdatasync which do, according to recent man pages. F_FULLFSYNC is
Apple's equivalent for flushing buffered data to permanent storage.

PR-URL: https://github.com/libuv/libuv/pull/1124
Refs: https://github.com/nodejs/node/issues/9439
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
Joran Dirk Greef 2016-11-04 16:14:04 +02:00 committed by Santiago Gimeno
parent a2a85f823f
commit c1c55ee1aa
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE

View File

@ -129,8 +129,23 @@
static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
#if defined(__linux__) || defined(__sun) || defined(__NetBSD__)
return fdatasync(req->file);
#elif defined(__APPLE__) && defined(SYS_fdatasync)
return syscall(SYS_fdatasync, req->file);
#elif defined(__APPLE__)
/* Apple's fdatasync and fsync explicitly do NOT flush the drive write cache
* to the drive platters. This is in contrast to Linux's fdatasync and fsync
* which do, according to recent man pages. F_FULLFSYNC is Apple's equivalent
* for flushing buffered data to permanent storage.
*/
return fcntl(req->file, F_FULLFSYNC);
#else
return fsync(req->file);
#endif
}
static ssize_t uv__fs_fsync(uv_fs_t* req) {
#if defined(__APPLE__)
/* See the comment in uv__fs_fdatasync. */
return fcntl(req->file, F_FULLFSYNC);
#else
return fsync(req->file);
#endif
@ -945,7 +960,7 @@ static void uv__fs_work(struct uv__work* w) {
X(FCHOWN, fchown(req->file, req->uid, req->gid));
X(FDATASYNC, uv__fs_fdatasync(req));
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
X(FSYNC, fsync(req->file));
X(FSYNC, uv__fs_fsync(req));
X(FTRUNCATE, ftruncate(req->file, req->off));
X(FUTIME, uv__fs_futime(req));
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));