mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-23 16:19:35 -05:00
ITS#7377 Invalidate txn on page-allocation errors
This should likely be reverted when all callers handle these errors.
This commit is contained in:
parent
123b6e3c3e
commit
c99525f42a
1 changed files with 29 additions and 11 deletions
|
|
@ -1405,6 +1405,8 @@ mdb_page_malloc(MDB_txn *txn, unsigned num)
|
||||||
memset((char *)ret + off, 0, psize);
|
memset((char *)ret + off, 0, psize);
|
||||||
ret->mp_pad = 0;
|
ret->mp_pad = 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
txn->mt_flags |= MDB_TXN_ERROR;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -1725,8 +1727,10 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||||
*mp = NULL;
|
*mp = NULL;
|
||||||
|
|
||||||
/* If our dirty list is already full, we can't do anything */
|
/* If our dirty list is already full, we can't do anything */
|
||||||
if (txn->mt_dirty_room == 0)
|
if (txn->mt_dirty_room == 0) {
|
||||||
return MDB_TXN_FULL;
|
rc = MDB_TXN_FULL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
for (op = MDB_FIRST;; op = MDB_NEXT) {
|
for (op = MDB_FIRST;; op = MDB_NEXT) {
|
||||||
MDB_val key, data;
|
MDB_val key, data;
|
||||||
|
|
@ -1771,7 +1775,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (rc == MDB_NOTFOUND)
|
if (rc == MDB_NOTFOUND)
|
||||||
break;
|
break;
|
||||||
return rc;
|
goto fail;
|
||||||
}
|
}
|
||||||
last = *(txnid_t*)key.mv_data;
|
last = *(txnid_t*)key.mv_data;
|
||||||
if (oldest <= last)
|
if (oldest <= last)
|
||||||
|
|
@ -1784,11 +1788,13 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||||
idl = (MDB_ID *) data.mv_data;
|
idl = (MDB_ID *) data.mv_data;
|
||||||
i = idl[0];
|
i = idl[0];
|
||||||
if (!mop) {
|
if (!mop) {
|
||||||
if (!(env->me_pghead = mop = mdb_midl_alloc(i)))
|
if (!(env->me_pghead = mop = mdb_midl_alloc(i))) {
|
||||||
return ENOMEM;
|
rc = ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((rc = mdb_midl_need(&env->me_pghead, i)) != 0)
|
if ((rc = mdb_midl_need(&env->me_pghead, i)) != 0)
|
||||||
return rc;
|
goto fail;
|
||||||
mop = env->me_pghead;
|
mop = env->me_pghead;
|
||||||
}
|
}
|
||||||
env->me_pglast = last;
|
env->me_pglast = last;
|
||||||
|
|
@ -1817,15 +1823,18 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||||
pgno = txn->mt_next_pgno;
|
pgno = txn->mt_next_pgno;
|
||||||
if (pgno + num >= env->me_maxpg) {
|
if (pgno + num >= env->me_maxpg) {
|
||||||
DPUTS("DB size maxed out");
|
DPUTS("DB size maxed out");
|
||||||
return MDB_MAP_FULL;
|
rc = MDB_MAP_FULL;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
search_done:
|
search_done:
|
||||||
if (env->me_flags & MDB_WRITEMAP) {
|
if (env->me_flags & MDB_WRITEMAP) {
|
||||||
np = (MDB_page *)(env->me_map + env->me_psize * pgno);
|
np = (MDB_page *)(env->me_map + env->me_psize * pgno);
|
||||||
} else {
|
} else {
|
||||||
if (!(np = mdb_page_malloc(txn, num)))
|
if (!(np = mdb_page_malloc(txn, num))) {
|
||||||
return ENOMEM;
|
rc = ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i) {
|
if (i) {
|
||||||
mop[0] = mop_len -= num;
|
mop[0] = mop_len -= num;
|
||||||
|
|
@ -1840,6 +1849,10 @@ search_done:
|
||||||
*mp = np;
|
*mp = np;
|
||||||
|
|
||||||
return MDB_SUCCESS;
|
return MDB_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
txn->mt_flags |= MDB_TXN_ERROR;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy the used portions of a non-overflow page.
|
/** Copy the used portions of a non-overflow page.
|
||||||
|
|
@ -1946,13 +1959,13 @@ mdb_page_touch(MDB_cursor *mc)
|
||||||
np = NULL;
|
np = NULL;
|
||||||
rc = mdb_page_unspill(txn, mp, &np);
|
rc = mdb_page_unspill(txn, mp, &np);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
goto fail;
|
||||||
if (np)
|
if (np)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((rc = mdb_midl_need(&txn->mt_free_pgs, 1)) ||
|
if ((rc = mdb_midl_need(&txn->mt_free_pgs, 1)) ||
|
||||||
(rc = mdb_page_alloc(mc, 1, &np)))
|
(rc = mdb_page_alloc(mc, 1, &np)))
|
||||||
return rc;
|
goto fail;
|
||||||
pgno = np->mp_pgno;
|
pgno = np->mp_pgno;
|
||||||
DPRINTF(("touched db %d page %"Z"u -> %"Z"u", DDBI(mc),
|
DPRINTF(("touched db %d page %"Z"u -> %"Z"u", DDBI(mc),
|
||||||
mp->mp_pgno, pgno));
|
mp->mp_pgno, pgno));
|
||||||
|
|
@ -1977,6 +1990,7 @@ mdb_page_touch(MDB_cursor *mc)
|
||||||
if (x <= dl[0].mid && dl[x].mid == pgno) {
|
if (x <= dl[0].mid && dl[x].mid == pgno) {
|
||||||
if (mp != dl[x].mptr) { /* bad cursor? */
|
if (mp != dl[x].mptr) { /* bad cursor? */
|
||||||
mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
|
mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
|
||||||
|
txn->mt_flags |= MDB_TXN_ERROR;
|
||||||
return MDB_CORRUPTED;
|
return MDB_CORRUPTED;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2025,6 +2039,10 @@ done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
txn->mt_flags |= MDB_TXN_ERROR;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue