ITS#7512 Fix MDB page leak when malloc error.

mdb_page_alloc(): Delay moving me_pgfirst,me_pglast
until malloc(MDB_oldpages to hold the IDs) succeeds.
vmware
Hallvard Furuseth 12 years ago
parent e0eb495fb3
commit 65c053a6e7
  1. 13
      libraries/liblmdb/mdb.c

@ -1341,19 +1341,24 @@ again:
if (!txn->mt_env->me_pgfirst) { if (!txn->mt_env->me_pgfirst) {
mdb_node_read(txn, leaf, &data); mdb_node_read(txn, leaf, &data);
} }
txn->mt_env->me_pglast = last;
if (!txn->mt_env->me_pgfirst)
txn->mt_env->me_pgfirst = last;
idl = (MDB_ID *) data.mv_data; idl = (MDB_ID *) data.mv_data;
/* We might have a zero-length IDL due to freelist growth /* We might have a zero-length IDL due to freelist growth
* during a prior commit * during a prior commit
*/ */
if (!idl[0]) goto again; if (!idl[0]) {
txn->mt_env->me_pglast = last;
if (!txn->mt_env->me_pgfirst)
txn->mt_env->me_pgfirst = last;
goto again;
}
mop = malloc(sizeof(MDB_oldpages) + MDB_IDL_SIZEOF(idl) - sizeof(pgno_t)); mop = malloc(sizeof(MDB_oldpages) + MDB_IDL_SIZEOF(idl) - sizeof(pgno_t));
if (!mop) if (!mop)
return ENOMEM; return ENOMEM;
mop->mo_next = txn->mt_env->me_pghead; mop->mo_next = txn->mt_env->me_pghead;
mop->mo_txnid = last; mop->mo_txnid = last;
txn->mt_env->me_pglast = last;
if (!txn->mt_env->me_pgfirst)
txn->mt_env->me_pgfirst = last;
txn->mt_env->me_pghead = mop; txn->mt_env->me_pghead = mop;
memcpy(mop->mo_pages, idl, MDB_IDL_SIZEOF(idl)); memcpy(mop->mo_pages, idl, MDB_IDL_SIZEOF(idl));

Loading…
Cancel
Save