diff --git a/src/mdbx.c b/src/mdbx.c index 7cc2c97c..a1059ea2 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -11281,6 +11281,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { uint8_t *ptr; int toggle = 0; int rc; + size_t offset = pgno2bytes(my->mc_env, NUM_METAS); #if defined(F_SETNOSIGPIPE) /* OS X delivers SIGPIPE to the whole process, not the thread that caused it. @@ -11309,7 +11310,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { ptr = my->mc_wbuf[toggle]; again: if (wsize > 0 && !my->mc_error) { - rc = mdbx_write(my->mc_fd, ptr, wsize); + rc = mdbx_pwrite(my->mc_fd, ptr, wsize, offset); if (rc != MDBX_SUCCESS) { #if defined(SIGPIPE) && !defined(_WIN32) && !defined(_WIN64) if (rc == EPIPE) { @@ -11320,7 +11321,9 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { } #endif my->mc_error = rc; + break; } + offset += wsize; } /* If there's an overflow page tail, write it too */ @@ -11708,7 +11711,7 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, /* Firstly write a stub to meta-pages. * Now we sure to incomplete copy will not be used. */ memset(buffer, -1, pgno2bytes(env, NUM_METAS)); - rc = mdbx_write(fd, buffer, pgno2bytes(env, NUM_METAS)); + rc = mdbx_pwrite(fd, buffer, pgno2bytes(env, NUM_METAS), 0); if (likely(rc == MDBX_SUCCESS)) { memset(buffer, 0, pgno2bytes(env, NUM_METAS)); rc = (flags & MDBX_CP_COMPACT) diff --git a/src/osal.c b/src/osal.c index a8f88383..2ee74441 100644 --- a/src/osal.c +++ b/src/osal.c @@ -1,4 +1,4 @@ -/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ +/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ /* * Copyright 2015-2019 Leonid Yuriev @@ -569,21 +569,21 @@ int mdbx_pread(mdbx_filehandle_t fd, void *buf, size_t bytes, uint64_t offset) { int mdbx_pwrite(mdbx_filehandle_t fd, const void *buf, size_t bytes, uint64_t offset) { -#if defined(_WIN32) || defined(_WIN64) - if (bytes > MAX_WRITE) - return ERROR_INVALID_PARAMETER; - - OVERLAPPED ov; - ov.hEvent = 0; - ov.Offset = (DWORD)offset; - ov.OffsetHigh = HIGH_DWORD(offset); - - DWORD written; - if (likely(WriteFile(fd, buf, (DWORD)bytes, &written, &ov))) - return (bytes == written) ? MDBX_SUCCESS : MDBX_EIO /* ERROR_WRITE_FAULT */; - return GetLastError(); -#else while (true) { +#if defined(_WIN32) || defined(_WIN64) + OVERLAPPED ov; + ov.hEvent = 0; + ov.Offset = (DWORD)offset; + ov.OffsetHigh = HIGH_DWORD(offset); + + DWORD written; + if (unlikely(!WriteFile(fd, buf, + (bytes <= MAX_WRITE) ? (DWORD)bytes : MAX_WRITE, + &written, &ov))) + return GetLastError(); + if (likely(bytes == written)) + return MDBX_SUCCESS; +#else STATIC_ASSERT_MSG(sizeof(off_t) >= sizeof(size_t), "libmdbx requires 64-bit file I/O on 64-bit systems"); const intptr_t written = @@ -594,15 +594,13 @@ int mdbx_pwrite(mdbx_filehandle_t fd, const void *buf, size_t bytes, const int rc = errno; if (rc != EINTR) return rc; - } else if (written > 0) { - bytes -= written; - offset += written; - buf = (char *)buf + written; - } else { - return -1; + continue; } - } #endif + bytes -= written; + offset += written; + buf = (char *)buf + written; + } } int mdbx_pwritev(mdbx_filehandle_t fd, struct iovec *iov, int iovcnt, @@ -633,52 +631,6 @@ int mdbx_pwritev(mdbx_filehandle_t fd, struct iovec *iov, int iovcnt, #endif } -int mdbx_write(mdbx_filehandle_t fd, const void *buf, size_t bytes) { -#ifdef SIGPIPE - sigset_t set, old; - sigemptyset(&set); - sigaddset(&set, SIGPIPE); - int rc = pthread_sigmask(SIG_BLOCK, &set, &old); - if (rc != 0) - return rc; -#endif - - const char *ptr = buf; - for (;;) { - size_t chunk = (MAX_WRITE < bytes) ? MAX_WRITE : bytes; -#if defined(_WIN32) || defined(_WIN64) - DWORD written; - if (unlikely(!WriteFile(fd, ptr, (DWORD)chunk, &written, NULL))) - return GetLastError(); -#else - intptr_t written = write(fd, ptr, chunk); - if (written < 0) { - int rc = errno; -#ifdef SIGPIPE - if (rc == EPIPE) { - /* Collect the pending SIGPIPE, otherwise at least OS X - * gives it to the process on thread-exit (ITS#8504). */ - int tmp; - sigwait(&set, &tmp); - written = 0; - continue; - } - pthread_sigmask(SIG_SETMASK, &old, NULL); -#endif - return rc; - } -#endif - if (likely(bytes == (size_t)written)) { -#ifdef SIGPIPE - pthread_sigmask(SIG_SETMASK, &old, NULL); -#endif - return MDBX_SUCCESS; - } - ptr += written; - bytes -= written; - } -} - int mdbx_filesync(mdbx_filehandle_t fd, bool filesize_changed) { #if defined(_WIN32) || defined(_WIN64) (void)filesize_changed; diff --git a/src/osal.h b/src/osal.h index 0208a522..c3e72e83 100644 --- a/src/osal.h +++ b/src/osal.h @@ -1,4 +1,4 @@ -/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ +/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ /* * Copyright 2015-2019 Leonid Yuriev @@ -494,7 +494,6 @@ int mdbx_pwritev(mdbx_filehandle_t fd, struct iovec *iov, int iovcnt, int mdbx_pread(mdbx_filehandle_t fd, void *buf, size_t count, uint64_t offset); int mdbx_pwrite(mdbx_filehandle_t fd, const void *buf, size_t count, uint64_t offset); -int mdbx_write(mdbx_filehandle_t fd, const void *buf, size_t count); int mdbx_thread_create(mdbx_thread_t *thread, THREAD_RESULT(THREAD_CALL *start_routine)(void *),