From 1b6085cb9b0735a7442d9972b5beb0be241dbdfc Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 2 Jul 2015 18:04:25 +0100 Subject: [PATCH 1/4] Return to Release Engineering --- libraries/liblmdb/CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index 957742e752..b35ca61d76 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -1,5 +1,7 @@ LMDB 0.9 Change Log +LMDB 0.9.16 Release Engineering + LMDB 0.9.15 Release (2015/06/19) Fix txn init (ITS#7961,#7987) Fix MDB_PREV_DUP (ITS#7955,#7671) From 7513bd4618959ded9cf8f7a9f7e58283a7671b6f Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 7 Jul 2015 13:41:32 +0100 Subject: [PATCH 2/4] ITS#8190 fix cursor EOF bug --- libraries/liblmdb/mdb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 6bdf3151dc..7129741e91 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -5725,8 +5725,10 @@ set2: if (leaf == NULL) { DPUTS("===> inexact leaf not found, goto sibling"); - if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) + if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) { + mc->mc_flags |= C_EOF; return rc; /* no entries matched */ + } mp = mc->mc_pg[mc->mc_top]; mdb_cassert(mc, IS_LEAF(mp)); leaf = NODEPTR(mp, 0); From 1fd0341f76db9fbfe2c70d73c51d6e2de154f4d5 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sat, 11 Jul 2015 21:01:40 +0200 Subject: [PATCH 3/4] ITS#8181 Verify that records are/aren't DBs. Except we don't catch the user passing F_SUBDATA to mdb_cursor_, like an internal LMDB call. --- libraries/liblmdb/lmdb.h | 14 +++++++++++--- libraries/liblmdb/mdb.c | 17 ++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h index 2f523579c8..e935509d9e 100644 --- a/libraries/liblmdb/lmdb.h +++ b/libraries/liblmdb/lmdb.h @@ -413,7 +413,14 @@ typedef enum MDB_cursor_op { #define MDB_PAGE_FULL (-30786) /** Database contents grew beyond environment mapsize */ #define MDB_MAP_RESIZED (-30785) - /** MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed */ + /** Operation and DB incompatible, or DB type changed. This can mean: + *
    + *
  • The operation expects an #MDB_DUPSORT / #MDB_DUPFIXED database. + *
  • Opening a named DB when the unnamed DB has #MDB_DUPSORT / #MDB_INTEGERKEY. + *
  • Accessing a data record as a database, or vice versa. + *
  • The database was dropped and recreated with different flags. + *
+ */ #define MDB_INCOMPATIBLE (-30784) /** Invalid reuse of reader locktable slot */ #define MDB_BAD_RSLOT (-30783) @@ -1034,8 +1041,9 @@ int mdb_txn_renew(MDB_txn *txn); * any other transaction in the process may use this function. * * To use named databases (with name != NULL), #mdb_env_set_maxdbs() - * must be called before opening the environment. Database names - * are kept as keys in the unnamed database. + * must be called before opening the environment. Database names are + * keys in the unnamed database, and may be read but not written. + * * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] name The name of the database to open. If only a single * database is needed in the environment, this value may be NULL. diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 7129741e91..eeab972a82 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -3395,7 +3395,8 @@ mdb_txn_commit(MDB_txn *txn) goto fail; } data.mv_data = &txn->mt_dbs[i]; - rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data, 0); + rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data, + F_SUBDATA); if (rc) goto fail; } @@ -5214,6 +5215,8 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags) &mc->mc_dbx->md_name, &exact); if (!exact) return MDB_NOTFOUND; + if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) + return MDB_INCOMPATIBLE; /* not a named DB */ rc = mdb_node_read(mc->mc_txn, leaf, &data); if (rc) return rc; @@ -6406,6 +6409,9 @@ prep_subDB: goto new_sub; } current: + /* LMDB passes F_SUBDATA in 'flags' to write a DB record */ + if ((leaf->mn_flags ^ flags) & F_SUBDATA) + return MDB_INCOMPATIBLE; /* overflow page overwrites need special handling */ if (F_ISSET(leaf->mn_flags, F_BIGDATA)) { MDB_page *omp; @@ -6676,6 +6682,11 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) goto fail; } } + /* LMDB passes F_SUBDATA in 'flags' to delete a DB record */ + else if ((leaf->mn_flags ^ flags) & F_SUBDATA) { + rc = MDB_INCOMPATIBLE; + goto fail; + } /* add overflow pages to free list */ if (F_ISSET(leaf->mn_flags, F_BIGDATA)) { @@ -9171,7 +9182,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db if (rc == MDB_SUCCESS) { /* make sure this is actually a DB */ MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); - if (!(node->mn_flags & F_SUBDATA)) + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) return MDB_INCOMPATIBLE; } else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) { /* Create if requested */ @@ -9364,7 +9375,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del) /* Can't delete the main DB */ if (del && dbi > MAIN_DBI) { - rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, 0); + rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, F_SUBDATA); if (!rc) { txn->mt_dbflags[dbi] = DB_STALE; mdb_dbi_close(txn->mt_env, dbi); From 4b58502c7767fd5f4e65a53de31b0ebaf6f9013c Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sun, 19 Jul 2015 21:18:31 +0200 Subject: [PATCH 4/4] ITS#8200 Fix mdb_midl_shrink() usage, return void --- libraries/liblmdb/mdb.c | 8 ++++---- libraries/liblmdb/midl.c | 4 +--- libraries/liblmdb/midl.h | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index eeab972a82..adc20f893b 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -2822,8 +2822,8 @@ mdb_txn_reset0(MDB_txn *txn, const char *act) } if (!txn->mt_parent) { - if (mdb_midl_shrink(&txn->mt_free_pgs)) - env->me_free_pgs = txn->mt_free_pgs; + mdb_midl_shrink(&txn->mt_free_pgs); + env->me_free_pgs = txn->mt_free_pgs; /* me_pgstate: */ env->me_pghead = NULL; env->me_pglast = 0; @@ -3409,8 +3409,8 @@ mdb_txn_commit(MDB_txn *txn) mdb_midl_free(env->me_pghead); env->me_pghead = NULL; - if (mdb_midl_shrink(&txn->mt_free_pgs)) - env->me_free_pgs = txn->mt_free_pgs; + mdb_midl_shrink(&txn->mt_free_pgs); + env->me_free_pgs = txn->mt_free_pgs; #if (MDB_DEBUG) > 2 mdb_audit(txn); diff --git a/libraries/liblmdb/midl.c b/libraries/liblmdb/midl.c index 16782dcafc..57a9d4920e 100644 --- a/libraries/liblmdb/midl.c +++ b/libraries/liblmdb/midl.c @@ -116,7 +116,7 @@ void mdb_midl_free(MDB_IDL ids) free(ids-1); } -int mdb_midl_shrink( MDB_IDL *idp ) +void mdb_midl_shrink( MDB_IDL *idp ) { MDB_IDL ids = *idp; if (*(--ids) > MDB_IDL_UM_MAX && @@ -124,9 +124,7 @@ int mdb_midl_shrink( MDB_IDL *idp ) { *ids++ = MDB_IDL_UM_MAX; *idp = ids; - return 1; } - return 0; } static int mdb_midl_grow( MDB_IDL *idp, int num ) diff --git a/libraries/liblmdb/midl.h b/libraries/liblmdb/midl.h index 9b041d72d1..2331e78398 100644 --- a/libraries/liblmdb/midl.h +++ b/libraries/liblmdb/midl.h @@ -98,9 +98,8 @@ void mdb_midl_free(MDB_IDL ids); /** Shrink an IDL. * Return the IDL to the default size if it has grown larger. * @param[in,out] idp Address of the IDL to shrink. - * @return 0 on no change, non-zero if shrunk. */ -int mdb_midl_shrink(MDB_IDL *idp); +void mdb_midl_shrink(MDB_IDL *idp); /** Make room for num additional elements in an IDL. * @param[in,out] idp Address of the IDL.