mirror of
https://github.com/isar/libmdbx.git
synced 2025-02-03 08:40:50 +08:00
mdbx: add checking result from mid2l-functions.
Change-Id: I8c2b4110c335b5632e4c71d6b8304f3ab437696e
This commit is contained in:
parent
c472300b13
commit
bc45eb30fb
57
src/mdbx.c
57
src/mdbx.c
@ -896,45 +896,45 @@ static unsigned __hot mdbx_mid2l_search(MDBX_ID2L pnl, pgno_t id) {
|
|||||||
* [in,out] pnl The ID2L to insert into.
|
* [in,out] pnl The ID2L to insert into.
|
||||||
* [in] id The ID2 to insert.
|
* [in] id The ID2 to insert.
|
||||||
* Returns 0 on success, -1 if the ID was already present in the ID2L. */
|
* Returns 0 on success, -1 if the ID was already present in the ID2L. */
|
||||||
static int mdbx_mid2l_insert(MDBX_ID2L pnl, MDBX_ID2 *id) {
|
static int __must_check_result mdbx_mid2l_insert(MDBX_ID2L pnl, MDBX_ID2 *id) {
|
||||||
unsigned x = mdbx_mid2l_search(pnl, id->mid);
|
unsigned x = mdbx_mid2l_search(pnl, id->mid);
|
||||||
if (unlikely(x < 1))
|
if (unlikely(x < 1))
|
||||||
return /* internal error */ -2;
|
return /* internal error */ MDBX_PROBLEM;
|
||||||
|
|
||||||
if (x <= pnl[0].mid && pnl[x].mid == id->mid)
|
if (x <= pnl[0].mid && pnl[x].mid == id->mid)
|
||||||
return /* duplicate */ -1;
|
return /* duplicate */ MDBX_PROBLEM;
|
||||||
|
|
||||||
if (unlikely(pnl[0].mid >= MDBX_PNL_UM_MAX))
|
if (unlikely(pnl[0].mid >= MDBX_PNL_UM_MAX))
|
||||||
return /* too big */ -2;
|
return /* too big */ MDBX_TXN_FULL;
|
||||||
|
|
||||||
/* insert id */
|
/* insert id */
|
||||||
pnl[0].mid++;
|
pnl[0].mid++;
|
||||||
for (unsigned i = (unsigned)pnl[0].mid; i > x; i--)
|
for (unsigned i = (unsigned)pnl[0].mid; i > x; i--)
|
||||||
pnl[i] = pnl[i - 1];
|
pnl[i] = pnl[i - 1];
|
||||||
pnl[x] = *id;
|
pnl[x] = *id;
|
||||||
return 0;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append an ID2 into a ID2L.
|
/* Append an ID2 into a ID2L.
|
||||||
* [in,out] pnl The ID2L to append into.
|
* [in,out] pnl The ID2L to append into.
|
||||||
* [in] id The ID2 to append.
|
* [in] id The ID2 to append.
|
||||||
* Returns 0 on success, -2 if the ID2L is too big. */
|
* Returns 0 on success, -2 if the ID2L is too big. */
|
||||||
static int mdbx_mid2l_append(MDBX_ID2L pnl, MDBX_ID2 *id) {
|
static int __must_check_result mdbx_mid2l_append(MDBX_ID2L pnl, MDBX_ID2 *id) {
|
||||||
#if MDBX_DEBUG
|
#if MDBX_DEBUG
|
||||||
for (unsigned i = pnl[0].mid; i > 0; --i) {
|
for (unsigned i = pnl[0].mid; i > 0; --i) {
|
||||||
assert(pnl[i].mid != id->mid);
|
assert(pnl[i].mid != id->mid);
|
||||||
if (unlikely(pnl[i].mid == id->mid))
|
if (unlikely(pnl[i].mid == id->mid))
|
||||||
return -1;
|
return MDBX_PROBLEM;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Too big? */
|
/* Too big? */
|
||||||
if (unlikely(pnl[0].mid >= MDBX_PNL_UM_MAX))
|
if (unlikely(pnl[0].mid >= MDBX_PNL_UM_MAX))
|
||||||
return -2;
|
return /* too big */ MDBX_TXN_FULL;
|
||||||
|
|
||||||
pnl[0].mid++;
|
pnl[0].mid++;
|
||||||
pnl[pnl[0].mid] = *id;
|
pnl[pnl[0].mid] = *id;
|
||||||
return 0;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -1997,7 +1997,7 @@ static txnid_t mdbx_find_oldest(MDBX_txn *txn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add a page to the txn's dirty list */
|
/* Add a page to the txn's dirty list */
|
||||||
static void mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
||||||
MDBX_ID2 mid;
|
MDBX_ID2 mid;
|
||||||
int rc, (*insert)(MDBX_ID2L, MDBX_ID2 *);
|
int rc, (*insert)(MDBX_ID2L, MDBX_ID2 *);
|
||||||
|
|
||||||
@ -2009,8 +2009,12 @@ static void mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
|||||||
mid.mid = mp->mp_pgno;
|
mid.mid = mp->mp_pgno;
|
||||||
mid.mptr = mp;
|
mid.mptr = mp;
|
||||||
rc = insert(txn->mt_rw_dirtylist, &mid);
|
rc = insert(txn->mt_rw_dirtylist, &mid);
|
||||||
mdbx_tassert(txn, rc == 0);
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
txn->mt_flags |= MDBX_TXN_ERROR;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
txn->mt_dirtyroom--;
|
txn->mt_dirtyroom--;
|
||||||
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
|
static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
|
||||||
@ -2553,7 +2557,9 @@ done:
|
|||||||
np->mp_leaf2_ksize = 0;
|
np->mp_leaf2_ksize = 0;
|
||||||
np->mp_flags = 0;
|
np->mp_flags = 0;
|
||||||
np->mp_pages = num;
|
np->mp_pages = num;
|
||||||
mdbx_page_dirty(txn, np);
|
rc = mdbx_page_dirty(txn, np);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto fail;
|
||||||
*mp = np;
|
*mp = np;
|
||||||
|
|
||||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||||
@ -2591,7 +2597,8 @@ static void mdbx_page_copy(MDBX_page *dst, MDBX_page *src, unsigned psize) {
|
|||||||
* [in] mp the page being referenced. It must not be dirty.
|
* [in] mp the page being referenced. It must not be dirty.
|
||||||
* [out] ret the writable page, if any.
|
* [out] ret the writable page, if any.
|
||||||
* ret is unchanged if mp wasn't spilled. */
|
* ret is unchanged if mp wasn't spilled. */
|
||||||
static int mdbx_page_unspill(MDBX_txn *txn, MDBX_page *mp, MDBX_page **ret) {
|
static int __must_check_result mdbx_page_unspill(MDBX_txn *txn, MDBX_page *mp,
|
||||||
|
MDBX_page **ret) {
|
||||||
MDBX_env *env = txn->mt_env;
|
MDBX_env *env = txn->mt_env;
|
||||||
const MDBX_txn *tx2;
|
const MDBX_txn *tx2;
|
||||||
unsigned x;
|
unsigned x;
|
||||||
@ -2630,7 +2637,10 @@ static int mdbx_page_unspill(MDBX_txn *txn, MDBX_page *mp, MDBX_page **ret) {
|
|||||||
} /* otherwise, if belonging to a parent txn, the
|
} /* otherwise, if belonging to a parent txn, the
|
||||||
* page remains spilled until child commits */
|
* page remains spilled until child commits */
|
||||||
|
|
||||||
mdbx_page_dirty(txn, np);
|
int rc = mdbx_page_dirty(txn, np);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
return rc;
|
||||||
|
|
||||||
np->mp_flags |= P_DIRTY;
|
np->mp_flags |= P_DIRTY;
|
||||||
*ret = np;
|
*ret = np;
|
||||||
break;
|
break;
|
||||||
@ -2692,8 +2702,8 @@ static int mdbx_page_touch(MDBX_cursor *mc) {
|
|||||||
" in the dirtylist[%d], expecting %p",
|
" in the dirtylist[%d], expecting %p",
|
||||||
dl[x].mptr, pgno, x, mp);
|
dl[x].mptr, pgno, x, mp);
|
||||||
mc->mc_flags &= ~(C_INITIALIZED | C_EOF);
|
mc->mc_flags &= ~(C_INITIALIZED | C_EOF);
|
||||||
txn->mt_flags |= MDBX_TXN_ERROR;
|
rc = MDBX_PROBLEM;
|
||||||
return MDBX_PROBLEM;
|
goto fail;
|
||||||
}
|
}
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2703,12 +2713,15 @@ static int mdbx_page_touch(MDBX_cursor *mc) {
|
|||||||
mdbx_cassert(mc, dl[0].mid < MDBX_PNL_UM_MAX);
|
mdbx_cassert(mc, dl[0].mid < MDBX_PNL_UM_MAX);
|
||||||
/* No - copy it */
|
/* No - copy it */
|
||||||
np = mdbx_page_malloc(txn, 1);
|
np = mdbx_page_malloc(txn, 1);
|
||||||
if (unlikely(!np))
|
if (unlikely(!np)) {
|
||||||
return MDBX_ENOMEM;
|
rc = MDBX_ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
mid.mid = pgno;
|
mid.mid = pgno;
|
||||||
mid.mptr = np;
|
mid.mptr = np;
|
||||||
rc = mdbx_mid2l_insert(dl, &mid);
|
rc = mdbx_mid2l_insert(dl, &mid);
|
||||||
mdbx_cassert(mc, rc == 0);
|
if (unlikely(rc))
|
||||||
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -7854,7 +7867,10 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
id2.mptr = np;
|
id2.mptr = np;
|
||||||
/* Note - this page is already counted in parent's dirtyroom */
|
/* Note - this page is already counted in parent's dirtyroom */
|
||||||
rc2 = mdbx_mid2l_insert(mc->mc_txn->mt_rw_dirtylist, &id2);
|
rc2 = mdbx_mid2l_insert(mc->mc_txn->mt_rw_dirtylist, &id2);
|
||||||
mdbx_cassert(mc, rc2 == 0);
|
if (unlikely(rc2 != MDBX_SUCCESS)) {
|
||||||
|
rc = rc2;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Currently we make the page look as with put() in the
|
/* Currently we make the page look as with put() in the
|
||||||
* parent txn, in case the user peeks at MDBX_RESERVEd
|
* parent txn, in case the user peeks at MDBX_RESERVEd
|
||||||
@ -8045,6 +8061,7 @@ new_sub:
|
|||||||
/* should not happen, we deleted that item */
|
/* should not happen, we deleted that item */
|
||||||
rc = MDBX_PROBLEM;
|
rc = MDBX_PROBLEM;
|
||||||
}
|
}
|
||||||
|
fail:
|
||||||
mc->mc_txn->mt_flags |= MDBX_TXN_ERROR;
|
mc->mc_txn->mt_flags |= MDBX_TXN_ERROR;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user