|
|
@ -3793,6 +3793,8 @@ done: |
|
|
|
return MDB_SUCCESS; |
|
|
|
return MDB_SUCCESS; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int ESECT mdb_env_share_locks(MDB_env *env, int *excl); |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
int |
|
|
|
mdb_txn_commit(MDB_txn *txn) |
|
|
|
mdb_txn_commit(MDB_txn *txn) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -4015,6 +4017,15 @@ mdb_txn_commit(MDB_txn *txn) |
|
|
|
if ((rc = mdb_env_write_meta(txn))) |
|
|
|
if ((rc = mdb_env_write_meta(txn))) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
|
end_mode = MDB_END_COMMITTED|MDB_END_UPDATE; |
|
|
|
end_mode = MDB_END_COMMITTED|MDB_END_UPDATE; |
|
|
|
|
|
|
|
if (env->me_flags & MDB_PREVSNAPSHOT) { |
|
|
|
|
|
|
|
if (!(env->me_flags & MDB_NOLOCK)) { |
|
|
|
|
|
|
|
int excl; |
|
|
|
|
|
|
|
rc = mdb_env_share_locks(env, &excl); |
|
|
|
|
|
|
|
if (rc) |
|
|
|
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
env->me_flags ^= MDB_PREVSNAPSHOT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
done: |
|
|
|
done: |
|
|
|
mdb_txn_end(txn, end_mode); |
|
|
|
mdb_txn_end(txn, end_mode); |
|
|
@ -4296,7 +4307,8 @@ static MDB_meta * |
|
|
|
mdb_env_pick_meta(const MDB_env *env) |
|
|
|
mdb_env_pick_meta(const MDB_env *env) |
|
|
|
{ |
|
|
|
{ |
|
|
|
MDB_meta *const *metas = env->me_metas; |
|
|
|
MDB_meta *const *metas = env->me_metas; |
|
|
|
return metas[ metas[0]->mm_txnid < metas[1]->mm_txnid ]; |
|
|
|
return metas[ (metas[0]->mm_txnid < metas[1]->mm_txnid) ^ |
|
|
|
|
|
|
|
((env->me_flags & MDB_PREVSNAPSHOT) != 0) ]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ESECT |
|
|
|
int ESECT |
|
|
@ -4868,6 +4880,9 @@ mdb_env_open2(MDB_env *env, int prev) |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
env->me_maxpg = env->me_mapsize / env->me_psize; |
|
|
|
env->me_maxpg = env->me_mapsize / env->me_psize; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (env->me_txns) |
|
|
|
|
|
|
|
env->me_txns->mti_txnid = meta.mm_txnid; |
|
|
|
|
|
|
|
|
|
|
|
#if MDB_DEBUG |
|
|
|
#if MDB_DEBUG |
|
|
|
{ |
|
|
|
{ |
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env); |
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env); |
|
|
@ -4967,9 +4982,6 @@ static int ESECT |
|
|
|
mdb_env_share_locks(MDB_env *env, int *excl) |
|
|
|
mdb_env_share_locks(MDB_env *env, int *excl) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int rc = 0; |
|
|
|
int rc = 0; |
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
env->me_txns->mti_txnid = meta->mm_txnid; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
|
{ |
|
|
|
{ |
|
|
@ -5391,7 +5403,7 @@ fail: |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT) |
|
|
|
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT) |
|
|
|
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \ |
|
|
|
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \ |
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVMETA) |
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVSNAPSHOT) |
|
|
|
|
|
|
|
|
|
|
|
#if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS) |
|
|
|
#if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS) |
|
|
|
# error "Persistent DB flags & env flags overlap, but both go in mm_flags" |
|
|
|
# error "Persistent DB flags & env flags overlap, but both go in mm_flags" |
|
|
@ -5477,6 +5489,10 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
rc = mdb_env_setup_locks(env, &fname, mode, &excl); |
|
|
|
rc = mdb_env_setup_locks(env, &fname, mode, &excl); |
|
|
|
if (rc) |
|
|
|
if (rc) |
|
|
|
goto leave; |
|
|
|
goto leave; |
|
|
|
|
|
|
|
if ((flags & MDB_PREVSNAPSHOT) && !excl) { |
|
|
|
|
|
|
|
rc = EAGAIN; |
|
|
|
|
|
|
|
goto leave; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rc = mdb_fopen(env, &fname, |
|
|
|
rc = mdb_fopen(env, &fname, |
|
|
@ -5491,7 +5507,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
goto leave; |
|
|
|
goto leave; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVMETA)) == MDB_SUCCESS) { |
|
|
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVSNAPSHOT)) == MDB_SUCCESS) { |
|
|
|
if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) { |
|
|
|
if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) { |
|
|
|
/* Synchronous fd for meta writes. Needed even with
|
|
|
|
/* Synchronous fd for meta writes. Needed even with
|
|
|
|
* MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset. |
|
|
|
* MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset. |
|
|
@ -5501,7 +5517,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
goto leave; |
|
|
|
goto leave; |
|
|
|
} |
|
|
|
} |
|
|
|
DPRINTF(("opened dbenv %p", (void *) env)); |
|
|
|
DPRINTF(("opened dbenv %p", (void *) env)); |
|
|
|
if (excl > 0) { |
|
|
|
if (excl > 0 && !(flags & MDB_PREVSNAPSHOT)) { |
|
|
|
rc = mdb_env_share_locks(env, &excl); |
|
|
|
rc = mdb_env_share_locks(env, &excl); |
|
|
|
if (rc) |
|
|
|
if (rc) |
|
|
|
goto leave; |
|
|
|
goto leave; |
|
|
|