mdbx: устранение регресса SIGSEGV при открытии БД с измененным размером страницы.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-07-12 11:40:47 +03:00
parent 2311706272
commit 32df0ad1eb
4 changed files with 18 additions and 17 deletions

View File

@ -530,12 +530,7 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
base + bitmap_bytes + base + bitmap_bytes +
env->max_dbi * (sizeof(txn->dbs[0]) + sizeof(txn->cursors[0]) + env->max_dbi * (sizeof(txn->dbs[0]) + sizeof(txn->cursors[0]) +
sizeof(txn->dbi_seqs[0]) + sizeof(txn->dbi_state[0])); sizeof(txn->dbi_seqs[0]) + sizeof(txn->dbi_state[0]));
rc = env_page_auxbuffer(env);
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
memset(env->page_auxbuf, -1, env->ps * (size_t)2);
memset(ptr_disp(env->page_auxbuf, env->ps * (size_t)2), 0, env->ps);
txn = osal_calloc(1, size); txn = osal_calloc(1, size);
if (unlikely(!txn)) { if (unlikely(!txn)) {
rc = MDBX_ENOMEM; rc = MDBX_ENOMEM;

View File

@ -641,6 +641,12 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc,
if (env->ps != header.pagesize) if (env->ps != header.pagesize)
env_setup_pagesize(env, header.pagesize); env_setup_pagesize(env, header.pagesize);
if ((env->flags & MDBX_RDONLY) == 0) {
err = env_page_auxbuffer(env);
if (unlikely(err != MDBX_SUCCESS))
return err;
}
const size_t used_bytes = pgno2bytes(env, header.geometry.first_unallocated); const size_t used_bytes = pgno2bytes(env, header.geometry.first_unallocated);
const size_t used_aligned2os_bytes = const size_t used_aligned2os_bytes =
ceil_powerof2(used_bytes, globals.sys_pagesize); ceil_powerof2(used_bytes, globals.sys_pagesize);

View File

@ -10,10 +10,16 @@ bool env_txn0_owned(const MDBX_env *env) {
} }
int env_page_auxbuffer(MDBX_env *env) { int env_page_auxbuffer(MDBX_env *env) {
return env->page_auxbuf ? MDBX_SUCCESS const int err =
: osal_memalign_alloc(globals.sys_pagesize, env->page_auxbuf
env->ps * (size_t)NUM_METAS, ? MDBX_SUCCESS
&env->page_auxbuf); : osal_memalign_alloc(globals.sys_pagesize,
env->ps * (size_t)NUM_METAS, &env->page_auxbuf);
if (likely(err == MDBX_SUCCESS)) {
memset(env->page_auxbuf, -1, env->ps * (size_t)2);
memset(ptr_disp(env->page_auxbuf, env->ps * (size_t)2), 0, env->ps);
}
return err;
} }
__cold unsigned env_setup_pagesize(MDBX_env *env, const size_t pagesize) { __cold unsigned env_setup_pagesize(MDBX_env *env, const size_t pagesize) {
@ -22,11 +28,8 @@ __cold unsigned env_setup_pagesize(MDBX_env *env, const size_t pagesize) {
ENSURE(env, is_powerof2(pagesize)); ENSURE(env, is_powerof2(pagesize));
ENSURE(env, pagesize >= MDBX_MIN_PAGESIZE); ENSURE(env, pagesize >= MDBX_MIN_PAGESIZE);
ENSURE(env, pagesize <= MDBX_MAX_PAGESIZE); ENSURE(env, pagesize <= MDBX_MAX_PAGESIZE);
ENSURE(env, !env->page_auxbuf && env->ps != pagesize);
env->ps = (unsigned)pagesize; env->ps = (unsigned)pagesize;
if (env->page_auxbuf) {
osal_memalign_free(env->page_auxbuf);
env->page_auxbuf = nullptr;
}
STATIC_ASSERT(MAX_GC1OVPAGE(MDBX_MIN_PAGESIZE) > 4); STATIC_ASSERT(MAX_GC1OVPAGE(MDBX_MIN_PAGESIZE) > 4);
STATIC_ASSERT(MAX_GC1OVPAGE(MDBX_MAX_PAGESIZE) < PAGELIST_LIMIT); STATIC_ASSERT(MAX_GC1OVPAGE(MDBX_MAX_PAGESIZE) < PAGELIST_LIMIT);

View File

@ -392,9 +392,6 @@ __cold meta_t *meta_init_triplet(const MDBX_env *env, void *buffer) {
__cold int __must_check_result meta_override(MDBX_env *env, size_t target, __cold int __must_check_result meta_override(MDBX_env *env, size_t target,
txnid_t txnid, txnid_t txnid,
const meta_t *shape) { const meta_t *shape) {
int rc = env_page_auxbuffer(env);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
page_t *const page = env->page_auxbuf; page_t *const page = env->page_auxbuf;
meta_model(env, page, target, meta_model(env, page, target,
&((target == 0 && shape) ? shape : METAPAGE(env, 0))->dxbid); &((target == 0 && shape) ? shape : METAPAGE(env, 0))->dxbid);
@ -440,7 +437,7 @@ __cold int __must_check_result meta_override(MDBX_env *env, size_t target,
} }
meta_sign_as_steady(model); meta_sign_as_steady(model);
rc = meta_validate(env, model, page, (pgno_t)target, nullptr); int rc = meta_validate(env, model, page, (pgno_t)target, nullptr);
if (unlikely(MDBX_IS_ERROR(rc))) if (unlikely(MDBX_IS_ERROR(rc)))
return MDBX_PROBLEM; return MDBX_PROBLEM;