From 9a41731949f2c9a9a133bd90b4a8aa0b511a9565 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 7 Jun 2019 09:38:28 +0200 Subject: [PATCH] darwin: fall back to F_BARRIERFSYNC Fall back to F_BARRIERFSYNC if F_FULLFSYNC is not supported by the file system, only fall back to fsync() if both fcntls fail. F_BARRIERFSYNC should be at least as safe as fsync() because it's fsync coupled with a barrier. PR-URL: https://github.com/libuv/libuv/pull/2317 Reviewed-By: Colin Ihrig --- src/unix/fs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index 24a130f5..c28c72c5 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -160,12 +160,15 @@ static ssize_t uv__fs_fsync(uv_fs_t* req) { * 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. If F_FULLFSYNC is not - * supported by the file system we should fall back to fsync(). This is the - * same approach taken by sqlite. + * supported by the file system we fall back to F_BARRIERFSYNC or fsync(). + * This is the same approach taken by sqlite, except sqlite does not issue + * an F_BARRIERFSYNC call. */ int r; r = fcntl(req->file, F_FULLFSYNC); + if (r != 0) + r = fcntl(req->file, F_BARRIERFSYNC); /* fsync + barrier */ if (r != 0) r = fsync(req->file); return r;