From: Hallvard Furuseth Date: Thu, 11 Jul 2013 20:09:46 +0000 (+0200) Subject: Save freelist using proper mdb_cursor_put(). X-Git-Tag: OPENLDAP_REL_ENG_2_4_36~32^2~18 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6741f9c0ef7973aeebacc3e547db9fc07702a8c2;p=openldap Save freelist using proper mdb_cursor_put(). (Restructuring for upcoming mdb_page_spill work.) mdb_freelist_save() can't just Get() the destination, since mdb_page_spill() may have put the destination in the read-only map. TODO: Can this new put() modify the freelist, which would break it? The final iteration's put() can shorten the node, the rest uses MDB_CURRENT. We could set P_KEEP on dirty freeDB leaves and ovpages, since they are all about to be modified. But the code in this commit must stay anyway, if mdb should support dropping a 256G DB. I.e. too big for dirty_list. --- diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 57353fc0de..50887d6789 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -2171,25 +2171,32 @@ mdb_freelist_save(MDB_txn *txn) total_room += head_room; } - /* Fill in the reserved, touched me_pghead records. Avoid write ops - * so they cannot rearrange anything, just read the destinations. - */ + /* Fill in the reserved, touched me_pghead records */ rc = MDB_SUCCESS; if (mop_len) { MDB_val key, data; - mop += mop_len + 1; + mop += mop_len; rc = mdb_cursor_first(&mc, &key, &data); for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) { - MDB_IDL dest = data.mv_data; + unsigned flags = MDB_CURRENT; + txnid_t id = *(txnid_t *)key.mv_data; ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1; + MDB_ID save; - assert(len >= 0 && *(txnid_t*)key.mv_data <= env->me_pglast); - if (len > mop_len) + assert(len >= 0 && id <= env->me_pglast); + key.mv_data = &id; + if (len > mop_len) { len = mop_len; - *dest++ = len; - memcpy(dest, mop -= len, len * sizeof(MDB_ID)); - if (! (mop_len -= len)) + data.mv_size = (len + 1) * sizeof(MDB_ID); + flags = 0; + } + data.mv_data = mop -= len; + save = mop[0]; + mop[0] = len; + rc = mdb_cursor_put(&mc, &key, &data, flags); + mop[0] = save; + if (rc || !(mop_len -= len)) break; } }