From: Hallvard Furuseth Date: Sat, 10 Dec 2016 20:42:39 +0000 (+0100) Subject: Clean up and comment C_UNTRACK X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d78c80d902e3b508b6d118c975a6c6a8d9782f40;p=openldap Clean up and comment C_UNTRACK Don't use it as a "cursor is tracked" hint in mdb_pages_xkeep(). It's been harmless so far, but would break after mdb_cursor_copy(). Checking m0 directly short-circuits better anyway. --- diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index edfb034e06..5a3a829629 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -2094,13 +2094,9 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) unsigned i, j; int rc = MDB_SUCCESS, level; - /* Mark pages seen by cursors */ - if (mc->mc_flags & C_UNTRACK) - mc = NULL; /* will find mc in mt_cursors */ - for (i = txn->mt_numdbs;; mc = txn->mt_cursors[--i]) { - for (; mc; mc=mc->mc_next) { - if (!(mc->mc_flags & C_INITIALIZED)) - continue; + /* Mark pages seen by cursors: First m0, then tracked cursors */ + for (i = txn->mt_numdbs;; ) { + if (mc->mc_flags & C_INITIALIZED) { for (m3 = mc;; m3 = &mx->mx_cursor) { mp = NULL; for (j=0; jmc_snum; j++) { @@ -2119,10 +2115,13 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) break; } } - if (i == 0) - break; + mc = mc->mc_next; + for (; !mc || mc == m0; mc = txn->mt_cursors[--i]) + if (i == 0) + goto mark_done; } +mark_done: if (all) { /* Mark dirty root pages */ for (i=0; imt_numdbs; i++) { @@ -8442,7 +8441,10 @@ mdb_cursor_close(MDB_cursor *mc) MDB_CURSOR_UNREF(mc, 0); } if (mc && !mc->mc_backup) { - /* remove from txn, if tracked */ + /* Remove from txn, if tracked. + * A read-only txn (!C_UNTRACK) may have been freed already, + * so do not peek inside it. Only write txns track cursors. + */ if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) { MDB_cursor **prev = &mc->mc_txn->mt_cursors[mc->mc_dbi]; while (*prev && *prev != mc) prev = &(*prev)->mc_next; @@ -9287,7 +9289,6 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi, * run out of space, triggering a split. We need this * cursor to be consistent until the end of the rebalance. */ - mc.mc_flags |= C_UNTRACK; mc.mc_next = txn->mt_cursors[dbi]; txn->mt_cursors[dbi] = &mc; rc = mdb_cursor_del(&mc, flags);