mdbx: использование fcntl64(F_GETLK64/F_SETLK64/F_SETLKW64) при наличии.

Это решает проблему срабатывания проверочного утверждения при сборке для
платформ где тип off_t шире соответствующих полей структуры flock,
используемой для блокировки файлов.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-10-12 20:47:22 +03:00
parent 5a45c4a210
commit d94e65b870
4 changed files with 62 additions and 31 deletions

View File

@ -20536,14 +20536,13 @@ LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest_path,
/* no locking required since the file opened with ShareMode == 0 */ /* no locking required since the file opened with ShareMode == 0 */
#else #else
if (rc == MDBX_SUCCESS) { if (rc == MDBX_SUCCESS) {
struct flock lock_op; MDBX_STRUCT_FLOCK lock_op;
memset(&lock_op, 0, sizeof(lock_op)); memset(&lock_op, 0, sizeof(lock_op));
lock_op.l_type = F_WRLCK; lock_op.l_type = F_WRLCK;
lock_op.l_whence = SEEK_SET; lock_op.l_whence = SEEK_SET;
lock_op.l_start = 0; lock_op.l_start = 0;
lock_op.l_len = lock_op.l_len = OFF_T_MAX;
(sizeof(lock_op.l_len) > 4 ? INT64_MAX : INT32_MAX) & ~(size_t)0xffff; if (MDBX_FCNTL(newfd, MDBX_F_SETLK, &lock_op)
if (fcntl(newfd, F_SETLK, &lock_op)
#if (defined(__linux__) || defined(__gnu_linux__)) && defined(LOCK_EX) && \ #if (defined(__linux__) || defined(__gnu_linux__)) && defined(LOCK_EX) && \
(!defined(__ANDROID_API__) || __ANDROID_API__ >= 24) (!defined(__ANDROID_API__) || __ANDROID_API__ >= 24)
|| flock(newfd, LOCK_EX | LOCK_NB) || flock(newfd, LOCK_EX | LOCK_NB)

View File

@ -178,26 +178,21 @@ __cold static void choice_fcntl(void) {
of reliability reasons */ of reliability reasons */
#endif /* linux */ #endif /* linux */
) { ) {
op_setlk = F_OFD_SETLK; op_setlk = MDBX_F_OFD_SETLK;
op_setlkw = F_OFD_SETLKW; op_setlkw = MDBX_F_OFD_SETLKW;
op_getlk = F_OFD_GETLK; op_getlk = MDBX_F_OFD_GETLK;
return; return;
} }
op_setlk = F_SETLK; op_setlk = MDBX_F_SETLK;
op_setlkw = F_SETLKW; op_setlkw = MDBX_F_SETLKW;
op_getlk = F_GETLK; op_getlk = MDBX_F_GETLK;
} }
#else #else
#define op_setlk F_SETLK #define op_setlk MDBX_F_SETLK
#define op_setlkw F_SETLKW #define op_setlkw MDBX_F_SETLKW
#define op_getlk F_GETLK #define op_getlk MDBX_F_GETLK
#endif /* MDBX_USE_OFDLOCKS */ #endif /* MDBX_USE_OFDLOCKS */
#ifndef OFF_T_MAX
#define OFF_T_MAX \
(((sizeof(off_t) > 4) ? INT64_MAX : INT32_MAX) & ~(size_t)0xffff)
#endif
static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck, static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
const off_t offset, off_t len) { const off_t offset, off_t len) {
STATIC_ASSERT(sizeof(off_t) >= sizeof(void *) && STATIC_ASSERT(sizeof(off_t) >= sizeof(void *) &&
@ -220,7 +215,7 @@ static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
assert((uint64_t)((off_t)((uint64_t)offset + (uint64_t)len)) == assert((uint64_t)((off_t)((uint64_t)offset + (uint64_t)len)) ==
((uint64_t)offset + (uint64_t)len)); ((uint64_t)offset + (uint64_t)len));
for (;;) { for (;;) {
struct flock lock_op; MDBX_STRUCT_FLOCK lock_op;
STATIC_ASSERT_MSG(sizeof(off_t) <= sizeof(lock_op.l_start) && STATIC_ASSERT_MSG(sizeof(off_t) <= sizeof(lock_op.l_start) &&
sizeof(off_t) <= sizeof(lock_op.l_len) && sizeof(off_t) <= sizeof(lock_op.l_len) &&
OFF_T_MAX == (off_t)OFF_T_MAX, OFF_T_MAX == (off_t)OFF_T_MAX,
@ -232,7 +227,7 @@ static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
lock_op.l_whence = SEEK_SET; lock_op.l_whence = SEEK_SET;
lock_op.l_start = offset; lock_op.l_start = offset;
lock_op.l_len = len; lock_op.l_len = len;
int rc = fcntl(fd, cmd, &lock_op); int rc = MDBX_FCNTL(fd, cmd, &lock_op);
jitter4testing(true); jitter4testing(true);
if (rc != -1) { if (rc != -1) {
if (cmd == op_getlk) { if (cmd == op_getlk) {
@ -246,18 +241,18 @@ static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
} }
rc = errno; rc = errno;
#if MDBX_USE_OFDLOCKS #if MDBX_USE_OFDLOCKS
if (rc == EINVAL && if (rc == EINVAL && (cmd == MDBX_F_OFD_SETLK || cmd == MDBX_F_OFD_SETLKW ||
(cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK)) { cmd == MDBX_F_OFD_GETLK)) {
/* fallback to non-OFD locks */ /* fallback to non-OFD locks */
if (cmd == F_OFD_SETLK) if (cmd == MDBX_F_OFD_SETLK)
cmd = F_SETLK; cmd = MDBX_F_SETLK;
else if (cmd == F_OFD_SETLKW) else if (cmd == MDBX_F_OFD_SETLKW)
cmd = F_SETLKW; cmd = MDBX_F_SETLKW;
else else
cmd = F_GETLK; cmd = MDBX_F_GETLK;
op_setlk = F_SETLK; op_setlk = MDBX_F_SETLK;
op_setlkw = F_SETLKW; op_setlkw = MDBX_F_SETLKW;
op_getlk = F_GETLK; op_getlk = MDBX_F_GETLK;
continue; continue;
} }
#endif /* MDBX_USE_OFDLOCKS */ #endif /* MDBX_USE_OFDLOCKS */

View File

@ -269,7 +269,10 @@
/** Advanced: Using POSIX OFD-locks (autodetection by default). */ /** Advanced: Using POSIX OFD-locks (autodetection by default). */
#ifndef MDBX_USE_OFDLOCKS #ifndef MDBX_USE_OFDLOCKS
#if defined(F_OFD_SETLK) && defined(F_OFD_SETLKW) && defined(F_OFD_GETLK) && \ #if ((defined(F_OFD_SETLK) && defined(F_OFD_SETLKW) && \
defined(F_OFD_GETLK)) || \
(defined(F_OFD_SETLK64) && defined(F_OFD_SETLKW64) && \
defined(F_OFD_GETLK64))) && \
!defined(MDBX_SAFE4QEMU) && \ !defined(MDBX_SAFE4QEMU) && \
!defined(__sun) /* OFD-lock are broken on Solaris */ !defined(__sun) /* OFD-lock are broken on Solaris */
#define MDBX_USE_OFDLOCKS 1 #define MDBX_USE_OFDLOCKS 1

View File

@ -425,6 +425,40 @@ MDBX_MAYBE_UNUSED static __inline void jitter4testing(bool tiny);
#define MAX_WRITE UINT32_C(0x04000000) #define MAX_WRITE UINT32_C(0x04000000)
#else #else
#define MAX_WRITE UINT32_C(0x3f000000) #define MAX_WRITE UINT32_C(0x3f000000)
#if defined(F_GETLK64) && defined(F_SETLK64) && defined(F_SETLKW64) && \
!defined(__ANDROID_API__)
#define MDBX_F_SETLK F_SETLK64
#define MDBX_F_SETLKW F_SETLKW64
#define MDBX_F_GETLK F_GETLK64
#define MDBX_FCNTL fcntl64
#define MDBX_STRUCT_FLOCK struct flock64
#ifndef OFF_T_MAX
#define OFF_T_MAX UINT64_C(0x7fffFFFFfff00000)
#endif /* OFF_T_MAX */
#else
#define MDBX_F_SETLK F_SETLK
#define MDBX_F_SETLKW F_SETLKW
#define MDBX_F_GETLK F_GETLK
#define MDBX_FCNTL fcntl
#define MDBX_STRUCT_FLOCK struct flock
#endif /* MDBX_F_SETLK, MDBX_F_SETLKW, MDBX_F_GETLK */
#if defined(F_OFD_SETLK64) && defined(F_OFD_SETLKW64) && \
defined(F_OFD_GETLK64) && !defined(__ANDROID_API__)
#define MDBX_F_OFD_SETLK F_OFD_SETLK64
#define MDBX_F_OFD_SETLKW F_OFD_SETLKW64
#define MDBX_F_OFD_GETLK F_OFD_GETLK64
#else
#define MDBX_F_OFD_SETLK F_OFD_SETLK
#define MDBX_F_OFD_SETLKW F_OFD_SETLKW
#define MDBX_F_OFD_GETLK F_OFD_GETLK
#ifndef OFF_T_MAX
#define OFF_T_MAX \
(((sizeof(off_t) > 4) ? INT64_MAX : INT32_MAX) & ~(size_t)0xFffff)
#endif /* OFF_T_MAX */
#endif /* MDBX_F_OFD_SETLK64, MDBX_F_OFD_SETLKW64, MDBX_F_OFD_GETLK64 */
#endif #endif
#if defined(__linux__) || defined(__gnu_linux__) #if defined(__linux__) || defined(__gnu_linux__)