diff --git a/libraries/libmdb/mdb.c b/libraries/libmdb/mdb.c index 6e829c8..21d468b 100644 --- a/libraries/libmdb/mdb.c +++ b/libraries/libmdb/mdb.c @@ -1617,9 +1617,9 @@ mdb_txn_commit(MDB_txn *txn) mdb_txn_abort(txn); return n; } + env->me_wtxnid = txn->mt_txnid; done: - env->me_wtxnid = txn->mt_txnid; env->me_txn = NULL; /* update the DB tables */ { @@ -2852,12 +2852,38 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int modify) if (F_ISSET(mc->mc_txn->mt_flags, MDB_TXN_ERROR)) { DPUTS("transaction has failed, must abort"); return EINVAL; - } else + } else { + /* Make sure we're using an up-to-date root */ + if (mc->mc_dbi > MAIN_DBI) { + if ((*mc->mc_dbflag & DB_STALE) || + (modify && !(*mc->mc_dbflag & DB_DIRTY))) { + MDB_cursor mc2; + unsigned char dbflag = 0; + mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, NULL); + rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, modify); + if (rc) + return rc; + if (*mc->mc_dbflag & DB_STALE) { + MDB_val data; + int exact = 0; + MDB_node *leaf = mdb_node_search(&mc2, + &mc->mc_dbx->md_name, &exact); + if (!exact) + return MDB_NOTFOUND; + mdb_node_read(mc->mc_txn, leaf, &data); + memcpy(mc->mc_db, data.mv_data, sizeof(MDB_db)); + } + if (modify) + dbflag = DB_DIRTY; + *mc->mc_dbflag = dbflag; + } + } root = mc->mc_db->md_root; - if (root == P_INVALID) { /* Tree is empty. */ - DPUTS("tree is empty"); - return MDB_NOTFOUND; + if (root == P_INVALID) { /* Tree is empty. */ + DPUTS("tree is empty"); + return MDB_NOTFOUND; + } } if ((rc = mdb_page_get(mc->mc_txn, root, &mc->mc_pg[0]))) @@ -2869,31 +2895,6 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int modify) DPRINTF("db %u root page %zu has flags 0x%X", mc->mc_dbi, root, mc->mc_pg[0]->mp_flags); - /* For sub-databases, update main root first */ - if (mc->mc_dbi > MAIN_DBI) { - if ((*mc->mc_dbflag & DB_STALE) || - (modify && !(*mc->mc_dbflag & DB_DIRTY))) { - MDB_cursor mc2; - unsigned char dbflag = 0; - mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, NULL); - rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, modify); - if (rc) - return rc; - if (*mc->mc_dbflag & DB_STALE) { - MDB_val data; - int exact = 0; - MDB_node *leaf = mdb_node_search(&mc2, - &mc->mc_dbx->md_name, &exact); - if (!exact) - return MDB_NOTFOUND; - mdb_node_read(mc->mc_txn, leaf, &data); - memcpy(mc->mc_db, data.mv_data, sizeof(MDB_db)); - } - if (modify) - dbflag = DB_DIRTY; - *mc->mc_dbflag = dbflag; - } - } if (modify) { if (!F_ISSET(mc->mc_pg[0]->mp_flags, P_DIRTY)) { if ((rc = mdb_page_touch(mc)))