|
|
|
@ -1074,8 +1074,6 @@ struct MDB_env { |
|
|
|
|
HANDLE me_mfd; /**< just for writing the meta pages */ |
|
|
|
|
/** Failed to update the meta page. Probably an I/O error. */ |
|
|
|
|
#define MDB_FATAL_ERROR 0x80000000U |
|
|
|
|
/** We're explicitly changing the mapsize. */ |
|
|
|
|
#define MDB_RESIZING 0x40000000U |
|
|
|
|
/** Some fields are initialized. */ |
|
|
|
|
#define MDB_ENV_ACTIVE 0x20000000U |
|
|
|
|
/** me_txkey is set */ |
|
|
|
@ -2537,9 +2535,7 @@ mdb_txn_renew0(MDB_txn *txn) |
|
|
|
|
} |
|
|
|
|
txn->mt_dbflags[0] = txn->mt_dbflags[1] = DB_VALID; |
|
|
|
|
|
|
|
|
|
/* If we didn't ask for a resize, but the size grew, fail */ |
|
|
|
|
if (!(env->me_flags & MDB_RESIZING) |
|
|
|
|
&& env->me_mapsize < meta->mm_mapsize) { |
|
|
|
|
if (env->me_maxpg < txn->mt_next_pgno) { |
|
|
|
|
mdb_txn_reset0(txn, "renew0-mapfail"); |
|
|
|
|
if (new_notls) { |
|
|
|
|
txn->mt_u.reader->mr_pid = 0; |
|
|
|
@ -3277,13 +3273,8 @@ mdb_txn_commit(MDB_txn *txn) |
|
|
|
|
mdb_cursors_close(txn, 0); |
|
|
|
|
|
|
|
|
|
if (!txn->mt_u.dirty_list[0].mid && |
|
|
|
|
!(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS))) { |
|
|
|
|
if ((env->me_flags & MDB_RESIZING) |
|
|
|
|
&& (rc = mdb_env_write_meta(txn))) { |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
!(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS))) |
|
|
|
|
goto done; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DPRINTF(("committing txn %"Z"u %p on mdbenv %p, root page %"Z"u", |
|
|
|
|
txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root)); |
|
|
|
@ -3324,6 +3315,7 @@ mdb_txn_commit(MDB_txn *txn) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if ((rc = mdb_page_flush(txn, 0)) || |
|
|
|
|
(rc = mdb_env_sync(env, 0)) || |
|
|
|
|
(rc = mdb_env_write_meta(txn))) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
@ -3480,7 +3472,7 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta) |
|
|
|
|
static int |
|
|
|
|
mdb_env_write_meta(MDB_txn *txn) |
|
|
|
|
{ |
|
|
|
|
MDB_env *env = txn->mt_env; |
|
|
|
|
MDB_env *env; |
|
|
|
|
MDB_meta meta, metab, *mp; |
|
|
|
|
off_t off; |
|
|
|
|
int rc, len, toggle; |
|
|
|
@ -3492,22 +3484,17 @@ mdb_env_write_meta(MDB_txn *txn) |
|
|
|
|
int r2; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* Sync data and previous metapage before writing a new metapage */ |
|
|
|
|
if ((rc = mdb_env_sync(env, 0)) != MDB_SUCCESS) |
|
|
|
|
return rc; |
|
|
|
|
|
|
|
|
|
toggle = txn->mt_txnid & 1; |
|
|
|
|
DPRINTF(("writing meta page %d for root page %"Z"u", |
|
|
|
|
toggle, txn->mt_dbs[MAIN_DBI].md_root)); |
|
|
|
|
|
|
|
|
|
env = txn->mt_env; |
|
|
|
|
mp = env->me_metas[toggle]; |
|
|
|
|
|
|
|
|
|
if (env->me_flags & MDB_WRITEMAP) { |
|
|
|
|
/* Persist any changes of mapsize config */ |
|
|
|
|
if (env->me_flags & MDB_RESIZING) { |
|
|
|
|
/* Persist any increases of mapsize config */ |
|
|
|
|
if (env->me_mapsize > mp->mm_mapsize) |
|
|
|
|
mp->mm_mapsize = env->me_mapsize; |
|
|
|
|
env->me_flags ^= MDB_RESIZING; |
|
|
|
|
} |
|
|
|
|
mp->mm_dbs[0] = txn->mt_dbs[0]; |
|
|
|
|
mp->mm_dbs[1] = txn->mt_dbs[1]; |
|
|
|
|
mp->mm_last_pg = txn->mt_next_pgno - 1; |
|
|
|
@ -3535,11 +3522,10 @@ mdb_env_write_meta(MDB_txn *txn) |
|
|
|
|
metab.mm_last_pg = env->me_metas[toggle]->mm_last_pg; |
|
|
|
|
|
|
|
|
|
ptr = (char *)&meta; |
|
|
|
|
if (env->me_flags & MDB_RESIZING) { |
|
|
|
|
/* Persist any changes of mapsize config */ |
|
|
|
|
if (env->me_mapsize > mp->mm_mapsize) { |
|
|
|
|
/* Persist any increases of mapsize config */ |
|
|
|
|
meta.mm_mapsize = env->me_mapsize; |
|
|
|
|
off = offsetof(MDB_meta, mm_mapsize); |
|
|
|
|
env->me_flags ^= MDB_RESIZING; |
|
|
|
|
} else { |
|
|
|
|
off = offsetof(MDB_meta, mm_dbs[0].md_depth); |
|
|
|
|
} |
|
|
|
@ -3728,25 +3714,19 @@ mdb_env_set_mapsize(MDB_env *env, size_t size) |
|
|
|
|
* sure there are no active txns. |
|
|
|
|
*/ |
|
|
|
|
if (env->me_map) { |
|
|
|
|
int rc, change = 0; |
|
|
|
|
int rc; |
|
|
|
|
void *old; |
|
|
|
|
if (env->me_txn) |
|
|
|
|
return EINVAL; |
|
|
|
|
if (!size) |
|
|
|
|
size = env->me_metas[mdb_env_pick_meta(env)]->mm_mapsize; |
|
|
|
|
else { |
|
|
|
|
if (size < env->me_mapsize) { |
|
|
|
|
/* If the configured size is smaller, make sure it's
|
|
|
|
|
* still big enough. Silently round up to minimum if not. |
|
|
|
|
*/ |
|
|
|
|
size_t minsize = (env->me_metas[mdb_env_pick_meta(env)]->mm_last_pg + 1) * env->me_psize; |
|
|
|
|
if (size < minsize) |
|
|
|
|
size = minsize; |
|
|
|
|
} |
|
|
|
|
/* nothing actually changed */ |
|
|
|
|
if (size == env->me_mapsize) |
|
|
|
|
return MDB_SUCCESS; |
|
|
|
|
change = 1; |
|
|
|
|
else if (size < env->me_mapsize) { |
|
|
|
|
/* If the configured size is smaller, make sure it's
|
|
|
|
|
* still big enough. Silently round up to minimum if not. |
|
|
|
|
*/ |
|
|
|
|
size_t minsize = (env->me_metas[mdb_env_pick_meta(env)]->mm_last_pg + 1) * env->me_psize; |
|
|
|
|
if (size < minsize) |
|
|
|
|
size = minsize; |
|
|
|
|
} |
|
|
|
|
munmap(env->me_map, env->me_mapsize); |
|
|
|
|
env->me_mapsize = size; |
|
|
|
@ -3754,8 +3734,6 @@ mdb_env_set_mapsize(MDB_env *env, size_t size) |
|
|
|
|
rc = mdb_env_map(env, old); |
|
|
|
|
if (rc) |
|
|
|
|
return rc; |
|
|
|
|
if (change) |
|
|
|
|
env->me_flags |= MDB_RESIZING; |
|
|
|
|
} |
|
|
|
|
env->me_mapsize = size; |
|
|
|
|
if (env->me_psize) |
|
|
|
@ -3828,17 +3806,13 @@ mdb_env_open2(MDB_env *env) |
|
|
|
|
* else use the size recorded in the existing env. |
|
|
|
|
*/ |
|
|
|
|
env->me_mapsize = newenv ? DEFAULT_MAPSIZE : meta.mm_mapsize; |
|
|
|
|
} else { |
|
|
|
|
if (env->me_mapsize < meta.mm_mapsize) { |
|
|
|
|
/* If the configured size is smaller, make sure it's
|
|
|
|
|
* still big enough. Silently round up to minimum if not. |
|
|
|
|
*/ |
|
|
|
|
size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize; |
|
|
|
|
if (env->me_mapsize < minsize) |
|
|
|
|
env->me_mapsize = minsize; |
|
|
|
|
} |
|
|
|
|
if (env->me_mapsize != meta.mm_mapsize) |
|
|
|
|
env->me_flags |= MDB_RESIZING; |
|
|
|
|
} else if (env->me_mapsize < meta.mm_mapsize) { |
|
|
|
|
/* If the configured size is smaller, make sure it's
|
|
|
|
|
* still big enough. Silently round up to minimum if not. |
|
|
|
|
*/ |
|
|
|
|
size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize; |
|
|
|
|
if (env->me_mapsize < minsize) |
|
|
|
|
env->me_mapsize = minsize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta.mm_address : NULL); |
|
|
|
|