mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: fix meta-invalidate race in MDBX_WRITEMAP mode (when target == head).
This commit is contained in:
parent
f4d3b76f81
commit
4293840055
50
src/mdbx.c
50
src/mdbx.c
@ -3508,27 +3508,49 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
||||
|
||||
const size_t offset = (char *)target - env->me_map;
|
||||
mdbx_assert(env, ((env->me_flags ^ flags) & MDBX_WRITEMAP) == 0);
|
||||
mdbx_ensure(env, target == head || target->mm_txnid < pending->mm_txnid);
|
||||
if (env->me_flags & MDBX_WRITEMAP) {
|
||||
/* LY: 'invalidate' the meta. */
|
||||
mdbx_jitter4testing(true);
|
||||
if (target->mm_datasync_sign != MDBX_DATASIGN_WEAK ||
|
||||
target->mm_txnid != pending->mm_txnid) {
|
||||
if (likely(target != head)) {
|
||||
#ifdef NDEBUG
|
||||
/* nodebug: 'invalidate' the meta to avoid false-reading
|
||||
* from violators (make safer) */
|
||||
target->mm_datasync_sign = MDBX_DATASIGN_WEAK;
|
||||
mdbx_jitter4testing(true);
|
||||
target->mm_txnid = 0;
|
||||
mdbx_coherent_barrier();
|
||||
#else
|
||||
/* debug: provoke failure to catch a violators */
|
||||
memset(target->mm_dbs, 0xCC,
|
||||
sizeof(target->mm_dbs) + sizeof(target->mm_canary));
|
||||
mdbx_jitter4testing(false);
|
||||
#endif
|
||||
|
||||
/* LY: update info */
|
||||
target->mm_mapsize = pending->mm_mapsize;
|
||||
target->mm_dbs[FREE_DBI] = pending->mm_dbs[FREE_DBI];
|
||||
target->mm_dbs[MAIN_DBI] = pending->mm_dbs[MAIN_DBI];
|
||||
target->mm_canary = pending->mm_canary;
|
||||
target->mm_last_pg = pending->mm_last_pg;
|
||||
mdbx_jitter4testing(true);
|
||||
mdbx_coherent_barrier();
|
||||
|
||||
/* LY: 'commit' the meta */
|
||||
target->mm_txnid = pending->mm_txnid;
|
||||
mdbx_jitter4testing(true);
|
||||
} else {
|
||||
/* dangerous case (target == head), only mm_datasync_sign could
|
||||
* me updated, check assertions once again */
|
||||
mdbx_ensure(env, head->mm_txnid == pending->mm_txnid &&
|
||||
!META_IS_STEADY(head) && META_IS_STEADY(pending));
|
||||
mdbx_ensure(env, head->mm_last_pg == pending->mm_last_pg);
|
||||
mdbx_ensure(env, head->mm_mapsize == pending->mm_mapsize);
|
||||
mdbx_ensure(env, memcmp(&head->mm_dbs, &pending->mm_dbs,
|
||||
sizeof(head->mm_dbs)) == 0);
|
||||
mdbx_ensure(env, memcmp(&head->mm_canary, &pending->mm_canary,
|
||||
sizeof(head->mm_canary)) == 0);
|
||||
}
|
||||
/* LY: update info */
|
||||
target->mm_mapsize = pending->mm_mapsize;
|
||||
target->mm_dbs[FREE_DBI] = pending->mm_dbs[FREE_DBI];
|
||||
target->mm_dbs[MAIN_DBI] = pending->mm_dbs[MAIN_DBI];
|
||||
target->mm_last_pg = pending->mm_last_pg;
|
||||
target->mm_canary = pending->mm_canary;
|
||||
/* LY: 'commit' the meta */
|
||||
mdbx_jitter4testing(true);
|
||||
target->mm_txnid = pending->mm_txnid;
|
||||
mdbx_jitter4testing(true);
|
||||
target->mm_datasync_sign = pending->mm_datasync_sign;
|
||||
mdbx_coherent_barrier();
|
||||
mdbx_jitter4testing(true);
|
||||
} else {
|
||||
pending->mm_magic = MDBX_MAGIC;
|
||||
|
Loading…
Reference in New Issue
Block a user