summaryrefslogtreecommitdiff
path: root/src/os/os_map.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-02-17 17:25:57 +0000
committer <>2015-03-17 16:26:24 +0000
commit780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch)
tree598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/os/os_map.c
parent7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff)
downloadberkeleydb-master.tar.gz
Imported from /home/lorry/working-area/delta_berkeleydb/db-6.1.23.tar.gz.HEADdb-6.1.23master
Diffstat (limited to 'src/os/os_map.c')
-rw-r--r--src/os/os_map.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/os/os_map.c b/src/os/os_map.c
index 0528f473..b17bf107 100644
--- a/src/os/os_map.c
+++ b/src/os/os_map.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -213,6 +213,15 @@ __os_attach(env, infop, rp)
if (rp->max < rp->size)
rp->max = rp->size;
if (ret == 0 && F_ISSET(infop, REGION_CREATE)) {
+#ifdef HAVE_MLOCK
+ /*
+ * When locking the region in memory extend it fully so that it
+ * can all be mlock()'d now, and not later when paging could
+ * interfere with the application. [#21379]
+ */
+ if (F_ISSET(env, ENV_LOCKDOWN))
+ rp->size = rp->max;
+#endif
if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
ret = __db_file_write(env, infop->fhp,
rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00);
@@ -255,7 +264,7 @@ __os_detach(env, infop, destroy)
{
DB_ENV *dbenv;
REGION *rp;
- int ret;
+ int ret, t_ret;
/*
* We pass a DB_ENV handle to the user's replacement unmap function,
@@ -263,8 +272,16 @@ __os_detach(env, infop, destroy)
*/
DB_ASSERT(env, env != NULL && env->dbenv != NULL);
dbenv = env->dbenv;
+ ret = 0;
+ /*
+ * Don't use a region which is no longer valid, e.g., after the
+ * env has been removed.
+ */
rp = infop->rp;
+ if ((rp->id != 0 && rp->id != infop->id) ||
+ rp->type <= INVALID_REGION_TYPE || rp->type > REGION_TYPE_MAX)
+ return (EINVAL);
/* If the user replaced the unmap call, call through their interface. */
if (DB_GLOBAL(j_region_unmap) != NULL)
@@ -314,16 +331,26 @@ __os_detach(env, infop, destroy)
return (ret);
}
+ if (F_ISSET(env, ENV_FORCESYNCENV))
+ if (msync(infop->addr, rp->max, MS_INVALIDATE | MS_SYNC) != 0) {
+ t_ret = __os_get_syserr();
+ __db_syserr(env, t_ret, DB_STR("0248",
+ "msync failed on closing environment"));
+ if (ret == 0)
+ ret = t_ret;
+ }
+
if (munmap(infop->addr, rp->max) != 0) {
- ret = __os_get_syserr();
- __db_syserr(env, ret, DB_STR("0123", "munmap"));
- return (__os_posix_err(ret));
+ t_ret = __os_get_syserr();
+ __db_syserr(env, t_ret, DB_STR("0123", "munmap"));
+ if (ret == 0)
+ ret = t_ret;
}
- if (destroy && (ret = __os_unlink(env, infop->name, 1)) != 0)
- return (ret);
+ if (destroy && (t_ret = __os_unlink(env, infop->name, 1)) != 0 && ret == 0)
+ ret = t_ret;
- return (0);
+ return (ret);
#else
COMPQUIET(destroy, 0);
COMPQUIET(ret, 0);