From d6b3c6f710dabf017cac3f583cc815175dc9d711 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sun, 19 Jul 2015 21:43:10 +0200 Subject: [PATCH] lmdb: ITS#7377 Always notice env error on txn startup. Move the check to the end of txn startup. Catches env breakage which happens while the new txn waits for a lock. Change-Id: I074d411cd5339b5e6caa2691078ea07b0d49828e --- mdb.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/mdb.c b/mdb.c index c2eb13be..ae50dfbe 100644 --- a/mdb.c +++ b/mdb.c @@ -2849,12 +2849,16 @@ mdb_txn_renew0(MDB_txn *txn) txn->mt_dbflags[MAIN_DBI] = DB_VALID|DB_USRVALID; txn->mt_dbflags[FREE_DBI] = DB_VALID; - if (unlikely(env->me_maxpg < txn->mt_next_pgno)) { - mdb_txn_end(txn, new_notls /*0 or MDB_END_SLOT*/ | MDB_END_FAIL_BEGIN); - return MDB_MAP_RESIZED; + if (unlikely(env->me_flags & MDB_FATAL_ERROR)) { + mdb_debug("environment had fatal error, must shutdown!"); + rc = MDB_PANIC; + } else if (unlikely(env->me_maxpg < txn->mt_next_pgno)) { + rc = MDB_MAP_RESIZED; + } else { + return MDB_SUCCESS; } - - return MDB_SUCCESS; + mdb_txn_end(txn, new_notls /*0 or MDB_END_SLOT*/ | MDB_END_FAIL_BEGIN); + return rc; } int @@ -2865,11 +2869,6 @@ mdb_txn_renew(MDB_txn *txn) if (unlikely(!txn || !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED))) return EINVAL; - if (unlikely(txn->mt_env->me_flags & MDB_FATAL_ERROR)) { - mdb_debug("environment had fatal error, must shutdown!"); - return MDB_PANIC; - } - rc = mdb_txn_renew0(txn); if (rc == MDB_SUCCESS) { mdb_debug("renew txn %zu%c %p on mdbenv %p, root page %zu", @@ -2889,11 +2888,7 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned flags, MDB_txn **ret) flags &= MDB_TXN_BEGIN_FLAGS; flags |= env->me_flags & MDB_WRITEMAP; - if (env->me_flags & MDB_FATAL_ERROR) { - mdb_debug("environment had fatal error, must shutdown!"); - return MDB_PANIC; - } - if (env->me_flags & MDB_RDONLY & ~flags) /* write txn in RDONLY env */ + if (unlikely(env->me_flags & MDB_RDONLY & ~flags)) /* write txn in RDONLY env */ return EACCES; if (parent) {