mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx: using fcntl64(F_GETLK64/F_SETLK64/F_SETLKW64)
when available (backport).
This fixes issues (static assertion failure, etc) on platforms where the `off_t` type is wider than corresponding fields of `struct flock`.
This commit is contained in:
parent
50e9e0e561
commit
db9e2c6f07
@ -19857,14 +19857,13 @@ __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
|
||||
/* no locking required since the file opened with ShareMode == 0 */
|
||||
#else
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
struct flock lock_op;
|
||||
MDBX_STRUCT_FLOCK lock_op;
|
||||
memset(&lock_op, 0, sizeof(lock_op));
|
||||
lock_op.l_type = F_WRLCK;
|
||||
lock_op.l_whence = SEEK_SET;
|
||||
lock_op.l_start = 0;
|
||||
lock_op.l_len =
|
||||
(sizeof(lock_op.l_len) > 4 ? INT64_MAX : INT32_MAX) & ~(size_t)0xffff;
|
||||
if (fcntl(newfd, F_SETLK, &lock_op)
|
||||
lock_op.l_len = OFF_T_MAX;
|
||||
if (MDBX_FCNTL(newfd, MDBX_F_SETLK, &lock_op)
|
||||
#if (defined(__linux__) || defined(__gnu_linux__)) && defined(LOCK_EX) && \
|
||||
(!defined(__ANDROID_API__) || __ANDROID_API__ >= 24)
|
||||
|| flock(newfd, LOCK_EX | LOCK_NB)
|
||||
|
@ -158,26 +158,21 @@ __cold static void choice_fcntl(void) {
|
||||
of reliability reasons */
|
||||
#endif /* linux */
|
||||
) {
|
||||
op_setlk = F_OFD_SETLK;
|
||||
op_setlkw = F_OFD_SETLKW;
|
||||
op_getlk = F_OFD_GETLK;
|
||||
op_setlk = MDBX_F_OFD_SETLK;
|
||||
op_setlkw = MDBX_F_OFD_SETLKW;
|
||||
op_getlk = MDBX_F_OFD_GETLK;
|
||||
return;
|
||||
}
|
||||
op_setlk = F_SETLK;
|
||||
op_setlkw = F_SETLKW;
|
||||
op_getlk = F_GETLK;
|
||||
op_setlk = MDBX_F_SETLK;
|
||||
op_setlkw = MDBX_F_SETLKW;
|
||||
op_getlk = MDBX_F_GETLK;
|
||||
}
|
||||
#else
|
||||
#define op_setlk F_SETLK
|
||||
#define op_setlkw F_SETLKW
|
||||
#define op_getlk F_GETLK
|
||||
#define op_setlk MDBX_F_SETLK
|
||||
#define op_setlkw MDBX_F_SETLKW
|
||||
#define op_getlk MDBX_F_GETLK
|
||||
#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,
|
||||
const off_t offset, off_t len) {
|
||||
STATIC_ASSERT(sizeof(off_t) >= sizeof(void *) &&
|
||||
@ -200,7 +195,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)) ==
|
||||
((uint64_t)offset + (uint64_t)len));
|
||||
for (;;) {
|
||||
struct flock lock_op;
|
||||
MDBX_STRUCT_FLOCK lock_op;
|
||||
STATIC_ASSERT_MSG(sizeof(off_t) <= sizeof(lock_op.l_start) &&
|
||||
sizeof(off_t) <= sizeof(lock_op.l_len) &&
|
||||
OFF_T_MAX == (off_t)OFF_T_MAX,
|
||||
@ -212,7 +207,7 @@ static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
|
||||
lock_op.l_whence = SEEK_SET;
|
||||
lock_op.l_start = offset;
|
||||
lock_op.l_len = len;
|
||||
int rc = fcntl(fd, cmd, &lock_op);
|
||||
int rc = MDBX_FCNTL(fd, cmd, &lock_op);
|
||||
mdbx_jitter4testing(true);
|
||||
if (rc != -1) {
|
||||
if (cmd == op_getlk) {
|
||||
@ -226,18 +221,18 @@ static int lck_op(const mdbx_filehandle_t fd, int cmd, const int lck,
|
||||
}
|
||||
rc = errno;
|
||||
#if MDBX_USE_OFDLOCKS
|
||||
if (rc == EINVAL &&
|
||||
(cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK)) {
|
||||
if (rc == EINVAL && (cmd == MDBX_F_OFD_SETLK || cmd == MDBX_F_OFD_SETLKW ||
|
||||
cmd == MDBX_F_OFD_GETLK)) {
|
||||
/* fallback to non-OFD locks */
|
||||
if (cmd == F_OFD_SETLK)
|
||||
cmd = F_SETLK;
|
||||
else if (cmd == F_OFD_SETLKW)
|
||||
cmd = F_SETLKW;
|
||||
if (cmd == MDBX_F_OFD_SETLK)
|
||||
cmd = MDBX_F_SETLK;
|
||||
else if (cmd == MDBX_F_OFD_SETLKW)
|
||||
cmd = MDBX_F_SETLKW;
|
||||
else
|
||||
cmd = F_GETLK;
|
||||
op_setlk = F_SETLK;
|
||||
op_setlkw = F_SETLKW;
|
||||
op_getlk = F_GETLK;
|
||||
cmd = MDBX_F_GETLK;
|
||||
op_setlk = MDBX_F_SETLK;
|
||||
op_setlkw = MDBX_F_SETLKW;
|
||||
op_getlk = MDBX_F_GETLK;
|
||||
continue;
|
||||
}
|
||||
#endif /* MDBX_USE_OFDLOCKS */
|
||||
|
@ -237,7 +237,10 @@
|
||||
|
||||
/** Advanced: Using POSIX OFD-locks (autodetection by default). */
|
||||
#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(__sun) /* OFD-lock are broken on Solaris */
|
||||
#define MDBX_USE_OFDLOCKS 1
|
||||
|
36
src/osal.h
36
src/osal.h
@ -287,7 +287,41 @@ MDBX_MAYBE_UNUSED static __inline void mdbx_jitter4testing(bool tiny);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define MAX_WRITE UINT32_C(0x01000000)
|
||||
#else
|
||||
#define MAX_WRITE UINT32_C(0x3fff0000)
|
||||
#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
|
||||
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
|
Loading…
Reference in New Issue
Block a user