From 488a272f8b6b2fe9e5ad0c7500aaf6da1658b7a9 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 18 Sep 2020 13:34:34 +0300 Subject: [PATCH] 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 --- src/core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/core.c b/src/core.c index cbb86554..57a5f32d 100644 --- a/src/core.c +++ b/src/core.c @@ -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);