]> git.sur5r.net Git - openldap/commitdiff
mdb_page_alloc(): Handle freeDB txnid range holes.
authorHallvard Furuseth <hallvard@openldap.org>
Tue, 19 Feb 2013 20:17:33 +0000 (21:17 +0100)
committerHallvard Furuseth <hallvard@openldap.org>
Tue, 19 Feb 2013 20:17:33 +0000 (21:17 +0100)
A txn writes no freeDB entry if previous txn dropped mainDB and a read
txn prevents freelist entry reuse. This surprised mdb_page_alloc (and
mdb_txn_commit too before 65c053a6e7f6973c1d09710aa1bd57b218206fcb).

libraries/liblmdb/mdb.c

index 8d7b97e099ce1c8bffd02c1ecb38547b7e9d35ce..368cf5227f7bf3fd1eac09d13fea0656f6487cbb 100644 (file)
@@ -1294,14 +1294,12 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
                                last = *kptr;
                        } else {
                                MDB_val key;
-                               int exact;
 again:
-                               exact = 0;
                                last = txn->mt_env->me_pglast + 1;
                                leaf = NULL;
                                key.mv_data = &last;
                                key.mv_size = sizeof(last);
-                               rc = mdb_cursor_set(&m2, &key, &data, MDB_SET, &exact);
+                               rc = mdb_cursor_set(&m2, &key, &data, MDB_SET_RANGE, NULL);
                                if (rc)
                                        goto none;
                                last = *(txnid_t *)key.mv_data;
@@ -1381,7 +1379,6 @@ none:
                                        if (readit) {
                                                MDB_val key, data;
                                                pgno_t *idl, *mop2;
-                                               int exact;
 
                                                last = txn->mt_env->me_pglast + 1;
 
@@ -1406,12 +1403,17 @@ none:
                                                if (oldest - last < 1)
                                                        break;
 
-                                               exact = 0;
                                                key.mv_data = &last;
                                                key.mv_size = sizeof(last);
-                                               rc = mdb_cursor_set(&m2, &key, &data, MDB_SET, &exact);
-                                               if (rc)
+                                               rc = mdb_cursor_set(&m2,&key,&data,MDB_SET_RANGE,NULL);
+                                               if (rc) {
+                                                       if (rc == MDB_NOTFOUND)
+                                                               break;
                                                        return rc;
+                                               }
+                                               last = *(txnid_t*)key.mv_data;
+                                               if (oldest <= last)
+                                                       break;
                                                idl = (MDB_ID *) data.mv_data;
                                                mop2 = malloc(MDB_IDL_SIZEOF(idl) + MDB_IDL_SIZEOF(mop));
                                                if (!mop2)