mirror of
https://gitflic.ru/project/erthink/libmdbx.git
synced 2025-01-24 17:16:06 +00:00
mdbx: доработка mdbx_close_dbi()
для возврата ошибки при попытке закрыть dbi-хендл измененной в транзакции таблицы (backport).
This commit is contained in:
parent
222150bb28
commit
945899e4fd
10
ChangeLog.md
10
ChangeLog.md
@ -20,6 +20,16 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
|
||||
изменения геометрии другим процессом с увеличением верхнего размера БД
|
||||
и увеличением БД больше предыдущего лимита.
|
||||
|
||||
- Доработка `mdbx_close_dbi()` для возврата ошибки при попытке закрыть
|
||||
dbi-дескриптор таблицы, созданной и/или измененной в ещё выполняющейся
|
||||
транзакции. Такое преждевременное закрытие дескриптора является неверным
|
||||
использованием API и нарушением контракта/предусловий сформулированных
|
||||
в описании `mdbx_close_dbi()`. Однако, вместо возврата ошибки
|
||||
выполнялось некорректное закрытие дескриптора, что могло приводить к
|
||||
созданию таблицы с пустым именем, утечки страниц БД и/или нарушению
|
||||
структуры b-tree (неверной ссылкой на корень таблицы).
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
26
src/core.c
26
src/core.c
@ -23134,9 +23134,29 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
|
||||
|
||||
rc = osal_fastmutex_acquire(&env->me_dbi_lock);
|
||||
if (likely(rc == MDBX_SUCCESS)) {
|
||||
rc = (dbi < env->me_maxdbs && (env->me_dbflags[dbi] & DB_VALID))
|
||||
? dbi_close_locked(env, dbi)
|
||||
: MDBX_BAD_DBI;
|
||||
retry:
|
||||
rc = MDBX_BAD_DBI;
|
||||
if (dbi < env->me_maxdbs && (env->me_dbflags[dbi] & DB_VALID)) {
|
||||
const MDBX_txn *const hazard = env->me_txn;
|
||||
osal_compiler_barrier();
|
||||
if (env->me_txn0 && (env->me_txn0->mt_flags & MDBX_TXN_FINISHED) == 0) {
|
||||
if (env->me_txn0->mt_dbistate[dbi] & (DBI_DIRTY | DBI_CREAT))
|
||||
goto bailout_dirty_dbi;
|
||||
osal_memory_barrier();
|
||||
if (unlikely(hazard != env->me_txn))
|
||||
goto retry;
|
||||
if (hazard != env->me_txn0 && hazard &&
|
||||
(hazard->mt_flags & MDBX_TXN_FINISHED) == 0 &&
|
||||
hazard->mt_signature == MDBX_MT_SIGNATURE &&
|
||||
(hazard->mt_dbistate[dbi] & (DBI_DIRTY | DBI_CREAT)))
|
||||
goto bailout_dirty_dbi;
|
||||
osal_compiler_barrier();
|
||||
if (unlikely(hazard != env->me_txn))
|
||||
goto retry;
|
||||
}
|
||||
rc = dbi_close_locked(env, dbi);
|
||||
}
|
||||
bailout_dirty_dbi:
|
||||
ENSURE(env, osal_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS);
|
||||
}
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user