mdbx: fix operation for unusual small/large system page size.

More for https://github.com/erthink/libmdbx/issues/157

Change-Id: I4f2ed54b50653d0375538b82c48590d1037cd93b
This commit is contained in:
Leonid Yuriev
2021-01-29 21:19:58 +03:00
parent 6cfac546a1
commit f698f07ff9
6 changed files with 34 additions and 14 deletions

View File

@@ -346,10 +346,18 @@ __cold int mdbx_env_get_maxkeysize_ex(const MDBX_env *env,
return (int)mdbx_limits_keysize_max((intptr_t)env->me_psize, flags);
}
size_t mdbx_default_pagesize(void) {
size_t pagesize = mdbx_syspagesize();
mdbx_ensure(nullptr, is_powerof2(pagesize));
pagesize = (pagesize >= MIN_PAGESIZE) ? pagesize : MIN_PAGESIZE;
pagesize = (pagesize <= MAX_PAGESIZE) ? pagesize : MAX_PAGESIZE;
return pagesize;
}
__cold intptr_t mdbx_limits_keysize_max(intptr_t pagesize,
MDBX_db_flags_t flags) {
if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize();
pagesize = (intptr_t)mdbx_default_pagesize();
if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
pagesize > (intptr_t)MAX_PAGESIZE ||
!is_powerof2((size_t)pagesize)))
@@ -383,7 +391,7 @@ __cold int mdbx_env_get_maxvalsize_ex(const MDBX_env *env,
__cold intptr_t mdbx_limits_valsize_max(intptr_t pagesize,
MDBX_db_flags_t flags) {
if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize();
pagesize = (intptr_t)mdbx_default_pagesize();
if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
pagesize > (intptr_t)MAX_PAGESIZE ||
!is_powerof2((size_t)pagesize)))
@@ -10004,7 +10012,8 @@ __cold int mdbx_env_create(MDBX_env **penv) {
goto bailout;
}
env->me_os_psize = (unsigned)os_psize;
mdbx_setup_pagesize(env, env->me_os_psize);
mdbx_setup_pagesize(env, (env->me_os_psize < MAX_PAGESIZE) ? env->me_os_psize
: MAX_PAGESIZE);
rc = mdbx_fastmutex_init(&env->me_dbi_lock);
if (unlikely(rc != MDBX_SUCCESS))
@@ -10969,12 +10978,14 @@ static __cold int mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
const size_t maxreaders =
((size_t)size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader);
if (size > 65536 || maxreaders < 2 || maxreaders > MDBX_READERS_LIMIT) {
mdbx_error("lck-size too big (up to %" PRIuPTR " readers)", maxreaders);
if (maxreaders < 4) {
mdbx_error("lck-size too small (up to %" PRIuPTR " readers)", maxreaders);
err = MDBX_PROBLEM;
goto bailout;
}
env->me_maxreaders = (unsigned)maxreaders;
env->me_maxreaders = (maxreaders <= MDBX_READERS_LIMIT)
? (unsigned)maxreaders
: (unsigned)MDBX_READERS_LIMIT;
err = mdbx_mmap((env->me_flags & MDBX_EXCLUSIVE) | MDBX_WRITEMAP,
&env->me_lck_mmap, (size_t)size, (size_t)size,
@@ -11388,7 +11399,8 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
memset(&dummy_env, 0, sizeof(dummy_env));
dummy_env.me_flags =
(mode == MDBX_ENV_ENSURE_UNUSED) ? MDBX_EXCLUSIVE : MDBX_ENV_DEFAULTS;
dummy_env.me_psize = dummy_env.me_os_psize = (unsigned)mdbx_syspagesize();
dummy_env.me_os_psize = (unsigned)mdbx_syspagesize();
dummy_env.me_psize = (unsigned)mdbx_default_pagesize();
dummy_env.me_pathname = (char *)pathname;
MDBX_handle_env_pathname env_pathname;
@@ -20119,7 +20131,7 @@ __cold MDBX_NOTHROW_CONST_FUNCTION intptr_t mdbx_limits_pgsize_max(void) {
__cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {
if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize();
pagesize = (intptr_t)mdbx_default_pagesize();
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
pagesize > (intptr_t)MAX_PAGESIZE ||
!is_powerof2((size_t)pagesize)))
@@ -20130,7 +20142,7 @@ __cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {
__cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) {
if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize();
pagesize = (intptr_t)mdbx_default_pagesize();
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
pagesize > (intptr_t)MAX_PAGESIZE ||
!is_powerof2((size_t)pagesize)))
@@ -20144,7 +20156,7 @@ __cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) {
__cold intptr_t mdbx_limits_txnsize_max(intptr_t pagesize) {
if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize();
pagesize = (intptr_t)mdbx_default_pagesize();
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
pagesize > (intptr_t)MAX_PAGESIZE ||
!is_powerof2((size_t)pagesize)))

View File

@@ -628,7 +628,7 @@ typedef struct MDBX_lockinfo {
#if MDBX_WORDBITS >= 64
#define MAX_MAPSIZE MAX_MAPSIZE64
#define MDBX_READERS_LIMIT \
((65536 - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
((MAX_PAGESIZE - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
#define MDBX_PGL_LIMIT MAX_PAGENO
#else
#define MDBX_READERS_LIMIT 1024

View File

@@ -985,8 +985,6 @@ template class LIBMDBX_API_TYPE buffer<polymorphic_allocator>;
//------------------------------------------------------------------------------
size_t env::default_pagesize() noexcept { return ::mdbx_syspagesize(); }
static inline MDBX_env_flags_t mode2flags(env::mode mode) {
switch (mode) {
default: