mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:54:13 +08:00
mdbx: rework allowing open large DB from a 32-bit environment.
Change-Id: Id7d9e2041158d0715496b852a5ddb297bde1495e
This commit is contained in:
parent
915830d0d3
commit
5acf93c54d
59
src/mdbx.c
59
src/mdbx.c
@ -3958,6 +3958,24 @@ static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *meta) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* LY: check end_pgno */
|
||||||
|
if (page.mp_meta.mm_geo.now < page.mp_meta.mm_geo.lower ||
|
||||||
|
page.mp_meta.mm_geo.now > page.mp_meta.mm_geo.upper) {
|
||||||
|
mdbx_notice("meta[%u] has invalid end-pageno (%" PRIaPGNO "), skip it",
|
||||||
|
meta_number, page.mp_meta.mm_geo.now);
|
||||||
|
rc = MDBX_CORRUPTED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LY: check last_pgno */
|
||||||
|
if (page.mp_meta.mm_geo.next < MIN_PAGENO ||
|
||||||
|
page.mp_meta.mm_geo.next - 1 > MAX_PAGENO) {
|
||||||
|
mdbx_notice("meta[%u] has invalid next-pageno (%" PRIaPGNO "), skip it",
|
||||||
|
meta_number, page.mp_meta.mm_geo.next);
|
||||||
|
rc = MDBX_CORRUPTED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* LY: check mapsize limits */
|
/* LY: check mapsize limits */
|
||||||
const uint64_t mapsize_min =
|
const uint64_t mapsize_min =
|
||||||
page.mp_meta.mm_geo.lower * (uint64_t)page.mp_meta.mm_psize;
|
page.mp_meta.mm_geo.lower * (uint64_t)page.mp_meta.mm_psize;
|
||||||
@ -3976,28 +3994,23 @@ static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *meta) {
|
|||||||
if (mapsize_max > MAX_MAPSIZE ||
|
if (mapsize_max > MAX_MAPSIZE ||
|
||||||
MAX_PAGENO < mdbx_roundup2((size_t)mapsize_max, env->me_os_psize) /
|
MAX_PAGENO < mdbx_roundup2((size_t)mapsize_max, env->me_os_psize) /
|
||||||
(uint64_t)page.mp_meta.mm_psize) {
|
(uint64_t)page.mp_meta.mm_psize) {
|
||||||
mdbx_notice("meta[%u] has too large max-mapsize (%" PRIu64 "), skip it",
|
const uint64_t used_bytes =
|
||||||
meta_number, mapsize_max);
|
page.mp_meta.mm_geo.next * (uint64_t)page.mp_meta.mm_psize;
|
||||||
rc = MDBX_TOO_LARGE;
|
if (page.mp_meta.mm_geo.next - 1 > MAX_PAGENO ||
|
||||||
continue;
|
used_bytes > MAX_MAPSIZE) {
|
||||||
}
|
mdbx_notice("meta[%u] has too large max-mapsize (%" PRIu64 "), skip it",
|
||||||
|
meta_number, mapsize_max);
|
||||||
|
rc = MDBX_TOO_LARGE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* LY: check end_pgno */
|
/* allow to open large DB from a 32-bit environment */
|
||||||
if (page.mp_meta.mm_geo.now < page.mp_meta.mm_geo.lower ||
|
mdbx_notice("meta[%u] has too large max-mapsize (%" PRIu64 "), "
|
||||||
page.mp_meta.mm_geo.now > page.mp_meta.mm_geo.upper) {
|
"but size of used space still acceptable (%" PRIu64 ")",
|
||||||
mdbx_notice("meta[%u] has invalid end-pageno (%" PRIaPGNO "), skip it",
|
meta_number, mapsize_max, used_bytes);
|
||||||
meta_number, page.mp_meta.mm_geo.now);
|
page.mp_meta.mm_geo.upper = (pgno_t)(MAX_MAPSIZE / page.mp_meta.mm_psize);
|
||||||
rc = MDBX_CORRUPTED;
|
if (page.mp_meta.mm_geo.now > page.mp_meta.mm_geo.upper)
|
||||||
continue;
|
page.mp_meta.mm_geo.now = page.mp_meta.mm_geo.upper;
|
||||||
}
|
|
||||||
|
|
||||||
/* LY: check last_pgno */
|
|
||||||
if (page.mp_meta.mm_geo.next < MIN_PAGENO ||
|
|
||||||
page.mp_meta.mm_geo.next - 1 > MAX_PAGENO) {
|
|
||||||
mdbx_notice("meta[%u] has invalid next-pageno (%" PRIaPGNO "), skip it",
|
|
||||||
meta_number, page.mp_meta.mm_geo.next);
|
|
||||||
rc = MDBX_CORRUPTED;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page.mp_meta.mm_geo.next > page.mp_meta.mm_geo.now) {
|
if (page.mp_meta.mm_geo.next > page.mp_meta.mm_geo.now) {
|
||||||
@ -4911,10 +4924,6 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, int lck_rc) {
|
|||||||
env->me_dbgeo.upper = pgno2bytes(env, meta.mm_geo.upper);
|
env->me_dbgeo.upper = pgno2bytes(env, meta.mm_geo.upper);
|
||||||
env->me_dbgeo.grow = pgno2bytes(env, meta.mm_geo.grow);
|
env->me_dbgeo.grow = pgno2bytes(env, meta.mm_geo.grow);
|
||||||
env->me_dbgeo.shrink = pgno2bytes(env, meta.mm_geo.shrink);
|
env->me_dbgeo.shrink = pgno2bytes(env, meta.mm_geo.shrink);
|
||||||
|
|
||||||
/* allowing open large DB from a 32-bit environment */
|
|
||||||
if (env->me_dbgeo.upper > MAX_MAPSIZE && used_bytes < MAX_MAPSIZE)
|
|
||||||
env->me_dbgeo.upper = MAX_MAPSIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t filesize_before_mmap;
|
uint64_t filesize_before_mmap;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user