mdbx: more for opening large DB from 32-bit env.

- return `MDBX_TOO_LARGE` only when used part of DB is too large for current platform;
- auto lowering both of `mm_geo.lower` and `mm_geo.upper` if the used part of DB is acceptable for current platform;

Change-Id: If67109ebb96063451c50f279c473ed38355a098a
This commit is contained in:
Leonid Yuriev 2020-09-18 13:34:34 +03:00
parent e2216f70f5
commit 488a272f8b

View File

@ -8409,15 +8409,30 @@ static int __cold mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
return MDBX_CORRUPTED;
}
}
if (meta->mm_geo.next - 1 > MAX_PAGENO || used_bytes > MAX_MAPSIZE) {
mdbx_warning("meta[%u] has too large used-space (%" PRIu64 "), skip it",
meta_number, used_bytes);
return MDBX_TOO_LARGE;
}
/* LY: check mapsize limits */
const uint64_t mapsize_min = meta->mm_geo.lower * (uint64_t)meta->mm_psize;
STATIC_ASSERT(MAX_MAPSIZE < PTRDIFF_MAX - MAX_PAGESIZE);
STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE);
if (mapsize_min < MIN_MAPSIZE || mapsize_min > MAX_MAPSIZE) {
mdbx_warning("meta[%u] has invalid min-mapsize (%" PRIu64 "), skip it",
meta_number, mapsize_min);
return MDBX_VERSION_MISMATCH;
if (MAX_MAPSIZE != MAX_MAPSIZE64 && mapsize_min > MAX_MAPSIZE &&
mapsize_min <= MAX_MAPSIZE64) {
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
used_bytes <= MAX_MAPSIZE);
mdbx_warning("meta[%u] has too large min-mapsize (%" PRIu64 "), "
"but size of used space still acceptable (%" PRIu64 ")",
meta_number, mapsize_min, used_bytes);
meta->mm_geo.lower = (pgno_t)(MAX_MAPSIZE / meta->mm_psize);
} else {
mdbx_warning("meta[%u] has invalid min-mapsize (%" PRIu64 "), skip it",
meta_number, mapsize_min);
return MDBX_VERSION_MISMATCH;
}
}
const uint64_t mapsize_max = meta->mm_geo.upper * (uint64_t)meta->mm_psize;
@ -8425,13 +8440,9 @@ static int __cold mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
if (mapsize_max > MAX_MAPSIZE ||
MAX_PAGENO < ceil_powerof2((size_t)mapsize_max, env->me_os_psize) /
(size_t)meta->mm_psize) {
if (meta->mm_geo.next - 1 > MAX_PAGENO || used_bytes > MAX_MAPSIZE) {
mdbx_warning("meta[%u] has too large max-mapsize (%" PRIu64 "), skip it",
meta_number, mapsize_max);
return MDBX_TOO_LARGE;
}
/* allow to open large DB from a 32-bit environment */
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
used_bytes <= MAX_MAPSIZE);
mdbx_warning("meta[%u] has too large max-mapsize (%" PRIu64 "), "
"but size of used space still acceptable (%" PRIu64 ")",
meta_number, mapsize_max, used_bytes);