From ccbf3a2bcf8eb060e156b024ff6670a3f272969b Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Tue, 20 Aug 2019 00:17:28 +0300 Subject: [PATCH] mdbx: rework mdbx_filesync(). --- src/mdbx.c | 19 ++++++++++++------- src/osal.c | 40 ++++++++++++++++------------------------ src/osal.h | 8 +++++++- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/mdbx.c b/src/mdbx.c index 93eef3d0..a8a6f302 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -3041,7 +3041,7 @@ __cold static int mdbx_env_sync_ex(MDBX_env *env, int force, int nonblock) { int rc = (flags & MDBX_WRITEMAP) ? mdbx_msync(&env->me_dxb_mmap, 0, usedbytes, flags & MDBX_MAPASYNC) - : mdbx_filesync(env->me_fd, false); + : mdbx_filesync(env->me_fd, MDBX_SYNC_DATA); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -5422,14 +5422,16 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, goto fail; if ((flags & MDBX_MAPASYNC) == 0) { if (unlikely(pending->mm_geo.next > steady->mm_geo.now)) { - rc = mdbx_filesize_sync(env->me_fd); + rc = mdbx_filesync(env->me_fd, MDBX_SYNC_SIZE); if (unlikely(rc != MDBX_SUCCESS)) goto fail; } env->me_sync_pending = 0; } } else { - rc = mdbx_filesync(env->me_fd, pending->mm_geo.next > steady->mm_geo.now); + rc = mdbx_filesync(env->me_fd, (pending->mm_geo.next > steady->mm_geo.now) + ? MDBX_SYNC_DATA | MDBX_SYNC_SIZE + : MDBX_SYNC_DATA); if (unlikely(rc != MDBX_SUCCESS)) goto fail; env->me_sync_pending = 0; @@ -5577,7 +5579,7 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, if (unlikely(rc != MDBX_SUCCESS)) goto fail; } else { - rc = mdbx_filesync(env->me_fd, false); + rc = mdbx_filesync(env->me_fd, MDBX_SYNC_DATA | MDBX_SYNC_IODQ); if (rc != MDBX_SUCCESS) goto undo; } @@ -11825,12 +11827,15 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, mdbx_txn_abort(read_txn); if (likely(rc == MDBX_SUCCESS)) - rc = mdbx_filesync(fd, true); + rc = mdbx_filesync(fd, MDBX_SYNC_DATA | MDBX_SYNC_SIZE); /* Write actual meta */ if (likely(rc == MDBX_SUCCESS)) rc = mdbx_pwrite(fd, buffer, pgno2bytes(env, NUM_METAS), 0); + if (likely(rc == MDBX_SUCCESS)) + rc = mdbx_filesync(fd, MDBX_SYNC_DATA | MDBX_SYNC_IODQ); + mdbx_memalign_free(buffer); return rc; } @@ -12871,7 +12876,7 @@ int __cold mdbx_setup_debug(int flags, MDBX_debug_func *logger) { unsigned ret = mdbx_runtime_flags; mdbx_runtime_flags = flags; -#ifdef __linux__ +#if defined(__linux__) || defined(__gnu_linux__) if (flags & MDBX_DBG_DUMP) { int core_filter_fd = open("/proc/self/coredump_filter", O_TRUNC | O_RDWR); if (core_filter_fd >= 0) { @@ -12894,7 +12899,7 @@ int __cold mdbx_setup_debug(int flags, MDBX_debug_func *logger) { close(core_filter_fd); } } -#endif /* __linux__ */ +#endif /* Linux */ mdbx_debug_logger = logger; return ret; diff --git a/src/osal.c b/src/osal.c index cd197f9e..141c010a 100644 --- a/src/osal.c +++ b/src/osal.c @@ -660,14 +660,22 @@ int mdbx_pwritev(mdbx_filehandle_t fd, struct iovec *iov, int iovcnt, #endif } -int mdbx_filesync(mdbx_filehandle_t fd, bool filesize_changed) { +int mdbx_filesync(mdbx_filehandle_t fd, enum mdbx_syncmode_bits mode_bits) { #if defined(_WIN32) || defined(_WIN64) - (void)filesize_changed; - return FlushFileBuffers(fd) ? MDBX_SUCCESS : GetLastError(); -#elif defined(__APPLE__) - (void)filesize_changed; - return likely(fcntl(fd, F_FULLFSYNC) != -1) ? MDBX_SUCCESS : errno; + return ((mode_bits & (MDBX_SYNC_DATA | MDBX_SYNC_IODQ)) == 0 || + FlushFileBuffers(fd)) + ? MDBX_SUCCESS + : GetLastError(); #else + +#ifdef __APPLE__ + if (mode_bits & MDBX_SYNC_IODQ) + return likely(fcntl(fd, F_FULLFSYNC) != -1) ? MDBX_SUCCESS : errno; +#endif /* MacOS */ +#if defined(__linux__) || defined(__gnu_linux__) + if (mode_bits == MDBX_SYNC_SIZE && linux_kernel_version >= 0x03060000) + return MDBX_SUCCESS; +#endif /* Linux */ int rc; do { #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 @@ -676,12 +684,12 @@ int mdbx_filesync(mdbx_filehandle_t fd, bool filesize_changed) { * * For more info about of a corresponding fdatasync() bug * see http://www.spinics.net/lists/linux-ext4/msg33714.html */ - if (!filesize_changed) { + if ((mode_bits & MDBX_SYNC_SIZE) == 0) { if (fdatasync(fd) == 0) return MDBX_SUCCESS; } else #else - (void)filesize_changed; + (void)mode_bits; #endif if (fsync(fd) == 0) return MDBX_SUCCESS; @@ -691,22 +699,6 @@ int mdbx_filesync(mdbx_filehandle_t fd, bool filesize_changed) { #endif } -int mdbx_filesize_sync(mdbx_filehandle_t fd) { -#if defined(_WIN32) || defined(_WIN64) - (void)fd; - /* Nothing on Windows (i.e. newer 100% steady) */ - return MDBX_SUCCESS; -#else - for (;;) { - if (fsync(fd) == 0) - return MDBX_SUCCESS; - int rc = errno; - if (rc != EINTR) - return rc; - } -#endif -} - int mdbx_filesize(mdbx_filehandle_t fd, uint64_t *length) { #if defined(_WIN32) || defined(_WIN64) BY_HANDLE_FILE_INFORMATION info; diff --git a/src/osal.h b/src/osal.h index 0e847a2f..3564e8dc 100644 --- a/src/osal.h +++ b/src/osal.h @@ -522,7 +522,13 @@ int mdbx_thread_create(mdbx_thread_t *thread, void *arg); int mdbx_thread_join(mdbx_thread_t thread); -int mdbx_filesync(mdbx_filehandle_t fd, bool fullsync); +enum mdbx_syncmode_bits { + MDBX_SYNC_DATA = 1, + MDBX_SYNC_SIZE = 2, + MDBX_SYNC_IODQ = 4 +}; + +int mdbx_filesync(mdbx_filehandle_t fd, enum mdbx_syncmode_bits mode_bits); int mdbx_filesize_sync(mdbx_filehandle_t fd); int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length); int mdbx_fseek(mdbx_filehandle_t fd, uint64_t pos);