mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:04:13 +08:00
mdbx: refine mdbx_validate_meta()
.
This commit is contained in:
parent
5ed50a4739
commit
fb67682a79
157
src/core.c
157
src/core.c
@ -10095,51 +10095,52 @@ fail:
|
|||||||
|
|
||||||
static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
||||||
const MDBX_page *const page,
|
const MDBX_page *const page,
|
||||||
const unsigned meta_number, MDBX_meta *dest,
|
const unsigned meta_number,
|
||||||
const unsigned guess_pagesize) {
|
unsigned *guess_pagesize) {
|
||||||
const uint64_t magic_and_version =
|
const uint64_t magic_and_version =
|
||||||
unaligned_peek_u64(4, &meta->mm_magic_and_version);
|
unaligned_peek_u64(4, &meta->mm_magic_and_version);
|
||||||
if (magic_and_version != MDBX_DATA_MAGIC &&
|
if (unlikely(magic_and_version != MDBX_DATA_MAGIC &&
|
||||||
magic_and_version != MDBX_DATA_MAGIC_DEVEL) {
|
magic_and_version != MDBX_DATA_MAGIC_DEVEL)) {
|
||||||
mdbx_error("meta[%u] has invalid magic/version %" PRIx64, meta_number,
|
mdbx_error("meta[%u] has invalid magic/version %" PRIx64, meta_number,
|
||||||
magic_and_version);
|
magic_and_version);
|
||||||
return ((magic_and_version >> 8) != MDBX_MAGIC) ? MDBX_INVALID
|
return ((magic_and_version >> 8) != MDBX_MAGIC) ? MDBX_INVALID
|
||||||
: MDBX_VERSION_MISMATCH;
|
: MDBX_VERSION_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page->mp_pgno != meta_number) {
|
if (unlikely(page->mp_pgno != meta_number)) {
|
||||||
mdbx_error("meta[%u] has invalid pageno %" PRIaPGNO, meta_number,
|
mdbx_error("meta[%u] has invalid pageno %" PRIaPGNO, meta_number,
|
||||||
page->mp_pgno);
|
page->mp_pgno);
|
||||||
return MDBX_INVALID;
|
return MDBX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page->mp_flags != P_META) {
|
if (unlikely(page->mp_flags != P_META)) {
|
||||||
mdbx_error("page #%u not a meta-page", meta_number);
|
mdbx_error("page #%u not a meta-page", meta_number);
|
||||||
return MDBX_INVALID;
|
return MDBX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check pagesize */
|
/* LY: check pagesize */
|
||||||
if (!is_powerof2(meta->mm_psize) || meta->mm_psize < MIN_PAGESIZE ||
|
if (unlikely(!is_powerof2(meta->mm_psize) || meta->mm_psize < MIN_PAGESIZE ||
|
||||||
meta->mm_psize > MAX_PAGESIZE) {
|
meta->mm_psize > MAX_PAGESIZE)) {
|
||||||
mdbx_warning("meta[%u] has invalid pagesize (%u), skip it", meta_number,
|
mdbx_warning("meta[%u] has invalid pagesize (%u), skip it", meta_number,
|
||||||
meta->mm_psize);
|
meta->mm_psize);
|
||||||
return is_powerof2(meta->mm_psize) ? MDBX_VERSION_MISMATCH : MDBX_INVALID;
|
return is_powerof2(meta->mm_psize) ? MDBX_VERSION_MISMATCH : MDBX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest && meta_number == 0 && guess_pagesize != meta->mm_psize) {
|
if (guess_pagesize && *guess_pagesize != meta->mm_psize) {
|
||||||
dest->mm_psize = meta->mm_psize;
|
*guess_pagesize = meta->mm_psize;
|
||||||
mdbx_verbose("meta[%u] took pagesize %u", meta_number, meta->mm_psize);
|
mdbx_verbose("meta[%u] took pagesize %u", meta_number, meta->mm_psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unaligned_peek_u64(4, &meta->mm_txnid_a) !=
|
const txnid_t txnid = unaligned_peek_u64(4, &meta->mm_txnid_a);
|
||||||
unaligned_peek_u64(4, &meta->mm_txnid_b)) {
|
if (unlikely(txnid != unaligned_peek_u64(4, &meta->mm_txnid_b))) {
|
||||||
mdbx_warning("meta[%u] not completely updated, skip it", meta_number);
|
mdbx_warning("meta[%u] not completely updated, skip it", meta_number);
|
||||||
return MDBX_RESULT_TRUE;
|
return MDBX_RESULT_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check signature as a checksum */
|
/* LY: check signature as a checksum */
|
||||||
if (META_IS_STEADY(meta) &&
|
if (META_IS_STEADY(meta) &&
|
||||||
unaligned_peek_u64(4, &meta->mm_datasync_sign) != mdbx_meta_sign(meta)) {
|
unlikely(unaligned_peek_u64(4, &meta->mm_datasync_sign) !=
|
||||||
|
mdbx_meta_sign(meta))) {
|
||||||
mdbx_warning("meta[%u] has invalid steady-checksum (0x%" PRIx64
|
mdbx_warning("meta[%u] has invalid steady-checksum (0x%" PRIx64
|
||||||
" != 0x%" PRIx64 "), skip it",
|
" != 0x%" PRIx64 "), skip it",
|
||||||
meta_number, unaligned_peek_u64(4, &meta->mm_datasync_sign),
|
meta_number, unaligned_peek_u64(4, &meta->mm_datasync_sign),
|
||||||
@ -10147,32 +10148,41 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
|||||||
return MDBX_RESULT_TRUE;
|
return MDBX_RESULT_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdbx_debug("read meta%" PRIaPGNO " = root %" PRIaPGNO "/%" PRIaPGNO
|
mdbx_debug("checking meta%" PRIaPGNO " = root %" PRIaPGNO "/%" PRIaPGNO
|
||||||
", geo %" PRIaPGNO "/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
", geo %" PRIaPGNO "/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
||||||
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||||
page->mp_pgno, meta->mm_dbs[MAIN_DBI].md_root,
|
page->mp_pgno, meta->mm_dbs[MAIN_DBI].md_root,
|
||||||
meta->mm_dbs[FREE_DBI].md_root, meta->mm_geo.lower,
|
meta->mm_dbs[FREE_DBI].md_root, meta->mm_geo.lower,
|
||||||
meta->mm_geo.next, meta->mm_geo.now, meta->mm_geo.upper,
|
meta->mm_geo.next, meta->mm_geo.now, meta->mm_geo.upper,
|
||||||
pv2pages(meta->mm_geo.grow_pv), pv2pages(meta->mm_geo.shrink_pv),
|
pv2pages(meta->mm_geo.grow_pv), pv2pages(meta->mm_geo.shrink_pv),
|
||||||
unaligned_peek_u64(4, meta->mm_txnid_a), mdbx_durable_str(meta));
|
txnid, mdbx_durable_str(meta));
|
||||||
|
|
||||||
|
if (unlikely(txnid < MIN_TXNID || txnid > MAX_TXNID)) {
|
||||||
|
mdbx_warning("meta[%u] has invalid txnid %" PRIaTXN ", skip it",
|
||||||
|
meta_number, txnid);
|
||||||
|
return MDBX_RESULT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* LY: check min-pages value */
|
/* LY: check min-pages value */
|
||||||
if (meta->mm_geo.lower < MIN_PAGENO || meta->mm_geo.lower > MAX_PAGENO) {
|
if (unlikely(meta->mm_geo.lower < MIN_PAGENO ||
|
||||||
|
meta->mm_geo.lower > MAX_PAGENO)) {
|
||||||
mdbx_warning("meta[%u] has invalid min-pages (%" PRIaPGNO "), skip it",
|
mdbx_warning("meta[%u] has invalid min-pages (%" PRIaPGNO "), skip it",
|
||||||
meta_number, meta->mm_geo.lower);
|
meta_number, meta->mm_geo.lower);
|
||||||
return MDBX_INVALID;
|
return MDBX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check max-pages value */
|
/* LY: check max-pages value */
|
||||||
if (meta->mm_geo.upper < MIN_PAGENO || meta->mm_geo.upper > MAX_PAGENO ||
|
if (unlikely(meta->mm_geo.upper < MIN_PAGENO ||
|
||||||
meta->mm_geo.upper < meta->mm_geo.lower) {
|
meta->mm_geo.upper > MAX_PAGENO ||
|
||||||
|
meta->mm_geo.upper < meta->mm_geo.lower)) {
|
||||||
mdbx_warning("meta[%u] has invalid max-pages (%" PRIaPGNO "), skip it",
|
mdbx_warning("meta[%u] has invalid max-pages (%" PRIaPGNO "), skip it",
|
||||||
meta_number, meta->mm_geo.upper);
|
meta_number, meta->mm_geo.upper);
|
||||||
return MDBX_INVALID;
|
return MDBX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check last_pgno */
|
/* LY: check last_pgno */
|
||||||
if (meta->mm_geo.next < MIN_PAGENO || meta->mm_geo.next - 1 > MAX_PAGENO) {
|
if (unlikely(meta->mm_geo.next < MIN_PAGENO ||
|
||||||
|
meta->mm_geo.next - 1 > MAX_PAGENO)) {
|
||||||
mdbx_warning("meta[%u] has invalid next-pageno (%" PRIaPGNO "), skip it",
|
mdbx_warning("meta[%u] has invalid next-pageno (%" PRIaPGNO "), skip it",
|
||||||
meta_number, meta->mm_geo.next);
|
meta_number, meta->mm_geo.next);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
@ -10192,17 +10202,19 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
|||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (meta->mm_geo.next - 1 > MAX_PAGENO || used_bytes > MAX_MAPSIZE) {
|
if (unlikely(meta->mm_geo.next - 1 > MAX_PAGENO ||
|
||||||
|
used_bytes > MAX_MAPSIZE)) {
|
||||||
mdbx_warning("meta[%u] has too large used-space (%" PRIu64 "), skip it",
|
mdbx_warning("meta[%u] has too large used-space (%" PRIu64 "), skip it",
|
||||||
meta_number, used_bytes);
|
meta_number, used_bytes);
|
||||||
return MDBX_TOO_LARGE;
|
return MDBX_TOO_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check mapsize limits */
|
/* LY: check mapsize limits */
|
||||||
const uint64_t mapsize_min = meta->mm_geo.lower * (uint64_t)meta->mm_psize;
|
pgno_t geo_lower = meta->mm_geo.lower;
|
||||||
|
uint64_t mapsize_min = geo_lower * (uint64_t)meta->mm_psize;
|
||||||
STATIC_ASSERT(MAX_MAPSIZE < PTRDIFF_MAX - MAX_PAGESIZE);
|
STATIC_ASSERT(MAX_MAPSIZE < PTRDIFF_MAX - MAX_PAGESIZE);
|
||||||
STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE);
|
STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE);
|
||||||
if (mapsize_min < MIN_MAPSIZE || mapsize_min > MAX_MAPSIZE) {
|
if (unlikely(mapsize_min < MIN_MAPSIZE || mapsize_min > MAX_MAPSIZE)) {
|
||||||
if (MAX_MAPSIZE != MAX_MAPSIZE64 && mapsize_min > MAX_MAPSIZE &&
|
if (MAX_MAPSIZE != MAX_MAPSIZE64 && mapsize_min > MAX_MAPSIZE &&
|
||||||
mapsize_min <= MAX_MAPSIZE64) {
|
mapsize_min <= MAX_MAPSIZE64) {
|
||||||
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
|
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
|
||||||
@ -10210,7 +10222,12 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
|||||||
mdbx_warning("meta[%u] has too large min-mapsize (%" PRIu64 "), "
|
mdbx_warning("meta[%u] has too large min-mapsize (%" PRIu64 "), "
|
||||||
"but size of used space still acceptable (%" PRIu64 ")",
|
"but size of used space still acceptable (%" PRIu64 ")",
|
||||||
meta_number, mapsize_min, used_bytes);
|
meta_number, mapsize_min, used_bytes);
|
||||||
meta->mm_geo.lower = (pgno_t)(MAX_MAPSIZE / meta->mm_psize);
|
geo_lower = (pgno_t)(mapsize_min = MAX_MAPSIZE / meta->mm_psize);
|
||||||
|
mdbx_warning("meta[%u] consider get-%s pageno is %" PRIaPGNO
|
||||||
|
" instead of wrong %" PRIaPGNO
|
||||||
|
", will be corrected on next commit(s)",
|
||||||
|
meta_number, "lower", geo_lower, meta->mm_geo.lower);
|
||||||
|
meta->mm_geo.lower = geo_lower;
|
||||||
} else {
|
} else {
|
||||||
mdbx_warning("meta[%u] has invalid min-mapsize (%" PRIu64 "), skip it",
|
mdbx_warning("meta[%u] has invalid min-mapsize (%" PRIu64 "), skip it",
|
||||||
meta_number, mapsize_min);
|
meta_number, mapsize_min);
|
||||||
@ -10218,18 +10235,30 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t mapsize_max = meta->mm_geo.upper * (uint64_t)meta->mm_psize;
|
pgno_t geo_upper = meta->mm_geo.upper;
|
||||||
|
uint64_t mapsize_max = geo_upper * (uint64_t)meta->mm_psize;
|
||||||
STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE);
|
STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE);
|
||||||
if (mapsize_max > MAX_MAPSIZE ||
|
if (unlikely(mapsize_max > MAX_MAPSIZE ||
|
||||||
MAX_PAGENO < ceil_powerof2((size_t)mapsize_max, env->me_os_psize) /
|
MAX_PAGENO <
|
||||||
(size_t)meta->mm_psize) {
|
ceil_powerof2((size_t)mapsize_max, env->me_os_psize) /
|
||||||
|
(size_t)meta->mm_psize)) {
|
||||||
|
if (mapsize_max > MAX_MAPSIZE64) {
|
||||||
|
mdbx_warning("meta[%u] has invalid max-mapsize (%" PRIu64 "), skip it",
|
||||||
|
meta_number, mapsize_max);
|
||||||
|
return MDBX_VERSION_MISMATCH;
|
||||||
|
}
|
||||||
/* allow to open large DB from a 32-bit environment */
|
/* allow to open large DB from a 32-bit environment */
|
||||||
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
|
mdbx_assert(env, meta->mm_geo.next - 1 <= MAX_PAGENO &&
|
||||||
used_bytes <= MAX_MAPSIZE);
|
used_bytes <= MAX_MAPSIZE);
|
||||||
mdbx_warning("meta[%u] has too large max-mapsize (%" PRIu64 "), "
|
mdbx_warning("meta[%u] has too large max-mapsize (%" PRIu64 "), "
|
||||||
"but size of used space still acceptable (%" PRIu64 ")",
|
"but size of used space still acceptable (%" PRIu64 ")",
|
||||||
meta_number, mapsize_max, used_bytes);
|
meta_number, mapsize_max, used_bytes);
|
||||||
meta->mm_geo.upper = (pgno_t)(MAX_MAPSIZE / meta->mm_psize);
|
geo_upper = (pgno_t)(mapsize_max = MAX_MAPSIZE / meta->mm_psize);
|
||||||
|
mdbx_warning("meta[%u] consider get-%s pageno is %" PRIaPGNO
|
||||||
|
" instead of wrong %" PRIaPGNO
|
||||||
|
", will be corrected on next commit(s)",
|
||||||
|
meta_number, "upper", geo_upper, meta->mm_geo.upper);
|
||||||
|
meta->mm_geo.upper = geo_upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: check and silently put mm_geo.now into [geo.lower...geo.upper].
|
/* LY: check and silently put mm_geo.now into [geo.lower...geo.upper].
|
||||||
@ -10239,54 +10268,58 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
|||||||
* at all. This is not a problem as there is no damage or loss of data.
|
* at all. This is not a problem as there is no damage or loss of data.
|
||||||
* Therefore it is better not to consider such situation as an error, but
|
* Therefore it is better not to consider such situation as an error, but
|
||||||
* silently correct it. */
|
* silently correct it. */
|
||||||
if (meta->mm_geo.now < meta->mm_geo.lower)
|
pgno_t geo_now = meta->mm_geo.now;
|
||||||
meta->mm_geo.now = meta->mm_geo.lower;
|
if (geo_now < geo_lower)
|
||||||
if (meta->mm_geo.now > meta->mm_geo.upper &&
|
geo_now = geo_lower;
|
||||||
meta->mm_geo.next <= meta->mm_geo.upper)
|
if (geo_now > geo_upper && meta->mm_geo.next <= geo_upper)
|
||||||
meta->mm_geo.now = meta->mm_geo.upper;
|
geo_now = geo_upper;
|
||||||
|
|
||||||
if (meta->mm_geo.next > meta->mm_geo.now) {
|
if (unlikely(meta->mm_geo.next > geo_now)) {
|
||||||
mdbx_warning("meta[%u] next-pageno (%" PRIaPGNO
|
mdbx_warning("meta[%u] next-pageno (%" PRIaPGNO
|
||||||
") is beyond end-pgno (%" PRIaPGNO "), skip it",
|
") is beyond end-pgno (%" PRIaPGNO "), skip it",
|
||||||
meta_number, meta->mm_geo.next, meta->mm_geo.now);
|
meta_number, meta->mm_geo.next, geo_now);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
if (meta->mm_geo.now != geo_now) {
|
||||||
|
mdbx_warning("meta[%u] consider geo-%s pageno is %" PRIaPGNO
|
||||||
|
" instead of wrong %" PRIaPGNO
|
||||||
|
", will be corrected on next commit(s)",
|
||||||
|
meta_number, "now", geo_now, meta->mm_geo.now);
|
||||||
|
meta->mm_geo.now = geo_now;
|
||||||
|
}
|
||||||
|
|
||||||
/* LY: GC root */
|
/* GC */
|
||||||
if (meta->mm_dbs[FREE_DBI].md_root == P_INVALID) {
|
if (meta->mm_dbs[FREE_DBI].md_root == P_INVALID) {
|
||||||
if (meta->mm_dbs[FREE_DBI].md_branch_pages ||
|
if (unlikely(meta->mm_dbs[FREE_DBI].md_branch_pages ||
|
||||||
meta->mm_dbs[FREE_DBI].md_depth || meta->mm_dbs[FREE_DBI].md_entries ||
|
meta->mm_dbs[FREE_DBI].md_depth ||
|
||||||
meta->mm_dbs[FREE_DBI].md_leaf_pages ||
|
meta->mm_dbs[FREE_DBI].md_entries ||
|
||||||
meta->mm_dbs[FREE_DBI].md_overflow_pages) {
|
meta->mm_dbs[FREE_DBI].md_leaf_pages ||
|
||||||
|
meta->mm_dbs[FREE_DBI].md_overflow_pages)) {
|
||||||
mdbx_warning("meta[%u] has false-empty GC, skip it", meta_number);
|
mdbx_warning("meta[%u] has false-empty GC, skip it", meta_number);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
} else if (meta->mm_dbs[FREE_DBI].md_root >= meta->mm_geo.next) {
|
} else if (unlikely(meta->mm_dbs[FREE_DBI].md_root >= meta->mm_geo.next)) {
|
||||||
mdbx_warning("meta[%u] has invalid GC-root %" PRIaPGNO ", skip it",
|
mdbx_warning("meta[%u] has invalid GC-root %" PRIaPGNO ", skip it",
|
||||||
meta_number, meta->mm_dbs[FREE_DBI].md_root);
|
meta_number, meta->mm_dbs[FREE_DBI].md_root);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: MainDB root */
|
/* MainDB */
|
||||||
if (meta->mm_dbs[MAIN_DBI].md_root == P_INVALID) {
|
if (meta->mm_dbs[MAIN_DBI].md_root == P_INVALID) {
|
||||||
if (meta->mm_dbs[MAIN_DBI].md_branch_pages ||
|
if (unlikely(meta->mm_dbs[MAIN_DBI].md_branch_pages ||
|
||||||
meta->mm_dbs[MAIN_DBI].md_depth || meta->mm_dbs[MAIN_DBI].md_entries ||
|
meta->mm_dbs[MAIN_DBI].md_depth ||
|
||||||
meta->mm_dbs[MAIN_DBI].md_leaf_pages ||
|
meta->mm_dbs[MAIN_DBI].md_entries ||
|
||||||
meta->mm_dbs[MAIN_DBI].md_overflow_pages) {
|
meta->mm_dbs[MAIN_DBI].md_leaf_pages ||
|
||||||
|
meta->mm_dbs[MAIN_DBI].md_overflow_pages)) {
|
||||||
mdbx_warning("meta[%u] has false-empty maindb", meta_number);
|
mdbx_warning("meta[%u] has false-empty maindb", meta_number);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
} else if (meta->mm_dbs[MAIN_DBI].md_root >= meta->mm_geo.next) {
|
} else if (unlikely(meta->mm_dbs[MAIN_DBI].md_root >= meta->mm_geo.next)) {
|
||||||
mdbx_warning("meta[%u] has invalid maindb-root %" PRIaPGNO ", skip it",
|
mdbx_warning("meta[%u] has invalid maindb-root %" PRIaPGNO ", skip it",
|
||||||
meta_number, meta->mm_dbs[MAIN_DBI].md_root);
|
meta_number, meta->mm_dbs[MAIN_DBI].md_root);
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unaligned_peek_u64(4, &meta->mm_txnid_a) == 0) {
|
|
||||||
mdbx_warning("meta[%u] has zero txnid, skip it", meta_number);
|
|
||||||
return MDBX_RESULT_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10305,16 +10338,15 @@ __cold static int mdbx_read_header(MDBX_env *env, MDBX_meta *dest,
|
|||||||
|
|
||||||
/* Read twice all meta pages so we can find the latest one. */
|
/* Read twice all meta pages so we can find the latest one. */
|
||||||
unsigned loop_limit = NUM_METAS * 2;
|
unsigned loop_limit = NUM_METAS * 2;
|
||||||
|
/* We don't know the page size on first time. So, just guess it. */
|
||||||
|
unsigned guess_pagesize = 0;
|
||||||
for (unsigned loop_count = 0; loop_count < loop_limit; ++loop_count) {
|
for (unsigned loop_count = 0; loop_count < loop_limit; ++loop_count) {
|
||||||
/* We don't know the page size on first time.
|
|
||||||
* So, just guess it. */
|
|
||||||
unsigned guess_pagesize = dest->mm_psize;
|
|
||||||
if (guess_pagesize == 0)
|
|
||||||
guess_pagesize =
|
|
||||||
(loop_count > NUM_METAS) ? env->me_psize : env->me_os_psize;
|
|
||||||
|
|
||||||
const unsigned meta_number = loop_count % NUM_METAS;
|
const unsigned meta_number = loop_count % NUM_METAS;
|
||||||
const unsigned offset = guess_pagesize * meta_number;
|
const unsigned offset =
|
||||||
|
(guess_pagesize
|
||||||
|
? guess_pagesize
|
||||||
|
: (loop_count > NUM_METAS) ? env->me_psize : env->me_os_psize) *
|
||||||
|
meta_number;
|
||||||
|
|
||||||
char buffer[MIN_PAGESIZE];
|
char buffer[MIN_PAGESIZE];
|
||||||
unsigned retryleft = 42;
|
unsigned retryleft = 42;
|
||||||
@ -10355,7 +10387,7 @@ __cold static int mdbx_read_header(MDBX_env *env, MDBX_meta *dest,
|
|||||||
|
|
||||||
MDBX_page *const page = (MDBX_page *)buffer;
|
MDBX_page *const page = (MDBX_page *)buffer;
|
||||||
MDBX_meta *const meta = page_meta(page);
|
MDBX_meta *const meta = page_meta(page);
|
||||||
rc = mdbx_validate_meta(env, meta, page, meta_number, dest, guess_pagesize);
|
rc = mdbx_validate_meta(env, meta, page, meta_number, &guess_pagesize);
|
||||||
if (rc != MDBX_SUCCESS)
|
if (rc != MDBX_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -11616,8 +11648,7 @@ __cold static int mdbx_setup_dxb(MDBX_env *env, const int lck_rc,
|
|||||||
MDBX_meta clone = *head;
|
MDBX_meta clone = *head;
|
||||||
err = mdbx_validate_meta(
|
err = mdbx_validate_meta(
|
||||||
env, &clone, data_page(head),
|
env, &clone, data_page(head),
|
||||||
bytes2pgno(env, (uint8_t *)data_page(head) - env->me_map), nullptr,
|
bytes2pgno(env, (uint8_t *)data_page(head) - env->me_map), nullptr);
|
||||||
env->me_psize);
|
|
||||||
if (err == MDBX_SUCCESS) {
|
if (err == MDBX_SUCCESS) {
|
||||||
mdbx_warning(
|
mdbx_warning(
|
||||||
"opening after an unclean shutdown, but boot-id(%016" PRIx64
|
"opening after an unclean shutdown, but boot-id(%016" PRIx64
|
||||||
|
Loading…
x
Reference in New Issue
Block a user