129129static ssize_t uv__fs_fdatasync (uv_fs_t * req ) {
130130#if defined(__linux__ ) || defined(__sun ) || defined(__NetBSD__ )
131131 return fdatasync (req -> file );
132- #elif defined(__APPLE__ ) && defined(SYS_fdatasync )
133- return syscall (SYS_fdatasync , req -> file );
132+ #elif defined(__APPLE__ )
133+ /* Apple's fdatasync and fsync explicitly do NOT flush the drive write cache
134+ * to the drive platters. This is in contrast to Linux's fdatasync and fsync
135+ * which do, according to recent man pages. F_FULLFSYNC is Apple's equivalent
136+ * for flushing buffered data to permanent storage.
137+ */
138+ return fcntl (req -> file , F_FULLFSYNC );
139+ #else
140+ return fsync (req -> file );
141+ #endif
142+ }
143+
144+
145+ static ssize_t uv__fs_fsync (uv_fs_t * req ) {
146+ #if defined(__APPLE__ )
147+ /* See the comment in uv__fs_fdatasync. */
148+ return fcntl (req -> file , F_FULLFSYNC );
134149#else
135150 return fsync (req -> file );
136151#endif
@@ -798,6 +813,10 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
798813 dst -> st_flags = 0 ;
799814 dst -> st_gen = 0 ;
800815#elif !defined(_AIX ) && ( \
816+ defined(__DragonFly__ ) || \
817+ defined(__FreeBSD__ ) || \
818+ defined(__OpenBSD__ ) || \
819+ defined(__NetBSD__ ) || \
801820 defined(_GNU_SOURCE ) || \
802821 defined(_BSD_SOURCE ) || \
803822 defined(_SVID_SOURCE ) || \
@@ -809,9 +828,7 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
809828 dst -> st_mtim .tv_nsec = src -> st_mtim .tv_nsec ;
810829 dst -> st_ctim .tv_sec = src -> st_ctim .tv_sec ;
811830 dst -> st_ctim .tv_nsec = src -> st_ctim .tv_nsec ;
812- # if defined(__DragonFly__ ) || \
813- defined(__FreeBSD__ ) || \
814- defined(__OpenBSD__ ) || \
831+ # if defined(__FreeBSD__ ) || \
815832 defined(__NetBSD__ )
816833 dst -> st_birthtim .tv_sec = src -> st_birthtim .tv_sec ;
817834 dst -> st_birthtim .tv_nsec = src -> st_birthtim .tv_nsec ;
@@ -945,7 +962,7 @@ static void uv__fs_work(struct uv__work* w) {
945962 X (FCHOWN , fchown (req -> file , req -> uid , req -> gid ));
946963 X (FDATASYNC , uv__fs_fdatasync (req ));
947964 X (FSTAT , uv__fs_fstat (req -> file , & req -> statbuf ));
948- X (FSYNC , fsync (req -> file ));
965+ X (FSYNC , uv__fs_fsync (req ));
949966 X (FTRUNCATE , ftruncate (req -> file , req -> off ));
950967 X (FUTIME , uv__fs_futime (req ));
951968 X (LSTAT , uv__fs_lstat (req -> path , & req -> statbuf ));
0 commit comments