leveldb/util
costan 296de8d5b8 leveldb: Fix PosixWritableFile::Sync() on Apple systems.
Apple doesn't follow POSIX specifications for fsync(). Instead, fsync() guarantees to flush the buffer cache to the device, which means the data will survive kernel panics, but may not survive power outages. Applications that need stronger guarantees (like databases) need to use fcntl(F_FULLFSYNC).

This CL switches PosixWritableFile::Sync() to get the stronger guarantees on Apple systems. The improved implementation follows the same principles as SQLite [1] and node.js [2].

Research for the fcntl() to fsync() fallback strategy:

Apple's released source code at https://opensource.apple.com/ shows at least three different error codes being returned when a filesystem does not support F_FULLFSYNC.

fcntl() is implemented in xnu-4903.221.2 in bsd/kern/kern_descrip.c, where it delegates to fcntl_nocancel(). The documentation for fcntl_nocancel() mentions error codes for some operations, but does not include F_FULLFSYNC. The F_FULLSYNC branch in fcntl_nocancel() calls VNOP_IOCTL(_, F_FULLSYNC, NULL, 0, _), whose return value sets the error
code.

VNOP_IOCTL() is implemented in bsd/vfs/kpi_vfs.c and calls the ioctl function in the vnode's operation vector. The per-filesystem function names follow the pattern _vnop_ioctl() for all the instances in opensource code: {hfs,msdosfs,nfs,ntfs,smbfs,webdav,zfs}_vnop_ioctl().

hfs-407.30.1, msdosfs-229.200.3, and nfs in xnu-4903.221.2 handle F_FULLFSYNC. ntfs-94.200.1 and smb-759.40.1 do not handle F_FULLFSYNC, and the default branch returns ENOSUP. webdav-380.200.1 also does not handle F_FULLFSYNC, but the default branch returns EINVAL. zfs-59 also does not handle F_FULLSYNC, and its default branch returns ENOTTY.

From a different angle, Apple's ntfs-94.200.1 includes utility code that uses fcntl(F_FULLFSYNC) and falls back to fsync() just like we do, supporting the hypothesis that there is no good way to detect lack of F_FULLFSYNC support. Also, Apple's fcntl() man page [3] does not mention a way to detect lack of F_FULLFSYNC support.

[1] https://www.sqlite.org/src/doc/trunk/src/os_unix.c
[2] https://github.com/libuv/libuv/blob/master/src/unix/fs.c
[3] https://developer.apple.com/library/archive/documentatiVon/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html
Tested:
    https://travis-ci.org/pwnall/leveldb/builds/477318498
    TAP global presubmit

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=228593729
2019-01-09 14:58:22 -08:00
..
arena_test.cc Release LevelDB 1.15 2013-12-10 10:36:31 -08:00
arena.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
arena.h Resolve race when getting approximate-memory-usage property 2015-12-09 11:27:50 -08:00
bloom_test.cc Fix size_t/int comparison/conversion issues in leveldb. 2015-12-09 10:34:58 -08:00
bloom.cc Fix size_t/int comparison/conversion issues in leveldb. 2015-12-09 10:34:58 -08:00
cache_test.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
cache.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
coding_test.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
coding.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
coding.h Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
comparator.cc Remove InitOnce from the port API. 2018-09-10 19:04:59 -07:00
crc32c_test.cc A number of fixes: 2011-10-31 17:22:06 +00:00
crc32c.cc Use portable CRC32C from google/crc32c. 2017-09-26 18:50:41 -07:00
crc32c.h Remove extern from function declarations. 2018-03-12 09:24:48 -07:00
env_posix_test_helper.h Limit the number of read-only files the POSIX Env will have open. 2017-01-04 09:13:20 -08:00
env_posix_test.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
env_posix.cc leveldb: Fix PosixWritableFile::Sync() on Apple systems. 2019-01-09 14:58:22 -08:00
env_test.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
env.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
filter_policy.cc Added bloom filter support. 2012-04-17 08:36:46 -07:00
hash_test.cc Release 1.18 2014-09-16 14:19:52 -07:00
hash.cc Release 1.18 2014-09-16 14:19:52 -07:00
hash.h Remove extern from function declarations. 2018-03-12 09:24:48 -07:00
histogram.cc A number of fixes: 2011-10-31 17:22:06 +00:00
histogram.h A number of fixes: 2011-10-31 17:22:06 +00:00
logging_test.cc Add tests for ConsumeDecimalNumber. 2018-04-13 15:36:55 -07:00
logging.cc Add forgotten <limits> header to util/logging.cc. 2018-04-13 16:21:07 -07:00
logging.h Remove extern from function declarations. 2018-03-12 09:24:48 -07:00
mutexlock.h C++11 cleanup for util/mutexlock.h. 2018-09-24 13:37:01 -07:00
no_destructor_test.cc Remove InitOnce from the port API. 2018-09-10 19:04:59 -07:00
no_destructor.h Remove InitOnce from the port API. 2018-09-10 19:04:59 -07:00
options.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
posix_logger.h Add back space to POSIX Logger. 2019-01-07 22:03:34 -08:00
random.h LevelDB 1.13 2013-08-21 11:12:47 -07:00
status_test.cc Add move constructor to Status. 2018-04-23 16:22:30 -07:00
status.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
testharness.cc Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00
testharness.h Fix includes in util/testharness.h. 2018-03-16 10:31:48 -07:00
testutil.cc Remove extern from function declarations. 2018-03-12 09:24:48 -07:00
testutil.h Replace NULL with nullptr in C++ files. 2018-04-10 16:26:43 -07:00