ITS#7377 Invalidate txn on page-allocation errors

This should likely be reverted when all callers handle these errors.
vmware
Hallvard Furuseth 11 years ago
parent 123b6e3c3e
commit c99525f42a
  1. 40
      libraries/liblmdb/mdb.c

@ -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…
Cancel
Save