mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-27 03:20:22 +08: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
@ -1405,6 +1405,8 @@ mdb_page_malloc(MDB_txn *txn, unsigned num)
|
||||
memset((char *)ret + off, 0, psize);
|
||||
ret->mp_pad = 0;
|
||||
}
|
||||
} else {
|
||||
txn->mt_flags |= MDB_TXN_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1725,8 +1727,10 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||
*mp = NULL;
|
||||
|
||||
/* If our dirty list is already full, we can't do anything */
|
||||
if (txn->mt_dirty_room == 0)
|
||||
return MDB_TXN_FULL;
|
||||
if (txn->mt_dirty_room == 0) {
|
||||
rc = MDB_TXN_FULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (op = MDB_FIRST;; op = MDB_NEXT) {
|
||||
MDB_val key, data;
|
||||
@ -1771,7 +1775,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||
if (rc) {
|
||||
if (rc == MDB_NOTFOUND)
|
||||
break;
|
||||
return rc;
|
||||
goto fail;
|
||||
}
|
||||
last = *(txnid_t*)key.mv_data;
|
||||
if (oldest <= last)
|
||||
@ -1784,11 +1788,13 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||
idl = (MDB_ID *) data.mv_data;
|
||||
i = idl[0];
|
||||
if (!mop) {
|
||||
if (!(env->me_pghead = mop = mdb_midl_alloc(i)))
|
||||
return ENOMEM;
|
||||
if (!(env->me_pghead = mop = mdb_midl_alloc(i))) {
|
||||
rc = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if ((rc = mdb_midl_need(&env->me_pghead, i)) != 0)
|
||||
return rc;
|
||||
goto fail;
|
||||
mop = env->me_pghead;
|
||||
}
|
||||
env->me_pglast = last;
|
||||
@ -1817,15 +1823,18 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||
pgno = txn->mt_next_pgno;
|
||||
if (pgno + num >= env->me_maxpg) {
|
||||
DPUTS("DB size maxed out");
|
||||
return MDB_MAP_FULL;
|
||||
rc = MDB_MAP_FULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
search_done:
|
||||
if (env->me_flags & MDB_WRITEMAP) {
|
||||
np = (MDB_page *)(env->me_map + env->me_psize * pgno);
|
||||
} else {
|
||||
if (!(np = mdb_page_malloc(txn, num)))
|
||||
return ENOMEM;
|
||||
if (!(np = mdb_page_malloc(txn, num))) {
|
||||
rc = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (i) {
|
||||
mop[0] = mop_len -= num;
|
||||
@ -1840,6 +1849,10 @@ search_done:
|
||||
*mp = np;
|
||||
|
||||
return MDB_SUCCESS;
|
||||
|
||||
fail:
|
||||
txn->mt_flags |= MDB_TXN_ERROR;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Copy the used portions of a non-overflow page.
|
||||
@ -1946,13 +1959,13 @@ mdb_page_touch(MDB_cursor *mc)
|
||||
np = NULL;
|
||||
rc = mdb_page_unspill(txn, mp, &np);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto fail;
|
||||
if (np)
|
||||
goto done;
|
||||
}
|
||||
if ((rc = mdb_midl_need(&txn->mt_free_pgs, 1)) ||
|
||||
(rc = mdb_page_alloc(mc, 1, &np)))
|
||||
return rc;
|
||||
goto fail;
|
||||
pgno = np->mp_pgno;
|
||||
DPRINTF(("touched db %d page %"Z"u -> %"Z"u", DDBI(mc),
|
||||
mp->mp_pgno, pgno));
|
||||
@ -1977,6 +1990,7 @@ mdb_page_touch(MDB_cursor *mc)
|
||||
if (x <= dl[0].mid && dl[x].mid == pgno) {
|
||||
if (mp != dl[x].mptr) { /* bad cursor? */
|
||||
mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
|
||||
txn->mt_flags |= MDB_TXN_ERROR;
|
||||
return MDB_CORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
@ -2025,6 +2039,10 @@ done:
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
txn->mt_flags |= MDB_TXN_ERROR;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user