about summary refs log tree commit diff
path: root/db2
diff options
context:
space:
mode:
Diffstat (limited to 'db2')
-rw-r--r--db2/Makefile4
-rw-r--r--db2/btree/bt_close.c8
-rw-r--r--db2/btree/bt_cursor.c30
-rw-r--r--db2/btree/bt_delete.c7
-rw-r--r--db2/btree/bt_open.c19
-rw-r--r--db2/btree/bt_page.c26
-rw-r--r--db2/btree/bt_put.c19
-rw-r--r--db2/btree/bt_rec.c113
-rw-r--r--db2/btree/bt_recno.c31
-rw-r--r--db2/btree/btree_auto.c22
-rw-r--r--db2/common/db_appinit.c7
-rw-r--r--db2/common/db_apprec.c129
-rw-r--r--db2/common/db_err.c28
-rw-r--r--db2/common/db_region.c77
-rw-r--r--db2/common/db_shash.c10
-rw-r--r--db2/db.h129
-rw-r--r--db2/db/db.c18
-rw-r--r--db2/db/db_auto.c22
-rw-r--r--db2/db/db_conv.c6
-rw-r--r--db2/db/db_dispatch.c11
-rw-r--r--db2/db/db_dup.c7
-rw-r--r--db2/db/db_pr.c4
-rw-r--r--db2/db/db_rec.c12
-rw-r--r--db2/db185/db185.c2
-rw-r--r--db2/db_185.h8
-rw-r--r--db2/db_int.h29
-rw-r--r--db2/dbm/dbm.c76
-rw-r--r--db2/hash/hash.c52
-rw-r--r--db2/hash/hash_auto.c20
-rw-r--r--db2/hash/hash_dup.c24
-rw-r--r--db2/hash/hash_page.c13
-rw-r--r--db2/hash/hash_rec.c4
-rw-r--r--db2/include/btree_ext.h18
-rw-r--r--db2/include/clib_ext.h3
-rw-r--r--db2/include/common_ext.h5
-rw-r--r--db2/include/db.h.src129
-rw-r--r--db2/include/db_185.h.src4
-rw-r--r--db2/include/db_am.h4
-rw-r--r--db2/include/db_ext.h14
-rw-r--r--db2/include/db_int.h.src29
-rw-r--r--db2/include/hash_ext.h15
-rw-r--r--db2/include/lock_ext.h12
-rw-r--r--db2/include/log.h13
-rw-r--r--db2/include/log_auto.h11
-rw-r--r--db2/include/log_ext.h16
-rw-r--r--db2/include/mp.h33
-rw-r--r--db2/include/mp_ext.h3
-rw-r--r--db2/include/mutex_ext.h5
-rw-r--r--db2/include/os_ext.h7
-rw-r--r--db2/include/os_func.h6
-rw-r--r--db2/include/txn_ext.h3
-rw-r--r--db2/lock/lock.c48
-rw-r--r--db2/lock/lock_util.c10
-rw-r--r--db2/log/log.c67
-rw-r--r--db2/log/log.src9
-rw-r--r--db2/log/log_archive.c4
-rw-r--r--db2/log/log_auto.c140
-rw-r--r--db2/log/log_get.c26
-rw-r--r--db2/log/log_put.c13
-rw-r--r--db2/log/log_rec.c102
-rw-r--r--db2/log/log_register.c55
-rw-r--r--db2/makedb.c6
-rw-r--r--db2/mp/mp_bh.c131
-rw-r--r--db2/mp/mp_fget.c13
-rw-r--r--db2/mp/mp_fopen.c34
-rw-r--r--db2/mp/mp_fput.c4
-rw-r--r--db2/mp/mp_pr.c4
-rw-r--r--db2/mp/mp_sync.c29
-rw-r--r--db2/mutex/mutex.c16
-rw-r--r--db2/os/os_alloc.c75
-rw-r--r--db2/os/os_config.c75
-rw-r--r--db2/os/os_stat.c31
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c5
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c4
-rw-r--r--db2/progs/db_load/db_load.c55
-rw-r--r--db2/progs/db_printlog/db_printlog.c5
-rw-r--r--db2/progs/db_recover/db_recover.c4
-rw-r--r--db2/progs/db_stat/db_stat.c19
-rw-r--r--db2/txn/txn.c12
79 files changed, 1313 insertions, 980 deletions
diff --git a/db2/Makefile b/db2/Makefile
index 0ae06a3089..02f1b300e6 100644
--- a/db2/Makefile
+++ b/db2/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+# Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -58,7 +58,7 @@ libdb-routines := bt_close bt_compare bt_conv bt_cursor bt_delete \
 	bt_open bt_page bt_put bt_rec bt_recno bt_rsearch bt_search \
 	bt_split bt_stat btree_auto db db_appinit db_apprec \
 	db_auto \
-	db_byteorder db_conv db_dispatch db_dup db_err db_log2 \
+	db_byteorder db_conv db_dispatch db_dup db_err db_log2 os_alloc \
 	os_abs os_config os_dir os_fid os_fsync os_map os_oflags \
 	os_open os_rpath os_rw os_seek os_sleep os_stat os_unlink \
 	os_spin db_overflow db_pr db_rec db_region db_ret db_salloc \
diff --git a/db2/btree/bt_close.c b/db2/btree/bt_close.c
index 7dd7139c66..ecccc9fe08 100644
--- a/db2/btree/bt_close.c
+++ b/db2/btree/bt_close.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_close.c	10.24 (Sleepycat) 9/17/97";
+static const char sccsid[] = "@(#)bt_close.c	10.25 (Sleepycat) 1/6/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -144,7 +144,7 @@ __bam_upstat(dbp)
 {
 	BTREE *t;
 	BTMETA *meta;
-	DB_LOCK mlock;
+	DB_LOCK metalock;
 	db_pgno_t pgno;
 	int flags, ret;
 
@@ -161,7 +161,7 @@ __bam_upstat(dbp)
 	pgno = PGNO_METADATA;
 
 	/* Lock and retrieve the page. */
-	if (__bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &mlock) != 0)
+	if (__bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &metalock) != 0)
 		return;
 	if (__bam_pget(dbp, (PAGE **)&meta, &pgno, 0) == 0) {
 		/* Log the change. */
@@ -178,5 +178,5 @@ __bam_upstat(dbp)
 	}
 
 err:	(void)memp_fput(dbp->mpf, (PAGE *)meta, flags);
-	(void)__BT_LPUT(dbp, mlock);
+	(void)__BT_LPUT(dbp, metalock);
 }
diff --git a/db2/btree/bt_cursor.c b/db2/btree/bt_cursor.c
index 47ecd7c66d..f526c965e5 100644
--- a/db2/btree/bt_cursor.c
+++ b/db2/btree/bt_cursor.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_cursor.c	10.37 (Sleepycat) 11/22/97";
+static const char sccsid[] = "@(#)bt_cursor.c	10.41 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -128,22 +128,25 @@ __bam_c_iclose(dbp, dbc)
 	CURSOR *cp;
 	int ret;
 
-	cp = dbc->internal;
+	/*
+	 * All cursors are queued from the master DB structure.  For
+	 * now, discard the DB handle which triggered this call, and
+	 * replace it with the cursor's reference.
+	 */
+	dbp = dbc->dbp;
 
 	/* If a cursor key was deleted, perform the actual deletion.  */
+	cp = dbc->internal;
 	ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0;
 
 	/* Discard any lock if we're not inside a transaction. */
 	if (cp->lock != LOCK_INVALID)
 		(void)__BT_TLPUT(dbp, cp->lock);
 
-	/*
-	 * All cursors are queued from the master DB structure.  Remove the
-	 * cursor from that queue.
-	 */
-	DB_THREAD_LOCK(dbc->dbp);
-	TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
-	DB_THREAD_UNLOCK(dbc->dbp);
+	/* Remove the cursor from the queue. */
+	DB_THREAD_LOCK(dbp);
+	TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
+	DB_THREAD_UNLOCK(dbp);
 
 	/* Discard the structures. */
 	FREE(dbc->internal, sizeof(CURSOR));
@@ -452,6 +455,8 @@ __bam_c_rget(dbp, cp, data, flags)
 	db_recno_t recno;
 	int exact, ret;
 
+	COMPQUIET(flags, 0);
+
 	/* Get the page with the current item on it. */
 	if ((ret = __bam_pget(dbp, &cp->page, &cp->pgno, 0)) != 0)
 		return (ret);
@@ -1086,6 +1091,8 @@ __bam_ovfl_chk(dbp, cp, indx, to_end)
 /*
  * __bam_cprint --
  *	Display the current btree cursor list.
+ *
+ * PUBLIC: int __bam_cprint __P((DB *));
  */
 int
 __bam_cprint(dbp)
@@ -1258,12 +1265,11 @@ __bam_ca_dup(dbp, fpgno, first, fi, tpgno, ti)
  * __bam_ca_move --
  *	Adjust the cursors when moving data items to another page.
  *
- * PUBLIC: void __bam_ca_move __P((DB *, BTREE *, db_pgno_t, db_pgno_t));
+ * PUBLIC: void __bam_ca_move __P((DB *, db_pgno_t, db_pgno_t));
  */
 void
-__bam_ca_move(dbp, t, fpgno, tpgno)
+__bam_ca_move(dbp, fpgno, tpgno)
 	DB *dbp;
-	BTREE *t;
 	db_pgno_t fpgno, tpgno;
 {
 	CURSOR *cp;
diff --git a/db2/btree/bt_delete.c b/db2/btree/bt_delete.c
index dbd1995f89..baa8a25401 100644
--- a/db2/btree/bt_delete.c
+++ b/db2/btree/bt_delete.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_delete.c	10.23 (Sleepycat) 11/22/97";
+static const char sccsid[] = "@(#)bt_delete.c	10.25 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -500,7 +500,8 @@ __bam_dpages(dbp, t)
 	db_recno_t rcnt;
 	int ret;
 
-	rcnt = 0;				/* XXX: Shut the compiler up. */
+	COMPQUIET(rcnt, 0);
+
 	epg = t->bt_sp;
 
 	/*
@@ -581,7 +582,7 @@ __bam_dpages(dbp, t)
 		++t->lstat.bt_freed;
 
 		/* Adjust the cursors. */
-		__bam_ca_move(dbp, t, h->pgno, PGNO_ROOT);
+		__bam_ca_move(dbp, h->pgno, PGNO_ROOT);
 	}
 
 	/* Release the top page in the subtree. */
diff --git a/db2/btree/bt_open.c b/db2/btree/bt_open.c
index 2361f69a3e..dd9f10927a 100644
--- a/db2/btree/bt_open.c
+++ b/db2/btree/bt_open.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_open.c	10.21 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)bt_open.c	10.22 (Sleepycat) 1/6/98";
 #endif /* not lint */
 
 /*
@@ -265,18 +265,18 @@ __bam_setmeta(dbp, t)
 {
 	BTMETA *meta;
 	PAGE *root;
-	DB_LOCK mlock, rlock;
+	DB_LOCK metalock, rootlock;
 	db_pgno_t pgno;
 	int ret;
 
 	/* Get, and optionally create the metadata page. */
 	pgno = PGNO_METADATA;
 	if ((ret =
-	    __bam_lget(dbp, 0, PGNO_METADATA, DB_LOCK_WRITE, &mlock)) != 0)
+	    __bam_lget(dbp, 0, PGNO_METADATA, DB_LOCK_WRITE, &metalock)) != 0)
 		return (ret);
 	if ((ret =
 	    __bam_pget(dbp, (PAGE **)&meta, &pgno, DB_MPOOL_CREATE)) != 0) {
-		(void)__BT_LPUT(dbp, mlock);
+		(void)__BT_LPUT(dbp, metalock);
 		return (ret);
 	}
 
@@ -290,7 +290,7 @@ __bam_setmeta(dbp, t)
 		t->bt_minkey = meta->minkey;
 
 		(void)memp_fput(dbp->mpf, (PAGE *)meta, 0);
-		(void)__BT_LPUT(dbp, mlock);
+		(void)__BT_LPUT(dbp, metalock);
 		return (0);
 	}
 
@@ -320,10 +320,11 @@ __bam_setmeta(dbp, t)
 
 	/* Create and initialize a root page. */
 	pgno = PGNO_ROOT;
-	if ((ret = __bam_lget(dbp, 0, PGNO_ROOT, DB_LOCK_WRITE, &rlock)) != 0)
+	if ((ret =
+	    __bam_lget(dbp, 0, PGNO_ROOT, DB_LOCK_WRITE, &rootlock)) != 0)
 		return (ret);
 	if ((ret = __bam_pget(dbp, &root, &pgno, DB_MPOOL_CREATE)) != 0) {
-		(void)__BT_LPUT(dbp, rlock);
+		(void)__BT_LPUT(dbp, rootlock);
 		return (ret);
 	}
 	P_INIT(root, dbp->pgsize, PGNO_ROOT, PGNO_INVALID,
@@ -348,8 +349,8 @@ __bam_setmeta(dbp, t)
 		ret = EINVAL;
 
 	/* Release the locks. */
-	(void)__BT_LPUT(dbp, mlock);
-	(void)__BT_LPUT(dbp, rlock);
+	(void)__BT_LPUT(dbp, metalock);
+	(void)__BT_LPUT(dbp, rootlock);
 
 	return (ret);
 }
diff --git a/db2/btree/bt_page.c b/db2/btree/bt_page.c
index 7ee74ffcf8..853317e835 100644
--- a/db2/btree/bt_page.c
+++ b/db2/btree/bt_page.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_page.c	10.5 (Sleepycat) 8/18/97";
+static const char sccsid[] = "@(#)bt_page.c	10.7 (Sleepycat) 1/7/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -75,17 +75,17 @@ __bam_new(dbp, type, pagepp)
 	PAGE **pagepp;
 {
 	BTMETA *meta;
-	DB_LOCK mlock;
+	DB_LOCK metalock;
 	PAGE *h;
 	db_pgno_t pgno;
 	int ret;
 
 	meta = NULL;
 	h = NULL;
-	mlock = LOCK_INVALID;
+	metalock = LOCK_INVALID;
 
 	pgno = PGNO_METADATA;
-	if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &mlock)) != 0)
+	if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &metalock)) != 0)
 		goto err;
 	if ((ret = __bam_pget(dbp, (PAGE **)&meta, &pgno, 0)) != 0)
 		goto err;
@@ -112,7 +112,7 @@ __bam_new(dbp, type, pagepp)
 	}
 
 	(void)memp_fput(dbp->mpf, (PAGE *)meta, DB_MPOOL_DIRTY);
-	(void)__BT_TLPUT(dbp, mlock);
+	(void)__BT_TLPUT(dbp, metalock);
 
 	P_INIT(h, dbp->pgsize, h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type);
 	*pagepp = h;
@@ -122,8 +122,8 @@ err:	if (h != NULL)
 		(void)memp_fput(dbp->mpf, h, 0);
 	if (meta != NULL)
 		(void)memp_fput(dbp->mpf, meta, 0);
-	if (mlock != LOCK_INVALID)
-		(void)__BT_TLPUT(dbp, mlock);
+	if (metalock != LOCK_INVALID)
+		(void)__BT_TLPUT(dbp, metalock);
 	return (ret);
 }
 
@@ -140,7 +140,7 @@ __bam_free(dbp, h)
 {
 	BTMETA *meta;
 	DBT ldbt;
-	DB_LOCK mlock;
+	DB_LOCK metalock;
 	db_pgno_t pgno;
 	int is_dirty, ret, t_ret;
 
@@ -152,10 +152,10 @@ __bam_free(dbp, h)
 	 */
 	is_dirty = 0;
 	pgno = PGNO_METADATA;
-	if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &mlock)) != 0)
+	if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_WRITE, &metalock)) != 0)
 		goto err;
 	if ((ret = __bam_pget(dbp, (PAGE **)&meta, &pgno, 0)) != 0) {
-		(void)__BT_TLPUT(dbp, mlock);
+		(void)__BT_TLPUT(dbp, metalock);
 		goto err;
 	}
 
@@ -168,7 +168,7 @@ __bam_free(dbp, h)
 		    dbp->txn, &meta->lsn, 0, dbp->log_fileid, h->pgno,
 		    &meta->lsn, &ldbt, meta->free)) != 0) {
 			(void)memp_fput(dbp->mpf, (PAGE *)meta, 0);
-			(void)__BT_TLPUT(dbp, mlock);
+			(void)__BT_TLPUT(dbp, metalock);
 			return (ret);
 		}
 		LSN(h) = LSN(meta);
@@ -194,7 +194,7 @@ __bam_free(dbp, h)
 
 	/* Discard the metadata page. */
 	ret = memp_fput(dbp->mpf, (PAGE *)meta, DB_MPOOL_DIRTY);
-	if ((t_ret = __BT_TLPUT(dbp, mlock)) != 0)
+	if ((t_ret = __BT_TLPUT(dbp, metalock)) != 0)
 		ret = t_ret;
 
 	/* Discard the caller's page reference. */
@@ -213,6 +213,8 @@ err:	if ((t_ret = memp_fput(dbp->mpf, h, is_dirty)) != 0 && ret == 0)
 /*
  * __bam_lt --
  *	Print out the list of currently held locks.
+ *
+ * PUBLIC: int __bam_lt __P((DB *));
  */
 int
 __bam_lt(dbp)
diff --git a/db2/btree/bt_put.c b/db2/btree/bt_put.c
index 3161b02b55..87f3fd9aff 100644
--- a/db2/btree/bt_put.c
+++ b/db2/btree/bt_put.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_put.c	10.35 (Sleepycat) 11/22/97";
+static const char sccsid[] = "@(#)bt_put.c	10.38 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -69,8 +69,7 @@ static int __bam_lookup __P((DB *, DBT *, int *));
 static int __bam_ndup __P((DB *, PAGE *, u_int32_t));
 static int __bam_ovput __P((DB *, PAGE *, u_int32_t, DBT *));
 static int __bam_partial __P((DB *, DBT *, PAGE *, u_int32_t, u_int32_t));
-static u_int32_t
-	   __bam_partsize __P((DB *, DBT *, PAGE *, u_int32_t));
+static u_int32_t __bam_partsize __P((DBT *, PAGE *, u_int32_t));
 
 /*
  * __bam_put --
@@ -446,11 +445,11 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
 	u_int32_t data_size, have_bytes, need_bytes, needed;
 	int bigkey, bigdata, dupadjust, replace, ret;
 
+	COMPQUIET(bk, NULL);
+
 	t = dbp->internal;
 	h = *hp;
 	indx = *indxp;
-
-	bk = NULL;			/* XXX: Shut the compiler up. */
 	dupadjust = replace = 0;
 
 	/*
@@ -490,7 +489,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
 	 */
 	bigkey = LF_ISSET(BI_NEWKEY) && key->size > t->bt_ovflsize;
 	data_size = F_ISSET(data, DB_DBT_PARTIAL) ?
-	    __bam_partsize(dbp, data, h, indx) : data->size;
+	    __bam_partsize(data, h, indx) : data->size;
 	bigdata = data_size > t->bt_ovflsize;
 
 	needed = 0;
@@ -626,7 +625,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
 			/*
 			 * 5. Delete/re-add the data item.
 			 *
-			 * If we're dealing with offpage items, we have to 
+			 * If we're dealing with offpage items, we have to
 			 * delete and then re-add the item.
 			 */
 			if (bigdata || B_TYPE(bk->type) != B_KEYDATA) {
@@ -693,8 +692,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
  *	Figure out how much space a partial data item is in total.
  */
 static u_int32_t
-__bam_partsize(dbp, data, h, indx)
-	DB *dbp;
+__bam_partsize(data, h, indx)
 	DBT *data;
 	PAGE *h;
 	u_int32_t indx;
@@ -1041,7 +1039,8 @@ __bam_partial(dbp, dbt, h, indx, nbytes)
 	int ret;
 	u_int8_t *p;
 
-	bo = NULL;			/* XXX: Shut the compiler up. */
+	COMPQUIET(bo, NULL);
+
 	t = dbp->internal;
 
 	/* We use the record data return memory, it's only a short-term use. */
diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c
index c0b7c8ae4c..90ee13764e 100644
--- a/db2/btree/bt_rec.c
+++ b/db2/btree/bt_rec.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_rec.c	10.17 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)bt_rec.c	10.18 (Sleepycat) 12/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -69,10 +69,17 @@ __bam_pg_alloc_recover(logp, dbtp, lsnp, redo, info)
 	 */
 	pgno = PGNO_METADATA;
 	if ((ret = memp_fget(mpf, &pgno, 0, &meta)) != 0) {
+		/* The metadata page must always exist. */
 		(void)__db_pgerr(file_dbp, pgno);
 		goto out;
 	}
 	if ((ret = memp_fget(mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
+		/*
+		 * We specify creation and check for it later, because this
+		 * operation was supposed to create the page, and even in
+		 * the undo case it's going to get linked onto the freelist
+		 * which we're also fixing up.
+		 */
 		(void)__db_pgerr(file_dbp, argp->pgno);
 		(void)memp_fput(mpf, meta, 0);
 		goto out;
@@ -162,6 +169,15 @@ __bam_pg_free_recover(logp, dbtp, lsnp, redo, info)
 	 * we're undoing the operation, we get the page and restore its header.
 	 */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		/*
+		 * We don't automatically create the page.  The only way the
+		 * page might not exist is if the alloc never happened, and
+		 * the only way the alloc might never have happened is if we
+		 * are undoing, in which case there's no reason to create the
+		 * page.
+		 */
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
 		goto out;
 	}
@@ -192,6 +208,7 @@ __bam_pg_free_recover(logp, dbtp, lsnp, redo, info)
 	 */
 	pgno = PGNO_METADATA;
 	if ((ret = memp_fget(mpf, &pgno, 0, &meta)) != 0) {
+		/* The metadata page must always exist. */
 		(void)__db_pgerr(file_dbp, pgno);
 		goto out;
 	}
@@ -217,7 +234,7 @@ __bam_pg_free_recover(logp, dbtp, lsnp, redo, info)
 		goto out;
 	}
 
-	*lsnp = argp->prev_lsn;
+done:	*lsnp = argp->prev_lsn;
 	ret = 0;
 
 out:	REC_CLOSE;
@@ -389,7 +406,7 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 		 * interest only if it wasn't a root split -- inserting a new
 		 * page in the tree requires that any following page have its
 		 * previous-page pointer updated to our new page.  The next
-		 * page had better exist.
+		 * page must exist because we're redoing the operation.
 		 */
 		if (!rootsplit && !IS_ZERO_LSN(argp->nlsn)) {
 			if ((ret = memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
@@ -409,12 +426,14 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 	} else {
 		/*
 		 * If the split page is wrong, replace its contents with the
-		 * logged page contents.  The split page had better exist.
+		 * logged page contents.  If the page doesn't exist, it means
+		 * that the create of the page never happened, nor did any of
+		 * the adds onto the page that caused the split, and there's
+		 * really no undo-ing to be done.
 		 */
 		if ((ret = memp_fget(mpf, &pgno, 0, &pp)) != 0) {
-			(void)__db_pgerr(file_dbp, pgno);
 			pp = NULL;
-			goto out;
+			goto lrundo;
 		}
 		if (log_compare(lsnp, &LSN(pp)) == 0) {
 			memcpy(pp, argp->pg.data, argp->pg.size);
@@ -424,13 +443,14 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 		}
 
 		/*
-		 * If it's a root split and the left child ever existed, put
-		 * it on the free list.  (If it's not a root split, we just
-		 * updated the left page -- it's the same as the split page.)
-		 * If the right child ever existed, root split or not, put it
-		 * on the free list.
+		 * If it's a root split and the left child ever existed, update
+		 * its LSN.  (If it's not a root split, we've updated the left
+		 * page already -- it's the same as the split page.) If the
+		 * right child ever existed, root split or not, update its LSN.
+		 * The undo of the page allocation(s) will restore them to the
+		 * free list.
 		 */
-		if ((rootsplit && lp != NULL) || rp != NULL) {
+lrundo:		if ((rootsplit && lp != NULL) || rp != NULL) {
 			if (rootsplit && lp != NULL &&
 			    log_compare(lsnp, &LSN(lp)) == 0) {
 				lp->lsn = argp->llsn;
@@ -453,14 +473,14 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 		 * Finally, undo the next-page link if necessary.  This is of
 		 * interest only if it wasn't a root split -- inserting a new
 		 * page in the tree requires that any following page have its
-		 * previous-page pointer updated to our new page.  The next
-		 * page had better exist.
+		 * previous-page pointer updated to our new page.  Since it's
+		 * possible that the next-page never existed, we ignore it as
+		 * if there's nothing to undo.
 		 */
 		if (!rootsplit && !IS_ZERO_LSN(argp->nlsn)) {
 			if ((ret = memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
-				(void)__db_pgerr(file_dbp, argp->npgno);
 				np = NULL;
-				goto out;
+				goto done;
 			}
 			if (log_compare(lsnp, &LSN(np)) == 0) {
 				PREV_PGNO(np) = argp->left;
@@ -472,8 +492,8 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 		}
 	}
 
-done:	ret = 0;
-	*lsnp = argp->prev_lsn;
+done:	*lsnp = argp->prev_lsn;
+	ret = 0;
 
 	if (0) {
 fatal:		(void)__db_panic(file_dbp);
@@ -525,8 +545,8 @@ __bam_rsplit_recover(logp, dbtp, lsnp, redo, info)
 	/* Fix the root page. */
 	pgno = PGNO_ROOT;
 	if ((ret = memp_fget(mpf, &pgno, 0, &pagep)) != 0) {
+		/* The root page must always exist. */
 		__db_pgerr(file_dbp, pgno);
-		pagep = NULL;
 		goto out;
 	}
 	modified = 0;
@@ -554,10 +574,15 @@ __bam_rsplit_recover(logp, dbtp, lsnp, redo, info)
 		goto out;
 	}
 
-	/* Fix the page copied over the root page. */
+	/*
+	 * Fix the page copied over the root page.  It's possible that the
+	 * page never made it to disk, so if we're undo-ing and the page
+	 * doesn't exist, it's okay and there's nothing further to do.
+	 */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
-		pagep = NULL;
 		goto out;
 	}
 	modified = 0;
@@ -577,8 +602,8 @@ __bam_rsplit_recover(logp, dbtp, lsnp, redo, info)
 		goto out;
 	}
 
+done:	*lsnp = argp->prev_lsn;
 	ret = 0;
-	*lsnp = argp->prev_lsn;
 
 out:	REC_CLOSE;
 }
@@ -607,9 +632,11 @@ __bam_adj_recover(logp, dbtp, lsnp, redo, info)
 	REC_PRINT(__bam_adj_print);
 	REC_INTRO(__bam_adj_read);
 
+	/* Get the page; if it never existed and we're undoing, we're done. */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
-		pagep = NULL;
 		goto out;
 	}
 
@@ -633,8 +660,11 @@ __bam_adj_recover(logp, dbtp, lsnp, redo, info)
 		LSN(pagep) = argp->lsn;
 		modified = 1;
 	}
-	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) == 0)
-		*lsnp = argp->prev_lsn;
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+done:	*lsnp = argp->prev_lsn;
+	ret = 0;
 
 	if (0) {
 err:		(void)memp_fput(mpf, pagep, 0);
@@ -667,9 +697,11 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
 	REC_PRINT(__bam_cadjust_print);
 	REC_INTRO(__bam_cadjust_read);
 
+	/* Get the page; if it never existed and we're undoing, we're done. */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
-		pagep = NULL;
 		goto out;
 	}
 
@@ -708,8 +740,11 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
 		LSN(pagep) = argp->lsn;
 		modified = 1;
 	}
-	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) == 0)
-		*lsnp = argp->prev_lsn;
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+done:	*lsnp = argp->prev_lsn;
+	ret = 0;
 
 out:	REC_CLOSE;
 }
@@ -738,9 +773,11 @@ __bam_cdel_recover(logp, dbtp, lsnp, redo, info)
 	REC_PRINT(__bam_cdel_print);
 	REC_INTRO(__bam_cdel_read);
 
+	/* Get the page; if it never existed and we're undoing, we're done. */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
-		pagep = NULL;
 		goto out;
 	}
 
@@ -760,8 +797,11 @@ __bam_cdel_recover(logp, dbtp, lsnp, redo, info)
 		LSN(pagep) = argp->lsn;
 		modified = 1;
 	}
-	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) == 0)
-		*lsnp = argp->prev_lsn;
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+done:	*lsnp = argp->prev_lsn;
+	ret = 0;
 
 out:	REC_CLOSE;
 }
@@ -793,9 +833,11 @@ __bam_repl_recover(logp, dbtp, lsnp, redo, info)
 	REC_PRINT(__bam_repl_print);
 	REC_INTRO(__bam_repl_read);
 
+	/* Get the page; if it never existed and we're undoing, we're done. */
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+		if (!redo)
+			goto done;
 		(void)__db_pgerr(file_dbp, argp->pgno);
-		pagep = NULL;
 		goto out;
 	}
 	bk = GET_BKEYDATA(pagep, argp->indx);
@@ -860,8 +902,11 @@ __bam_repl_recover(logp, dbtp, lsnp, redo, info)
 		LSN(pagep) = argp->lsn;
 		modified = 1;
 	}
-	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) == 0)
-		*lsnp = argp->prev_lsn;
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+done:	*lsnp = argp->prev_lsn;
+	ret = 0;
 
 	if (0) {
 err:		(void)memp_fput(mpf, pagep, 0);
diff --git a/db2/btree/bt_recno.c b/db2/btree/bt_recno.c
index 5e1cbc426c..70ab63b8d4 100644
--- a/db2/btree/bt_recno.c
+++ b/db2/btree/bt_recno.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_recno.c	10.22 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)bt_recno.c	10.26 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -72,6 +72,8 @@ __ram_open(dbp, type, dbinfo)
 	RECNO *rp;
 	int ret;
 
+	COMPQUIET(type, DB_RECNO);
+
 	ret = 0;
 
 	/* Allocate and initialize the private RECNO structure. */
@@ -402,12 +404,16 @@ __ram_c_iclose(dbp, dbc)
 	DBC *dbc;
 {
 	/*
-	 * All cursors are queued from the master DB structure.  Remove the
-	 * cursor from that queue.
+	 * All cursors are queued from the master DB structure.  For
+	 * now, discard the DB handle which triggered this call, and
+	 * replace it with the cursor's reference.
 	 */
-	DB_THREAD_LOCK(dbc->dbp);
-	TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
-	DB_THREAD_UNLOCK(dbc->dbp);
+	dbp = dbc->dbp;
+
+	/* Remove the cursor from the queue. */
+	DB_THREAD_LOCK(dbp);
+	TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
+	DB_THREAD_UNLOCK(dbp);
 
 	/* Discard the structures. */
 	FREE(dbc->internal, sizeof(RCURSOR));
@@ -699,6 +705,8 @@ __ram_ca(dbp, recno, op)
 /*
  * __ram_cprint --
  *	Display the current recno cursor list.
+ *
+ * PUBLIC: int __ram_cprint __P((DB *));
  */
 int
 __ram_cprint(dbp)
@@ -844,7 +852,8 @@ __ram_source(dbp, rp, fname)
 	RECNO *rp;
 	const char *fname;
 {
-	off_t size;
+	size_t size;
+	u_int32_t mbytes, bytes;
 	int oflags, ret;
 
 	if ((ret = __db_appname(dbp->dbenv,
@@ -866,15 +875,17 @@ __ram_source(dbp, rp, fname)
 	 * compiler will perpetrate, doing the comparison in a portable way is
 	 * flatly impossible.  Hope that mmap fails if the file is too large.
 	 */
-	if ((ret = __db_ioinfo(rp->re_source, rp->re_fd, &size, NULL)) != 0) {
+	if ((ret = __db_ioinfo(rp->re_source,
+	    rp->re_fd, &mbytes, &bytes, NULL)) != 0) {
 		__db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
 		goto err;
 	}
-	if (size == 0) {
+	if (mbytes == 0 && bytes == 0) {
 		F_SET(rp, RECNO_EOF);
 		return (0);
 	}
 
+	size = mbytes * MEGABYTE + bytes;
 	if ((ret = __db_map(rp->re_fd, (size_t)size, 1, 1, &rp->re_smap)) != 0)
 		goto err;
 	rp->re_cmap = rp->re_smap;
@@ -981,7 +992,7 @@ __ram_writeback(dbp)
 		}
 		memset(pad, rp->re_pad, rp->re_len);
 	} else
-		pad = NULL;			/* XXX: Shut the compiler up. */
+		COMPQUIET(pad, NULL);
 	for (keyno = 1;; ++keyno) {
 		switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) {
 		case 0:
diff --git a/db2/btree/btree_auto.c b/db2/btree/btree_auto.c
index 18b9b34975..18bbd5db37 100644
--- a/db2/btree/btree_auto.c
+++ b/db2/btree/btree_auto.c
@@ -182,7 +182,7 @@ __bam_pg_alloc_read(recbuf, argpp)
 /*
  * PUBLIC: int __bam_pg_free_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, DBT *,
+ * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, const DBT *,
  * PUBLIC:     db_pgno_t));
  */
 int __bam_pg_free_log(logp, txnid, ret_lsnp, flags,
@@ -194,7 +194,7 @@ int __bam_pg_free_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t fileid;
 	db_pgno_t pgno;
 	DB_LSN * meta_lsn;
-	DBT *header;
+	const DBT *header;
 	db_pgno_t next;
 {
 	DBT logrec;
@@ -354,7 +354,7 @@ __bam_pg_free_read(recbuf, argpp)
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
  * PUBLIC:     DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *,
- * PUBLIC:     DBT *));
+ * PUBLIC:     const DBT *));
  */
 int __bam_split_log(logp, txnid, ret_lsnp, flags,
 	fileid, left, llsn, right, rlsn, indx,
@@ -371,7 +371,7 @@ int __bam_split_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t indx;
 	db_pgno_t npgno;
 	DB_LSN * nlsn;
-	DBT *pg;
+	const DBT *pg;
 {
 	DBT logrec;
 	DB_LSN *lsnp, null_lsn;
@@ -560,8 +560,8 @@ __bam_split_read(recbuf, argpp)
 /*
  * PUBLIC: int __bam_rsplit_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t, db_pgno_t, DBT *, db_pgno_t,
- * PUBLIC:     DBT *, DB_LSN *));
+ * PUBLIC:     u_int32_t, db_pgno_t, const DBT *, db_pgno_t,
+ * PUBLIC:     const DBT *, DB_LSN *));
  */
 int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
 	fileid, pgno, pgdbt, nrec, rootent, rootlsn)
@@ -571,9 +571,9 @@ int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t flags;
 	u_int32_t fileid;
 	db_pgno_t pgno;
-	DBT *pgdbt;
+	const DBT *pgdbt;
 	db_pgno_t nrec;
-	DBT *rootent;
+	const DBT *rootent;
 	DB_LSN * rootlsn;
 {
 	DBT logrec;
@@ -1215,7 +1215,7 @@ __bam_cdel_read(recbuf, argpp)
  * PUBLIC: int __bam_repl_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t, DBT *, DBT *, u_int32_t,
+ * PUBLIC:     u_int32_t, const DBT *, const DBT *, u_int32_t,
  * PUBLIC:     u_int32_t));
  */
 int __bam_repl_log(logp, txnid, ret_lsnp, flags,
@@ -1230,8 +1230,8 @@ int __bam_repl_log(logp, txnid, ret_lsnp, flags,
 	DB_LSN * lsn;
 	u_int32_t indx;
 	u_int32_t isdeleted;
-	DBT *orig;
-	DBT *repl;
+	const DBT *orig;
+	const DBT *repl;
 	u_int32_t prefix;
 	u_int32_t suffix;
 {
diff --git a/db2/common/db_appinit.c b/db2/common/db_appinit.c
index 05fc7cc084..4ee9e4f40c 100644
--- a/db2/common/db_appinit.c
+++ b/db2/common/db_appinit.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_appinit.c	10.37 (Sleepycat) 11/25/97";
+static const char sccsid[] = "@(#)db_appinit.c	10.38 (Sleepycat) 1/7/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -69,7 +69,8 @@ db_appinit(db_home, db_config, dbenv, flags)
 {
 	FILE *fp;
 	int ret;
-	char *lp, **p, buf[MAXPATHLEN * 2];
+	char * const *p;
+	char *lp, buf[MAXPATHLEN * 2];
 
 	/* Validate arguments. */
 	if (dbenv == NULL)
@@ -104,7 +105,7 @@ db_appinit(db_home, db_config, dbenv, flags)
 		goto err;
 
 	/* Parse the config array. */
-	for (p = (char **)db_config; p != NULL && *p != NULL; ++p)
+	for (p = db_config; p != NULL && *p != NULL; ++p)
 		if ((ret = __db_parse(dbenv, *p)) != 0)
 			goto err;
 
diff --git a/db2/common/db_apprec.c b/db2/common/db_apprec.c
index 188c6b9f95..7a42e13317 100644
--- a/db2/common/db_apprec.c
+++ b/db2/common/db_apprec.c
@@ -11,12 +11,13 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_apprec.c	10.19 (Sleepycat) 11/23/97";
+static const char sccsid[] = "@(#)db_apprec.c	10.23 (Sleepycat) 1/17/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 
+#include <errno.h>
 #include <time.h>
 #include <string.h>
 #include <stdlib.h>
@@ -44,9 +45,9 @@ __db_apprec(dbenv, flags)
 {
 	DBT data;
 	DB_LOG *lp;
-	DB_LSN ckp_lsn, first_lsn, lsn, tmp_lsn;
+	DB_LSN ckp_lsn, first_lsn, lsn;
 	time_t now;
-	int first_flag, is_thread, ret;
+	int is_thread, ret;
 	void *txninfo;
 
 	lp = dbenv->lg_info;
@@ -63,73 +64,109 @@ __db_apprec(dbenv, flags)
 	F_CLR(lp, DB_AM_THREAD);
 
 	/*
-	 * Read forward through the log, opening the appropriate files so that
-	 * we can call recovery routines.  In general, we start at the last
-	 * checkpoint prior to the last checkpointed LSN.  For catastrophic
-	 * recovery, we begin at the first LSN that appears in any log file
-	 * (log_get figures this out for us when we pass it the DB_FIRST flag).
+	 * Recovery is done in three passes:
+	 * Pass #1:
+	 *	Read forward through the log from the last checkpoint to the
+	 *	end of the log, opening and closing files so that at the end
+	 *	of the log we have the "current" set of files open.
+	 * Pass #2:
+	 *	Read backward through the log undoing any uncompleted TXNs.
+	 *	If doing catastrophic recovery, we read to the beginning of
+	 *	the log, otherwise, to the most recent checkpoint that occurs
+	 *	before the most recent checkpoint LSN, which is returned by
+	 *	__log_findckp().  During this pass, checkpoint file information
+	 *	is ignored, and file openings and closings are undone.
+	 * Pass #3:
+	 *	Read forward through the log from the LSN found in pass #2,
+	 *	redoing any committed TXNs.  During this pass, checkpoint
+	 *	file information is ignored, and file openings and closings
+	 *	are redone.
 	 */
-	if (LF_ISSET(DB_RECOVER_FATAL))
-		first_flag = DB_FIRST;
-	else {
-		if ((ret = __log_findckp(lp, &lsn)) == DB_NOTFOUND)
-			goto out;
-		first_flag = DB_SET;
-	}
 
-	/* If we're a threaded application, we have to allocate space. */
+	/*
+	 * Find the last checkpoint in the log.  This is the point from which
+	 * we want to begin pass #1 (the TXN_OPENFILES pass).
+	 */
 	memset(&data, 0, sizeof(data));
-	if ((ret = log_get(lp, &lsn, &data, first_flag)) != 0) {
-		__db_err(dbenv, "Failure: unable to get log record");
-		if (first_flag == DB_SET)
-			__db_err(dbenv, "Retrieving LSN %lu %lu",
-			    (u_long)lsn.file, (u_long)lsn.offset);
-		else
-			__db_err(dbenv, "Retrieving first LSN");
-		goto out;
+	if ((ret = log_get(lp, &ckp_lsn, &data, DB_CHECKPOINT)) != 0) {
+		/*
+		 * If we don't find a checkpoint, start from the beginning.
+		 * If that fails, we're done.  Note, we require that there
+		 * be log records if we're performing recovery, and fail if
+		 * there aren't.
+		 */
+		if ((ret = log_get(lp, &ckp_lsn, &data, DB_FIRST)) != 0) {
+			__db_err(dbenv, "First log record not found");
+			if (ret == DB_NOTFOUND)
+				ret = EINVAL;
+			goto out;
+		}
 	}
 
-	first_lsn = lsn;
+	/*
+	 * Now, ckp_lsn is either the lsn of the last checkpoint or the lsn
+	 * of the first record in the log.  Begin the TXN_OPENFILES pass from
+	 * that lsn, and proceed to the end of the log.
+	 */
+	lsn = ckp_lsn;
 	for (;;) {
 		ret = __db_dispatch(lp, &data, &lsn, TXN_OPENFILES, txninfo);
 		if (ret != 0 && ret != DB_TXN_CKP)
 			goto msgerr;
-		if ((ret =
-		    log_get(dbenv->lg_info, &lsn, &data, DB_NEXT)) != 0) {
-			if (ret != DB_NOTFOUND)
-				goto out;
-			break;
+		if ((ret = log_get(lp, &lsn, &data, DB_NEXT)) != 0) {
+			if (ret == DB_NOTFOUND)
+				break;
+			goto out;
 		}
 	}
 
 	/*
-	 * Initialize the ckp_lsn to 0,0.  If we never find a valid
-	 * checkpoint in the log, then leaving ckp_lsn at 0,0 is correct.
+	 * Pass #2.
+	 *
+	 * Before we can begin pass #2, backward roll phase, we determine how
+	 * far back in the log to recover.  If we are doing catastrophic
+	 * recovery, then we go as far back as we have files.  If we are
+	 * doing normal recovery, we go as back to the most recent checkpoint
+	 * that occurs before the most recent checkpoint LSN.
 	 */
-	ZERO_LSN(ckp_lsn);
+	if (LF_ISSET(DB_RECOVER_FATAL)) {
+		ZERO_LSN(first_lsn);
+	} else
+		if ((ret = __log_findckp(lp, &first_lsn)) == DB_NOTFOUND) {
+			/*
+			 * If recovery was specified, there must be log files.
+			 * If we don't find one, it's an error.  (This should
+			 * have been caught above, when a log_get() of DB_FIRST
+			 * or DB_CHECKPOINT succeeded, but paranoia is good.)
+			 */
+			ret = EINVAL;
+			goto out;
+		}
 	for (ret = log_get(lp, &lsn, &data, DB_LAST);
 	    ret == 0 && log_compare(&lsn, &first_lsn) > 0;
-	    ret = log_get(lp,&lsn, &data, DB_PREV)) {
-		tmp_lsn = lsn;
+	    ret = log_get(lp, &lsn, &data, DB_PREV)) {
 		ret = __db_dispatch(lp,
 		    &data, &lsn, TXN_BACKWARD_ROLL, txninfo);
-		if (ret == DB_TXN_CKP) {
-			if (IS_ZERO_LSN(ckp_lsn))
-				ckp_lsn = tmp_lsn;
-			ret = 0;
-		} else if (ret != 0)
-			goto msgerr;
+		if (ret != 0)
+			if (ret != DB_TXN_CKP)
+				goto msgerr;
+			else
+				ret = 0;
 	}
 	if (ret != 0 && ret != DB_NOTFOUND)
 		goto out;
 
+	/*
+	 * Pass #3.
+	 */
 	for (ret = log_get(lp, &lsn, &data, DB_NEXT);
 	    ret == 0; ret = log_get(lp, &lsn, &data, DB_NEXT)) {
 		ret = __db_dispatch(lp, &data, &lsn, TXN_FORWARD_ROLL, txninfo);
-		if (ret == DB_TXN_CKP)
-			ret = 0;
-		else if (ret != 0)
-			goto msgerr;
+		if (ret != 0)
+			if (ret != DB_TXN_CKP)
+				goto msgerr;
+			else
+				ret = 0;
 	}
 	if (ret != DB_NOTFOUND)
 		goto out;
@@ -149,7 +186,7 @@ __db_apprec(dbenv, flags)
 		goto out;
 
 	if (dbenv->db_verbose) {
-		__db_err(lp->dbenv, "Recovery complete at %s", ctime(&now));
+		__db_err(lp->dbenv, "Recovery complete at %.24s", ctime(&now));
 		__db_err(lp->dbenv, "%s %lu %s [%lu][%lu]",
 		    "Maximum transaction id",
 		    (u_long)dbenv->tx_info->region->last_txnid,
diff --git a/db2/common/db_err.c b/db2/common/db_err.c
index 13f2cb5dc3..fc59aadbaf 100644
--- a/db2/common/db_err.c
+++ b/db2/common/db_err.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_err.c	10.19 (Sleepycat) 11/9/97";
+static const char sccsid[] = "@(#)db_err.c	10.21 (Sleepycat) 1/13/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -97,7 +97,9 @@ __db_ecursor(a, b, c)
 	DB_TXN *b;
 	DBC **c;
 {
-	a = a; b = b; c = c;			/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, NULL);
+	COMPQUIET(c, NULL);
 
 	return (EPERM);
 }
@@ -113,7 +115,10 @@ __db_edel(a, b, c, d)
 	DBT *c;
 	int d;
 {
-	a = a; b = b; c = c; d = d;		/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, NULL);
+	COMPQUIET(c, NULL);
+	COMPQUIET(d, 0);
 
 	return (EPERM);
 }
@@ -127,7 +132,8 @@ __db_efd(a, b)
 	DB *a;
 	int *b;
 {
-	a = a; b = b;				/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, NULL);
 
 	return (EPERM);
 }
@@ -143,7 +149,11 @@ __db_egp(a, b, c, d, e)
 	DBT *c, *d;
 	int e;
 {
-	a = a; b = b; c = c; d = d; e = e;	/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, NULL);
+	COMPQUIET(c, NULL);
+	COMPQUIET(d, NULL);
+	COMPQUIET(e, 0);
 
 	return (EPERM);
 }
@@ -159,7 +169,10 @@ __db_estat(a, b, c, d)
 	void *(*c) __P((size_t));
 	int d;
 {
-	a = a; b = b; c = c; d = d;		/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, NULL);
+	COMPQUIET(c, NULL);
+	COMPQUIET(d, 0);
 
 	return (EPERM);
 }
@@ -173,7 +186,8 @@ __db_esync(a, b)
 	DB *a;
 	int b;
 {
-	a = a; b = b;				/* XXX: Shut the compiler up. */
+	COMPQUIET(a, NULL);
+	COMPQUIET(b, 0);
 
 	return (EPERM);
 }
diff --git a/db2/common/db_region.c b/db2/common/db_region.c
index 4fc603a2b0..02d939e3e6 100644
--- a/db2/common/db_region.c
+++ b/db2/common/db_region.c
@@ -43,7 +43,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_region.c	10.18 (Sleepycat) 11/28/97";
+static const char sccsid[] = "@(#)db_region.c	10.21 (Sleepycat) 1/16/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -168,6 +168,8 @@ __db_rinit(dbenv, rp, fd, size, lock_region)
 {
 	int ret;
 
+	COMPQUIET(dbenv, NULL);
+
 	/*
 	 * Initialize the common information.
 	 *
@@ -190,6 +192,12 @@ __db_rinit(dbenv, rp, fd, size, lock_region)
 	 * been initialized in which case an attempt to get it could lead to
 	 * random behavior.  If the version number isn't there (the file size
 	 * is too small) or it's 0, we know that the region is being created.
+	 *
+	 * We also make sure to check the return of __db_mutex_lock() here,
+	 * even though we don't usually check elsewhere.  This is the first
+	 * lock we attempt to acquire, and if it fails we have to know.  (It
+	 * can fail -- SunOS, using fcntl(2) for locking, with an in-memory
+	 * filesystem specified as the database home.)
 	 */
 	__db_mutex_init(&rp->lock, MUTEX_LOCK_OFFSET(rp, &rp->lock));
 	if (lock_region && (ret = __db_mutex_lock(&rp->lock, fd)) != 0)
@@ -219,7 +227,8 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
 	void *retp;
 {
 	RLAYOUT *rp;
-	off_t size1, size2;
+	size_t size;
+	u_int32_t mbytes, bytes;
 	int fd, ret;
 	char *name;
 
@@ -251,19 +260,20 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
 	 * flatly impossible.  Hope that mmap fails if the file is too large.
 	 *
 	 */
-	if ((ret = __db_ioinfo(name, fd, &size1, NULL)) != 0) {
+	if ((ret = __db_ioinfo(name, fd, &mbytes, &bytes, NULL)) != 0) {
 		__db_err(dbenv, "%s: %s", name, strerror(ret));
 		goto err2;
 	}
+	size = mbytes * MEGABYTE + bytes;
 
 	/* Check to make sure the first block has been written. */
-	if ((size_t)size1 < sizeof(RLAYOUT)) {
+	if (size < sizeof(RLAYOUT)) {
 		ret = EAGAIN;
 		goto err2;
 	}
 
 	/* Map in whatever is there. */
-	if ((ret = __db_rmap(dbenv, fd, size1, &rp)) != 0)
+	if ((ret = __db_rmap(dbenv, fd, size, &rp)) != 0)
 		goto err2;
 
 	/*
@@ -284,11 +294,11 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
 	 * getting the size of the file and checking the major version.  Check
 	 * to make sure we got the entire file.
 	 */
-	if ((ret = __db_ioinfo(name, fd, &size2, NULL)) != 0) {
+	if ((ret = __db_ioinfo(name, fd, &mbytes, &bytes, NULL)) != 0) {
 		__db_err(dbenv, "%s: %s", name, strerror(ret));
 		goto err1;
 	}
-	if (size1 != size2) {
+	if (size != mbytes * MEGABYTE + bytes) {
 		ret = EAGAIN;
 		goto err1;
 	}
@@ -490,11 +500,9 @@ __db_rgrow(dbenv, fd, incr)
 	int fd;
 	size_t incr;
 {
-#ifdef MMAP_INIT_NEEDED
 	size_t i;
-#endif
 	ssize_t nw;
-	int ret;
+	int mmap_init_needed, ret;
 	char buf[__DB_VMPAGESIZE];
 
 	/* Seek to the end of the region. */
@@ -506,33 +514,42 @@ __db_rgrow(dbenv, fd, incr)
 
 	/*
 	 * Historically, some systems required that all of the bytes of the
-	 * region be written before you could mmap it and access it randomly.
+	 * region be written before it could be mmapped and accessed randomly.
+	 *
+	 * Windows/95 doesn't have that problem, but it leaves file contents
+	 * uninitialized.  Win/NT apparently initializes them.
 	 */
 #ifdef MMAP_INIT_NEEDED
-	/* Extend the region by writing each new page. */
-	for (i = 0; i < incr; i += __DB_VMPAGESIZE) {
+	mmap_init_needed = 1;
+#else
+	mmap_init_needed = __os_oldwin();
+#endif
+	if (mmap_init_needed)
+		/* Extend the region by writing each new page. */
+		for (i = 0; i < incr; i += __DB_VMPAGESIZE) {
+			if ((ret = __db_write(fd, buf, sizeof(buf), &nw)) != 0)
+				goto err;
+			if (nw != sizeof(buf))
+				goto eio;
+		}
+	else {
+		/*
+		 * Extend the region by writing the last page.
+		 *
+		 * Round off the increment to the next page boundary.
+		 */
+		incr += __DB_VMPAGESIZE - 1;
+		incr -= incr % __DB_VMPAGESIZE;
+
+		/* Write the last page, not the page after the last. */
+		if ((ret =
+		    __db_seek(fd, 0, 0, incr - __DB_VMPAGESIZE, SEEK_CUR)) != 0)
+			goto err;
 		if ((ret = __db_write(fd, buf, sizeof(buf), &nw)) != 0)
 			goto err;
 		if (nw != sizeof(buf))
 			goto eio;
 	}
-#else
-	/*
-	 * Extend the region by writing the last page.
-	 *
-	 * Round off the increment to the next page boundary.
-	 */
-	incr += __DB_VMPAGESIZE - 1;
-	incr -= incr % __DB_VMPAGESIZE;
-
-	/* Write the last page, not the page after the last. */
-	if ((ret = __db_seek(fd, 0, 0, incr - __DB_VMPAGESIZE, SEEK_CUR)) != 0)
-		goto err;
-	if ((ret = __db_write(fd, buf, sizeof(buf), &nw)) != 0)
-		goto err;
-	if (nw != sizeof(buf))
-		goto eio;
-#endif
 	return (0);
 
 eio:	ret = EIO;
diff --git a/db2/common/db_shash.c b/db2/common/db_shash.c
index 988de8a994..ab188f564f 100644
--- a/db2/common/db_shash.c
+++ b/db2/common/db_shash.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_shash.c	10.3 (Sleepycat) 6/21/97";
+static const char sccsid[] = "@(#)db_shash.c	10.4 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -21,8 +21,8 @@ static const char sccsid[] = "@(#)db_shash.c	10.3 (Sleepycat) 6/21/97";
 
 /* Powers-of-2 and close-by prime number pairs. */
 static const struct {
-	int	power;
-	int	prime;
+	u_int	power;
+	u_int	prime;
 } list[] = {
 	{  64,	  67},
 	{ 128,	 131},
@@ -39,11 +39,11 @@ static const struct {
  * __db_tablesize --
  *	Choose a size for the hash table.
  *
- * PUBLIC: int __db_tablesize __P((int));
+ * PUBLIC: int __db_tablesize __P((u_int));
  */
 int
 __db_tablesize(n_buckets)
-	int n_buckets;
+	u_int n_buckets;
 {
 	int i;
 
diff --git a/db2/db.h b/db2/db.h
index f976acafb7..6a75bcd33d 100644
--- a/db2/db.h
+++ b/db2/db.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db.h.src	10.97 (Sleepycat) 11/28/97
+ *	@(#)db.h.src	10.102 (Sleepycat) 1/18/98
  */
 
 #ifndef _DB_H_
@@ -73,8 +73,8 @@
 
 #define	DB_VERSION_MAJOR	2
 #define	DB_VERSION_MINOR	3
-#define	DB_VERSION_PATCH	14
-#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.14: (11/28/97)"
+#define	DB_VERSION_PATCH	16
+#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.16: (1/19/98)"
 
 typedef	u_int32_t	db_pgno_t;	/* Page number type. */
 typedef	u_int16_t	db_indx_t;	/* Page offset type. */
@@ -241,7 +241,7 @@ struct __db_env {
 	DB_LOCKTAB	*lk_info;	/* Return from lock_open(). */
 	u_int8_t	*lk_conflicts;	/* Two dimensional conflict matrix. */
 	int		 lk_modes;	/* Number of lock modes in table. */
-	unsigned int	 lk_max;	/* Maximum number of locks. */
+	u_int		 lk_max;	/* Maximum number of locks. */
 	u_int32_t	 lk_detect;	/* Deadlock detect on every conflict. */
 
 	/* Logging. */
@@ -461,7 +461,6 @@ struct __db {
 #define	DB_RE_PAD	0x004000	/* DB_PAD (internal). */
 #define	DB_RE_RENUMBER	0x008000	/* DB_RENUMBER (internal). */
 #define	DB_RE_SNAPSHOT	0x010000	/* DB_SNAPSHOT (internal). */
-
 	u_int32_t flags;
 };
 
@@ -532,7 +531,7 @@ int   db_open __P((const char *, DBTYPE, int, int, DB_ENV *, DB_INFO *, DB **));
 int   db_value_set __P((int, int));
 char *db_version __P((int *, int *, int *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -611,7 +610,7 @@ int	  lock_unlink __P((const char *, int, DB_ENV *));
 int	  lock_vec __P((DB_LOCKTAB *,
 	    u_int32_t, int, DB_LOCKREQ *, int, DB_LOCKREQ **));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -650,6 +649,8 @@ struct __db_log_stat {
 	u_int32_t st_scount;		/* Total writes to the log. */
 	u_int32_t st_region_wait;	/* Region lock granted after wait. */
 	u_int32_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_cur_file;		/* Current log file number. */
+	u_int32_t st_cur_offset;	/* Current log file offset. */
 };
 
 #if defined(__cplusplus)
@@ -668,7 +669,7 @@ int	 log_stat __P((DB_LOG *, DB_LOG_STAT **, void *(*)(size_t)));
 int	 log_unlink __P((const char *, int, DB_ENV *));
 int	 log_unregister __P((DB_LOG *, u_int32_t));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -739,7 +740,7 @@ int	memp_sync __P((DB_MPOOL *, DB_LSN *));
 int	memp_trickle __P((DB_MPOOL *, int, int *));
 int	memp_unlink __P((const char *, int, DB_ENV *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -790,10 +791,13 @@ int	  txn_prepare __P((DB_TXN *));
 int	  txn_stat __P((DB_TXNMGR *, DB_TXN_STAT **, void *(*)(size_t)));
 int	  txn_unlink __P((const char *, int, DB_ENV *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
-#ifdef DB_DBM_HSEARCH
+#ifndef DB_DBM_HSEARCH
+#define	DB_DBM_HSEARCH	0		/* No historic interfaces by default. */
+#endif
+#if DB_DBM_HSEARCH != 0
 /*******************************************************
  * Dbm/Ndbm historic interfaces.
  *******************************************************/
@@ -811,40 +815,74 @@ typedef struct {
 	int dsize;
 } datum;
 
+/*
+ * Translate DBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ *
+ * The global variables dbrdonly, dirf and pagf were not retained when
+ * 4BSD replaced the dbm interface with ndbm, and are not support here.
+ */
+#define	dbminit(a)	__db_dbm_init(a)
+#if !defined(__cplusplus)
+#define	delete(a)	__db_dbm_delete(a)
+#endif
+#define	fetch(a)	__db_dbm_fetch(a)
+#define	firstkey	__db_dbm_firstkey
+#define	nextkey(a)	__db_dbm_nextkey(a)
+#define	store(a, b)	__db_dbm_store(a, b)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
 extern "C" {
 #endif
-int	 dbminit __P((char *));
-#if !defined(__cplusplus)
-int	 delete __P((datum));
+int	 __db_dbm_init __P((char *));
+int	 __db_dbm_delete __P((datum));
+int	 __db_dbm_dbrdonly __P((void));
+int	 __db_dbm_dirf __P((void));
+datum	 __db_dbm_fetch __P((datum));
+datum	 __db_dbm_firstkey __P((void));
+datum	 __db_dbm_nextkey __P((datum));
+int	 __db_dbm_pagf __P((void));
+int	 __db_dbm_store __P((datum, datum));
+#if defined(__cplusplus)
+}
 #endif
-datum	 fetch __P((datum));
-datum	 firstkey __P((void));
-datum	 nextkey __P((datum));
-int	 store __P((datum, datum));
 
 /*
- * !!!
- * Don't prototype:
- *
- *	 dbm_clearerr(DBM *db);
- *	 dbm_dirfno(DBM *db);
- *	 dbm_error(DBM *db);
- *	 dbm_pagfno(DBM *db);
- *	 dbm_rdonly(DBM *db);
- *
- * they weren't documented and were historically implemented as #define's.
+ * Translate NDBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
  */
-void	 dbm_close __P((DBM *));
-int	 dbm_delete __P((DBM *, datum));
-datum	 dbm_fetch __P((DBM *, datum));
-datum	 dbm_firstkey __P((DBM *));
-long	 dbm_forder __P((DBM *, datum));
-datum	 dbm_nextkey __P((DBM *));
-DBM	*dbm_open __P((const char *, int, int));
-int	 dbm_store __P((DBM *, datum, datum, int));
+#define	dbm_clearerr(a)		__db_ndbm_clearerr(a)
+#define	dbm_close(a)		__db_ndbm_close(a)
+#define	dbm_delete(a, b)	__db_ndbm_delete(a, b)
+#define	dbm_dirfno(a)		__db_ndbm_dirfno(a)
+#define	dbm_error(a)		__db_ndbm_error(a)
+#define	dbm_fetch(a, b)		__db_ndbm_fetch(a, b)
+#define	dbm_firstkey(a)		__db_ndbm_firstkey(a)
+#define	dbm_nextkey(a)		__db_ndbm_nextkey(a)
+#define	dbm_open(a, b, c)	__db_ndbm_open(a, b, c)
+#define	dbm_pagfno(a)		__db_ndbm_pagfno(a)
+#define	dbm_rdonly(a)		__db_ndbm_rdonly(a)
+#define	dbm_store(a, b, c, d)	__db_ndbm_store(a, b, c, d)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
-};
+extern "C" {
+#endif
+int	 __db_ndbm_clearerr __P((DBM *));
+void	 __db_ndbm_close __P((DBM *));
+int	 __db_ndbm_delete __P((DBM *, datum));
+int	 __db_ndbm_dirfno __P((DBM *));
+int	 __db_ndbm_error __P((DBM *));
+datum	 __db_ndbm_fetch __P((DBM *, datum));
+datum	 __db_ndbm_firstkey __P((DBM *));
+datum	 __db_ndbm_nextkey __P((DBM *));
+DBM	*__db_ndbm_open __P((const char *, int, int));
+int	 __db_ndbm_pagfno __P((DBM *));
+int	 __db_ndbm_rdonly __P((DBM *));
+int	 __db_ndbm_store __P((DBM *, datum, datum, int));
+#if defined(__cplusplus)
+}
 #endif
 
 /*******************************************************
@@ -859,14 +897,23 @@ typedef struct entry {
 	void *data;
 } ENTRY;
 
+/*
+ * Translate HSEARCH calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ */
+#define	hcreate(a)	__db_hcreate(a)
+#define	hdestroy	__db_hdestroy
+#define	hsearch(a, b)	__db_hsearch(a, b)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
 extern "C" {
 #endif
-int	 hcreate __P((unsigned int));
-void	 hdestroy __P((void));
-ENTRY	*hsearch __P((ENTRY, ACTION));
+int	 __db_hcreate __P((unsigned int));
+void	 __db_hdestroy __P((void));
+ENTRY	*__db_hsearch __P((ENTRY, ACTION));
 #if defined(__cplusplus)
-};
+}
 #endif
 #endif /* DB_DBM_HSEARCH */
 
diff --git a/db2/db/db.c b/db2/db/db.c
index 50b14eba7c..8df76349d1 100644
--- a/db2/db/db.c
+++ b/db2/db/db.c
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db.c	10.44 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)db.c	10.45 (Sleepycat) 12/4/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -110,9 +110,9 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
 	DB_ENV *envp, t_dbenv;
 	DB_PGINFO pginfo;
 	HASHHDR *hashm;
-	off_t io;
 	size_t cachesize;
 	ssize_t nr;
+	u_int32_t iopsize;
 	int fd, ftype, need_fileid, restore, ret, retry_cnt, swapped;
 	char *real_name, mbuf[512];
 
@@ -269,17 +269,17 @@ open_retry:	if (LF_ISSET(DB_CREATE)) {
 		 * sizes, we limit the default pagesize to 16K.
 		 */
 		if (dbp->pgsize == 0) {
-			if ((ret =
-			    __db_ioinfo(real_name, fd, NULL, &io)) != 0) {
+			if ((ret = __db_ioinfo(real_name,
+			    fd, NULL, NULL, &iopsize)) != 0) {
 				__db_err(dbenv,
 				    "%s: %s", real_name, strerror(ret));
 				goto err;
 			}
-			if (io < 512)
-				io = 512;
-			if (io > 16 * 1024)
-				io = 16 * 1024;
-			dbp->pgsize = io;
+			if (iopsize < 512)
+				iopsize = 512;
+			if (iopsize > 16 * 1024)
+				iopsize = 16 * 1024;
+			dbp->pgsize = iopsize;
 			F_SET(dbp, DB_AM_PGDEF);
 		}
 
diff --git a/db2/db/db_auto.c b/db2/db/db_auto.c
index 88bca7b583..5d35264103 100644
--- a/db2/db/db_auto.c
+++ b/db2/db/db_auto.c
@@ -20,7 +20,7 @@
  * PUBLIC: int __db_addrem_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- * PUBLIC:     size_t, DBT *, DBT *, DB_LSN *));
+ * PUBLIC:     size_t, const DBT *, const DBT *, DB_LSN *));
  */
 int __db_addrem_log(logp, txnid, ret_lsnp, flags,
 	opcode, fileid, pgno, indx, nbytes, hdr,
@@ -34,8 +34,8 @@ int __db_addrem_log(logp, txnid, ret_lsnp, flags,
 	db_pgno_t pgno;
 	u_int32_t indx;
 	size_t nbytes;
-	DBT *hdr;
-	DBT *dbt;
+	const DBT *hdr;
+	const DBT *dbt;
 	DB_LSN * pagelsn;
 {
 	DBT logrec;
@@ -229,7 +229,7 @@ __db_addrem_read(recbuf, argpp)
 /*
  * PUBLIC: int __db_split_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, DBT *,
+ * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, const DBT *,
  * PUBLIC:     DB_LSN *));
  */
 int __db_split_log(logp, txnid, ret_lsnp, flags,
@@ -241,7 +241,7 @@ int __db_split_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t opcode;
 	u_int32_t fileid;
 	db_pgno_t pgno;
-	DBT *pageimage;
+	const DBT *pageimage;
 	DB_LSN * pagelsn;
 {
 	DBT logrec;
@@ -400,7 +400,7 @@ __db_split_read(recbuf, argpp)
  * PUBLIC: int __db_big_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
- * PUBLIC:     db_pgno_t, DBT *, DB_LSN *, DB_LSN *,
+ * PUBLIC:     db_pgno_t, const DBT *, DB_LSN *, DB_LSN *,
  * PUBLIC:     DB_LSN *));
  */
 int __db_big_log(logp, txnid, ret_lsnp, flags,
@@ -415,7 +415,7 @@ int __db_big_log(logp, txnid, ret_lsnp, flags,
 	db_pgno_t pgno;
 	db_pgno_t prev_pgno;
 	db_pgno_t next_pgno;
-	DBT *dbt;
+	const DBT *dbt;
 	DB_LSN * pagelsn;
 	DB_LSN * prevlsn;
 	DB_LSN * nextlsn;
@@ -1079,7 +1079,7 @@ __db_addpage_read(recbuf, argpp)
 /*
  * PUBLIC: int __db_debug_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     DBT *, u_int32_t, DBT *, DBT *,
+ * PUBLIC:     const DBT *, u_int32_t, const DBT *, const DBT *,
  * PUBLIC:     u_int32_t));
  */
 int __db_debug_log(logp, txnid, ret_lsnp, flags,
@@ -1088,10 +1088,10 @@ int __db_debug_log(logp, txnid, ret_lsnp, flags,
 	DB_TXN *txnid;
 	DB_LSN *ret_lsnp;
 	u_int32_t flags;
-	DBT *op;
+	const DBT *op;
 	u_int32_t fileid;
-	DBT *key;
-	DBT *data;
+	const DBT *key;
+	const DBT *data;
 	u_int32_t arg_flags;
 {
 	DBT logrec;
diff --git a/db2/db/db_conv.c b/db2/db/db_conv.c
index 8eccc2e602..c075df33fe 100644
--- a/db2/db/db_conv.c
+++ b/db2/db/db_conv.c
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_conv.c	10.7 (Sleepycat) 9/21/97";
+static const char sccsid[] = "@(#)db_conv.c	10.8 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -94,7 +94,7 @@ __db_pgout(pg, pagesize, pp)
  */
 static int
 __db_convert(pg, pp, pagesize, pgin)
-	db_pgno_t pg;			/* Unused, but left for the future. */
+	db_pgno_t pg;
 	void *pp;
 	size_t pagesize;
 	int pgin;
@@ -107,6 +107,8 @@ __db_convert(pg, pp, pagesize, pgin)
 	db_indx_t i, len, tmp;
 	u_int8_t *p, *end;
 
+	COMPQUIET(pg, 0);
+
 	h = pp;
 	if (pgin) {
 		M_32_SWAP(h->lsn.file);
diff --git a/db2/db/db_dispatch.c b/db2/db/db_dispatch.c
index 4f89d2b917..736575adfc 100644
--- a/db2/db/db_dispatch.c
+++ b/db2/db/db_dispatch.c
@@ -43,7 +43,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_dispatch.c	10.7 (Sleepycat) 11/23/97";
+static const char sccsid[] = "@(#)db_dispatch.c	10.9 (Sleepycat) 1/17/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -61,6 +61,7 @@ static const char sccsid[] = "@(#)db_dispatch.c	10.7 (Sleepycat) 11/23/97";
 #include "db_dispatch.h"
 #include "db_am.h"
 #include "common_ext.h"
+#include "log_auto.h"
 
 /*
  * Data structures to manage the DB dispatch table.  The dispatch table
@@ -113,7 +114,8 @@ __db_dispatch(logp, db, lsnp, redo, info)
 		 * seen it, then we call the appropriate recovery routine
 		 * in "abort mode".
 		 */
-		if (__db_txnlist_find(info, txnid) == DB_NOTFOUND)
+		if (rectype == DB_log_register ||
+		    __db_txnlist_find(info, txnid) == DB_NOTFOUND)
 			return ((dispatch_table[rectype])(logp,
 			    db, lsnp, TXN_UNDO, info));
 		break;
@@ -122,7 +124,8 @@ __db_dispatch(logp, db, lsnp, redo, info)
 		 * In the forward pass, if we haven't seen the transaction,
 		 * do nothing, else recovery it.
 		 */
-		if (__db_txnlist_find(info, txnid) != DB_NOTFOUND)
+		if (rectype == DB_log_register ||
+		    __db_txnlist_find(info, txnid) != DB_NOTFOUND)
 			return ((dispatch_table[rectype])(logp,
 			    db, lsnp, TXN_REDO, info));
 		break;
@@ -258,6 +261,8 @@ __db_txnlist_find(listp, txnid)
 /*
  * __db_txnlist_print --
  *	Print out the transaction list.
+ *
+ * PUBLIC: void __db_txnlist_print __P((void *));
  */
 void
 __db_txnlist_print(listp)
diff --git a/db2/db/db_dup.c b/db2/db/db_dup.c
index faeefa0744..59dfb85b92 100644
--- a/db2/db/db_dup.c
+++ b/db2/db/db_dup.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_dup.c	10.10 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)db_dup.c	10.11 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -369,14 +369,13 @@ __db_dsplit(dbp, hp, indxp, size, newfunc)
  * __db_ditem --
  *	Remove an item from a page.
  *
- * PUBLIC:  int __db_ditem __P((DB *, PAGE *, int, u_int32_t));
+ * PUBLIC:  int __db_ditem __P((DB *, PAGE *, u_int32_t, u_int32_t));
  */
 int
 __db_ditem(dbp, pagep, indx, nbytes)
 	DB *dbp;
 	PAGE *pagep;
-	int indx;
-	u_int32_t nbytes;
+	u_int32_t indx, nbytes;
 {
 	DBT ldbt;
 	db_indx_t cnt, offset;
diff --git a/db2/db/db_pr.c b/db2/db/db_pr.c
index 6b6171a13c..1135a9e738 100644
--- a/db2/db/db_pr.c
+++ b/db2/db/db_pr.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_pr.c	10.19 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)db_pr.c	10.20 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -81,7 +81,7 @@ __db_dump(dbp, name, all)
 {
 	FILE *fp, *save_fp;
 
-	save_fp = NULL;				/* XXX: Shut the compiler up. */
+	COMPQUIET(save_fp, NULL);
 
 	if (set_psize == PSIZE_BOUNDARY)
 		__db_psize(dbp->mpf);
diff --git a/db2/db/db_rec.c b/db2/db/db_rec.c
index 2c9ca9abe0..48e09e6f23 100644
--- a/db2/db/db_rec.c
+++ b/db2/db/db_rec.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_rec.c	10.10 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)db_rec.c	10.12 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -87,8 +87,8 @@ __db_addrem_recover(logp, dbtp, lsnp, redo, info)
 	} else if ((cmp_n == 0 && !redo && argp->opcode == DB_ADD_DUP) ||
 	    (cmp_p == 0 && redo && argp->opcode == DB_REM_DUP)) {
 		/* Need to undo an add, or redo a delete. */
-		if ((ret = __db_ditem(file_dbp, pagep, argp->indx,
-		    argp->nbytes)) != 0)
+		if ((ret = __db_ditem(file_dbp,
+		    pagep, argp->indx, argp->nbytes)) != 0)
 			goto out;
 		change = DB_MPOOL_DIRTY;
 	}
@@ -585,6 +585,9 @@ __db_debug_recover(logp, dbtp, lsnp, redo, info)
 	__db_debug_args *argp;
 	int ret;
 
+	COMPQUIET(redo, 0);
+	COMPQUIET(logp, NULL);
+
 	REC_PRINT(__db_debug_print);
 	REC_NOOP_INTRO(__db_debug_read);
 
@@ -612,6 +615,9 @@ __db_noop_recover(logp, dbtp, lsnp, redo, info)
 	__db_noop_args *argp;
 	int ret;
 
+	COMPQUIET(redo, 0);
+	COMPQUIET(logp, NULL);
+
 	REC_PRINT(__db_noop_print);
 	REC_NOOP_INTRO(__db_noop_read);
 
diff --git a/db2/db185/db185.c b/db2/db185/db185.c
index 1affdcdf0d..7f6a16de49 100644
--- a/db2/db185/db185.c
+++ b/db2/db185/db185.c
@@ -119,7 +119,7 @@ __dbopen(file, oflags, mode, type, openinfo)
 		 */
 		if (file != NULL) {
 			if (oflags & O_CREAT && __db_exists(file, NULL) != 0)
-				(void)__os_close(open(file, oflags, mode));
+				(void)__os_close(__os_open(file, oflags, mode));
 			dbinfop->re_source = (char *)file;
 			file = NULL;
 		}
diff --git a/db2/db_185.h b/db2/db_185.h
index b6a4d0a12a..f3b02c71e9 100644
--- a/db2/db_185.h
+++ b/db2/db_185.h
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)db_185.h.src	8.4 (Sleepycat) 9/16/97
+ *	@(#)db_185.h.src	8.5 (Sleepycat) 1/15/98
  */
 
 #ifndef _DB_185_H_
@@ -76,8 +76,8 @@
  * XXX
  * SGI/IRIX already has a pgno_t.
  */
-#ifdef sgi
-#define        pgno_t  db_pgno_t
+#ifdef	sgi
+#define	pgno_t	db_pgno_t
 #endif
 
 #define	MAX_PAGE_NUMBER	0xffffffff	/* >= # of pages in a file */
@@ -174,6 +174,6 @@ DB *__dbopen __P((const char *, int, int, DBTYPE, const void *));
 DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
 
 #if defined(__cplusplus)
-};
+}
 #endif
 #endif /* !_DB_185_H_ */
diff --git a/db2/db_int.h b/db2/db_int.h
index 21460722a3..eacd3f9806 100644
--- a/db2/db_int.h
+++ b/db2/db_int.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_int.h.src	10.37 (Sleepycat) 11/25/97
+ *	@(#)db_int.h.src	10.41 (Sleepycat) 1/8/98
  */
 
 #ifndef _DB_INTERNAL_H_
@@ -18,14 +18,22 @@
 /*******************************************************
  * General purpose constants and macros.
  *******************************************************/
-#define	UINT32_T_MAX	0xffffffff	/* Maximum 32 bit unsigned. */
 #define	UINT16_T_MAX	    0xffff	/* Maximum 16 bit unsigned. */
+#define	UINT32_T_MAX	0xffffffff	/* Maximum 32 bit unsigned. */
 
 #define	DB_MIN_PGSIZE	0x000200	/* Minimum page size. */
 #define	DB_MAX_PGSIZE	0x010000	/* Maximum page size. */
 
 #define	DB_MINCACHE	10		/* Minimum cached pages */
 
+#define	MEGABYTE	1048576
+
+/*
+ * If we are unable to determine the underlying filesystem block size, use
+ * 8K on the grounds that most OS's use less than 8K as their VM page size.
+ */
+#define	DB_DEF_IOSIZE	(8 * 1024)
+
 /*
  * Aligning items to particular sizes or in pages or memory.  ALIGNP is a
  * separate macro, as we've had to cast the pointer to different integral
@@ -109,6 +117,9 @@ typedef struct __fn {
 #undef	DB_LINE
 #define	DB_LINE "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
 
+/* Unused, or not-used-yet variable.  "Shut that bloody compiler up!" */
+#define	COMPQUIET(n, v)	(n) = (v)
+
 /*******************************************************
  * Files.
  *******************************************************/
@@ -155,18 +166,22 @@ typedef unsigned char tsl_t;
 
 /*
  * The offset of a mutex in memory.
+ *
+ * !!!
+ * Not an off_t, so backing file offsets MUST be less than 4Gb.  See the
+ * off field of the db_mutex_t as well.
  */
-#define	MUTEX_LOCK_OFFSET(a, b)	((off_t)((u_int8_t *)b - (u_int8_t *)a))
+#define	MUTEX_LOCK_OFFSET(a, b)	((u_int32_t)((u_int8_t *)b - (u_int8_t *)a))
 
 typedef struct _db_mutex_t {
 #ifdef HAVE_SPINLOCKS
-	tsl_t	tsl_resource;		/* Resource test and set. */
+	tsl_t	  tsl_resource;		/* Resource test and set. */
 #ifdef DEBUG
-	u_long	pid;			/* Lock holder: 0 or process pid. */
+	u_long	  pid;			/* Lock holder: 0 or process pid. */
 #endif
 #else
-	off_t	off;			/* Backing file offset. */
-	u_long	pid;			/* Lock holder: 0 or process pid. */
+	u_int32_t off;			/* Backing file offset. */
+	u_long	  pid;			/* Lock holder: 0 or process pid. */
 #endif
 	u_int32_t spins;		/* Spins before block. */
 	u_int32_t mutex_set_wait;	/* Granted after wait. */
diff --git a/db2/dbm/dbm.c b/db2/dbm/dbm.c
index bd7c7a6636..81f4bba69c 100644
--- a/db2/dbm/dbm.c
+++ b/db2/dbm/dbm.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)dbm.c	10.7 (Sleepycat) 11/25/97";
+static const char sccsid[] = "@(#)dbm.c	10.10 (Sleepycat) 1/16/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -59,18 +59,12 @@ static const char sccsid[] = "@(#)dbm.c	10.7 (Sleepycat) 11/25/97";
 #include <string.h>
 #endif
 
-#define	DB_DBM_HSEARCH
+#define	DB_DBM_HSEARCH	1
 #include "db_int.h"
 
 #include "db_page.h"
 #include "hash.h"
 
-/* Provide prototypes here since there are none in db.h. */
-int dbm_clearerr __P((DBM *));
-int dbm_dirfno __P((DBM *));
-int dbm_error __P((DBM *));
-int dbm_pagfno __P((DBM *));
-
 /*
  *
  * This package provides dbm and ndbm compatible interfaces to DB.
@@ -82,7 +76,7 @@ static DBM *__cur_db;
 static void __db_no_open __P((void));
 
 int
-dbminit(file)
+__db_dbm_init(file)
 	char *file;
 {
 	if (__cur_db != NULL)
@@ -94,9 +88,10 @@ dbminit(file)
 		return (0);
 	return (-1);
 }
+weak_alias (__db_dbm_init, dbminit)
 
 datum
-fetch(key)
+__db_dbm_fetch(key)
 	datum key;
 {
 	datum item;
@@ -108,9 +103,10 @@ fetch(key)
 	}
 	return (dbm_fetch(__cur_db, key));
 }
+weak_alias (__db_dbm_fetch, fetch)
 
 datum
-firstkey()
+__db_dbm_firstkey()
 {
 	datum item;
 
@@ -121,13 +117,17 @@ firstkey()
 	}
 	return (dbm_firstkey(__cur_db));
 }
+#undef firstkey
+weak_alias (__db_dbm_firstkey, firstkey)
 
 datum
-nextkey(key)
+__db_dbm_nextkey(key)
 	datum key;
 {
 	datum item;
 
+	COMPQUIET(key.dsize, 0);
+
 	if (__cur_db == NULL) {
 		__db_no_open();
 		item.dptr = 0;
@@ -135,9 +135,10 @@ nextkey(key)
 	}
 	return (dbm_nextkey(__cur_db));
 }
+weak_alias (__db_dbm_nextkey, nextkey)
 
 int
-delete(key)
+__db_dbm_delete(key)
 	datum key;
 {
 	int ret;
@@ -151,9 +152,10 @@ delete(key)
 		ret = (((DB *)__cur_db)->sync)((DB *)__cur_db, 0);
 	return (ret);
 }
+weak_alias (__db_dbm_delete, delete)
 
 int
-store(key, dat)
+__db_dbm_store(key, dat)
 	datum key, dat;
 {
 	int ret;
@@ -167,6 +169,7 @@ store(key, dat)
 		ret = (((DB *)__cur_db)->sync)((DB *)__cur_db, 0);
 	return (ret);
 }
+weak_alias (__db_dbm_store, store)
 
 static void
 __db_no_open()
@@ -185,7 +188,7 @@ __db_no_open()
  *	 NULL on failure
  */
 DBM *
-dbm_open(file, oflags, mode)
+__db_ndbm_open(file, oflags, mode)
 	const char *file;
 	int oflags, mode;
 {
@@ -215,17 +218,19 @@ dbm_open(file, oflags, mode)
 		return (NULL);
 	return ((DBM *)dbp);
 }
+weak_alias (__db_ndbm_open, dbm_open)
 
 /*
  * Returns:
  *	Nothing.
  */
 void
-dbm_close(db)
+__db_ndbm_close(db)
 	DBM *db;
 {
 	(void)db->close(db, 0);
 }
+weak_alias (__db_ndbm_close, dbm_close)
 
 /*
  * Returns:
@@ -233,7 +238,7 @@ dbm_close(db)
  *	NULL on failure
  */
 datum
-dbm_fetch(db, key)
+__db_ndbm_fetch(db, key)
 	DBM *db;
 	datum key;
 {
@@ -255,6 +260,7 @@ dbm_fetch(db, key)
 	}
 	return (data);
 }
+weak_alias (__db_ndbm_fetch, dbm_fetch)
 
 /*
  * Returns:
@@ -262,7 +268,7 @@ dbm_fetch(db, key)
  *	NULL on failure
  */
 datum
-dbm_firstkey(db)
+__db_ndbm_firstkey(db)
 	DBM *db;
 {
 	DBT _key, _data;
@@ -289,6 +295,7 @@ dbm_firstkey(db)
 	}
 	return (key);
 }
+weak_alias (__db_ndbm_firstkey, dbm_firstkey)
 
 /*
  * Returns:
@@ -296,7 +303,7 @@ dbm_firstkey(db)
  *	NULL on failure
  */
 datum
-dbm_nextkey(db)
+__db_ndbm_nextkey(db)
 	DBM *db;
 {
 	DBC *cp;
@@ -322,6 +329,7 @@ dbm_nextkey(db)
 	}
 	return (key);
 }
+weak_alias (__db_ndbm_nextkey, dbm_nextkey)
 
 /*
  * Returns:
@@ -329,7 +337,7 @@ dbm_nextkey(db)
  *	<0 failure
  */
 int
-dbm_delete(db, key)
+__db_ndbm_delete(db, key)
 	DBM *db;
 	datum key;
 {
@@ -348,6 +356,7 @@ dbm_delete(db, key)
 	}
 	return (ret);
 }
+weak_alias (__db_ndbm_delete, dbm_delete)
 
 /*
  * Returns:
@@ -356,7 +365,7 @@ dbm_delete(db, key)
  *	 1 if DBM_INSERT and entry exists
  */
 int
-dbm_store(db, key, data, flags)
+__db_ndbm_store(db, key, data, flags)
 	DBM *db;
 	datum key, data;
 	int flags;
@@ -372,9 +381,10 @@ dbm_store(db, key, data, flags)
 	return (db->put((DB *)db,
 	    NULL, &_key, &_data, (flags == DBM_INSERT) ? DB_NOOVERWRITE : 0));
 }
+weak_alias (__db_ndbm_store, dbm_store)
 
 int
-dbm_error(db)
+__db_ndbm_error(db)
 	DBM *db;
 {
 	HTAB *hp;
@@ -382,9 +392,10 @@ dbm_error(db)
 	hp = (HTAB *)db->internal;
 	return (hp->local_errno);
 }
+weak_alias (__db_ndbm_error, dbm_error)
 
 int
-dbm_clearerr(db)
+__db_ndbm_clearerr(db)
 	DBM *db;
 {
 	HTAB *hp;
@@ -393,6 +404,19 @@ dbm_clearerr(db)
 	hp->local_errno = 0;
 	return (0);
 }
+weak_alias (__db_ndbm_clearerr, dbm_clearerr)
+
+/*
+ * Returns:
+ *	1 if read-only
+ *	0 if not read-only
+ */
+int
+__db_ndbm_rdonly(db)
+	DBM *db;
+{
+	return (F_ISSET((DB *)db, DB_AM_RDONLY) ? 1 : 0);
+}
 
 /*
  * XXX
@@ -401,7 +425,7 @@ dbm_clearerr(db)
  * and picked one to use at random.
  */
 int
-dbm_dirfno(db)
+__db_ndbm_dirfno(db)
 	DBM *db;
 {
 	int fd;
@@ -409,9 +433,10 @@ dbm_dirfno(db)
 	(void)db->fd(db, &fd);
 	return (fd);
 }
+weak_alias (__db_ndbm_dirfno, dbm_dirfno)
 
 int
-dbm_pagfno(db)
+__db_ndbm_pagfno(db)
 	DBM *db;
 {
 	int fd;
@@ -419,3 +444,4 @@ dbm_pagfno(db)
 	(void)db->fd(db, &fd);
 	return (fd);
 }
+weak_alias (__db_ndbm_pagfno, dbm_pagfno)
diff --git a/db2/hash/hash.c b/db2/hash/hash.c
index c08495378e..5193ece561 100644
--- a/db2/hash/hash.c
+++ b/db2/hash/hash.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash.c	10.33 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)hash.c	10.36 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -731,7 +731,7 @@ __ham_c_del(cursor, flags)
 		} else						/* Case 1 */
 			F_SET(hcp, H_DELETED);
 		if (chg_pgno != PGNO_INVALID)
-			__ham_c_update(hashp, hcp, chg_pgno, 0, 0, 1);
+			__ham_c_update(hcp, chg_pgno, 0, 0, 1);
 	} else if (F_ISSET(hcp, H_ISDUP)) {			/* on page */
 		if (hcp->dup_off == 0 && DUP_SIZE(hcp->dup_len) ==
 		    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx))
@@ -747,7 +747,7 @@ __ham_c_del(cursor, flags)
 			ret = __ham_replpair(hashp, hcp, &repldbt, 0);
 			hcp->dup_tlen -= DUP_SIZE(hcp->dup_len);
 			F_SET(hcp, H_DELETED);
-			__ham_c_update(hashp, hcp, hcp->pgno,
+			__ham_c_update(hcp, hcp->pgno,
 			    DUP_SIZE(hcp->dup_len), 0, 1);
 		}
 
@@ -1009,9 +1009,9 @@ __ham_expand_table(hashp)
 		 * if the next doubling is going to be big (more than 8
 		 * pages), we have some extra pages around.
 		 */
-		if (hashp->hdr->max_bucket + 1 >= 8 && 
+		if (hashp->hdr->max_bucket + 1 >= 8 &&
 		    hashp->hdr->spares[hashp->hdr->ovfl_point] <
-		    hashp->hdr->spares[hashp->hdr->ovfl_point - 1] + 
+		    hashp->hdr->spares[hashp->hdr->ovfl_point - 1] +
 		    hashp->hdr->ovfl_point + 1)
 			__ham_init_ovflpages(hashp);
 	}
@@ -1347,17 +1347,15 @@ __ham_init_dbt(dbt, size, bufp, sizep)
  * added (add == 1) or deleted (add == 0).
  * dup indicates if the addition occurred into a duplicate set.
  *
- * PUBLIC: void __ham_c_update __P((HTAB *,
- * PUBLIC:    HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
+ * PUBLIC: void __ham_c_update
+ * PUBLIC:    __P((HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
  */
 void
-__ham_c_update(hashp, hcp, chg_pgno, len, add, dup)
-	HTAB *hashp;
+__ham_c_update(hcp, chg_pgno, len, add, is_dup)
 	HASH_CURSOR *hcp;
 	db_pgno_t chg_pgno;
 	u_int32_t len;
-	int add;
-	int dup;
+	int add, is_dup;
 {
 	DBC *cp;
 	HTAB *hp;
@@ -1365,22 +1363,21 @@ __ham_c_update(hashp, hcp, chg_pgno, len, add, dup)
 	int page_deleted;
 
 	/*
-	 * Regular adds are always at the end of a given page,
-	 * so we never have to adjust anyone's cursor after
-	 * a regular add.
+	 * Regular adds are always at the end of a given page, so we never
+	 * have to adjust anyone's cursor after a regular add.
 	 */
-	if (!dup && add)
+	if (!is_dup && add)
 		return;
 
 	/*
 	 * Determine if a page was deleted.    If this is a regular update
-	 * (i.e., not dup) then the deleted page's number will be that in
+	 * (i.e., not is_dup) then the deleted page's number will be that in
 	 * chg_pgno, and the pgno in the cursor will be different.  If this
 	 * was an onpage-duplicate, then the same conditions apply.  If this
 	 * was an off-page duplicate, then we need to verify if hcp->dpgno
 	 * is the same (no delete) or different (delete) than chg_pgno.
 	 */
-	if (!dup || hcp->dpgno == PGNO_INVALID)
+	if (!is_dup || hcp->dpgno == PGNO_INVALID)
 		page_deleted =
 		    chg_pgno != PGNO_INVALID && chg_pgno != hcp->pgno;
 	else
@@ -1397,17 +1394,18 @@ __ham_c_update(hashp, hcp, chg_pgno, len, add, dup)
 
 		lcp = (HASH_CURSOR *)cp->internal;
 
-		if (!dup && lcp->pgno != chg_pgno)
-			continue;
-
-		if (dup && F_ISSET(hcp, H_DELETED) && lcp->pgno != chg_pgno)
+		if (!is_dup && lcp->pgno != chg_pgno)
 			continue;
 
-		if (dup && !F_ISSET(hcp, H_DELETED) && lcp->dpgno != chg_pgno)
-			continue;
+		if (is_dup) {
+			if (F_ISSET(hcp, H_DELETED) && lcp->pgno != chg_pgno)
+				continue;
+			if (!F_ISSET(hcp, H_DELETED) && lcp->dpgno != chg_pgno)
+				continue;
+		}
 
 		if (page_deleted) {
-			if (dup) {
+			if (is_dup) {
 				lcp->dpgno = hcp->dpgno;
 				lcp->dndx = hcp->dndx;
 			} else {
@@ -1419,11 +1417,11 @@ __ham_c_update(hashp, hcp, chg_pgno, len, add, dup)
 			continue;
 		}
 
-		if (!dup && lcp->bndx > hcp->bndx)
+		if (!is_dup && lcp->bndx > hcp->bndx)
 			lcp->bndx--;
-		else if (!dup && lcp->bndx == hcp->bndx)
+		else if (!is_dup && lcp->bndx == hcp->bndx)
 			F_SET(lcp, H_DELETED);
-		else if (dup && lcp->bndx == hcp->bndx) {
+		else if (is_dup && lcp->bndx == hcp->bndx) {
 			/* Assign dpgno in case there was page conversion. */
 			lcp->dpgno = hcp->dpgno;
 			if (add && lcp->dndx >= hcp->dndx )
diff --git a/db2/hash/hash_auto.c b/db2/hash/hash_auto.c
index 787ee04ddb..830ea46a4e 100644
--- a/db2/hash/hash_auto.c
+++ b/db2/hash/hash_auto.c
@@ -21,7 +21,7 @@
  * PUBLIC: int __ham_insdel_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- * PUBLIC:     DB_LSN *, DBT *, DBT *));
+ * PUBLIC:     DB_LSN *, const DBT *, const DBT *));
  */
 int __ham_insdel_log(logp, txnid, ret_lsnp, flags,
 	opcode, fileid, pgno, ndx, pagelsn, key,
@@ -35,8 +35,8 @@ int __ham_insdel_log(logp, txnid, ret_lsnp, flags,
 	db_pgno_t pgno;
 	u_int32_t ndx;
 	DB_LSN * pagelsn;
-	DBT *key;
-	DBT *data;
+	const DBT *key;
+	const DBT *data;
 {
 	DBT logrec;
 	DB_LSN *lsnp, null_lsn;
@@ -555,7 +555,7 @@ __ham_splitmeta_read(recbuf, argpp)
 /*
  * PUBLIC: int __ham_splitdata_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, DBT *,
+ * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, const DBT *,
  * PUBLIC:     DB_LSN *));
  */
 int __ham_splitdata_log(logp, txnid, ret_lsnp, flags,
@@ -567,7 +567,7 @@ int __ham_splitdata_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t fileid;
 	u_int32_t opcode;
 	db_pgno_t pgno;
-	DBT *pageimage;
+	const DBT *pageimage;
 	DB_LSN * pagelsn;
 {
 	DBT logrec;
@@ -726,7 +726,7 @@ __ham_splitdata_read(recbuf, argpp)
  * PUBLIC: int __ham_replace_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
- * PUBLIC:     int32_t, DBT *, DBT *, u_int32_t));
+ * PUBLIC:     int32_t, const DBT *, const DBT *, u_int32_t));
  */
 int __ham_replace_log(logp, txnid, ret_lsnp, flags,
 	fileid, pgno, ndx, pagelsn, off, olditem,
@@ -740,8 +740,8 @@ int __ham_replace_log(logp, txnid, ret_lsnp, flags,
 	u_int32_t ndx;
 	DB_LSN * pagelsn;
 	int32_t off;
-	DBT *olditem;
-	DBT *newitem;
+	const DBT *olditem;
+	const DBT *newitem;
 	u_int32_t makedup;
 {
 	DBT logrec;
@@ -1279,7 +1279,7 @@ __ham_ovfl_read(recbuf, argpp)
  * PUBLIC: int __ham_copypage_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- * PUBLIC:     DB_LSN *, db_pgno_t, DB_LSN *, DBT *));
+ * PUBLIC:     DB_LSN *, db_pgno_t, DB_LSN *, const DBT *));
  */
 int __ham_copypage_log(logp, txnid, ret_lsnp, flags,
 	fileid, pgno, pagelsn, next_pgno, nextlsn, nnext_pgno,
@@ -1295,7 +1295,7 @@ int __ham_copypage_log(logp, txnid, ret_lsnp, flags,
 	DB_LSN * nextlsn;
 	db_pgno_t nnext_pgno;
 	DB_LSN * nnextlsn;
-	DBT *page;
+	const DBT *page;
 {
 	DBT logrec;
 	DB_LSN *lsnp, null_lsn;
diff --git a/db2/hash/hash_dup.c b/db2/hash/hash_dup.c
index 22444e4966..f8b0adb933 100644
--- a/db2/hash/hash_dup.c
+++ b/db2/hash/hash_dup.c
@@ -42,7 +42,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_dup.c	10.8 (Sleepycat) 10/14/97";
+static const char sccsid[] = "@(#)hash_dup.c	10.10 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 /*
@@ -182,7 +182,7 @@ __ham_add_dup(hashp, hcp, nval, flags)
 		ret = __ham_replpair(hashp, hcp, &tmp_val, 0);
 		if (ret == 0)
 			ret = __ham_dirty_page(hashp, hcp->pagep);
-		__ham_c_update(hashp, hcp, hcp->pgno, tmp_val.size, 1, 1);
+		__ham_c_update(hcp, hcp->pgno, tmp_val.size, 1, 1);
 		return (ret);
 	}
 
@@ -227,7 +227,7 @@ __ham_add_dup(hashp, hcp, nval, flags)
 	ret = __db_dput(hashp->dbp,
 	    nval, &hcp->dpagep, &hcp->dndx, __ham_overflow_page);
 	hcp->pgno = PGNO(hcp->pagep);
-	__ham_c_update(hashp, hcp, hcp->pgno, nval->size, 1, 1);
+	__ham_c_update(hcp, hcp->pgno, nval->size, 1, 1);
 	return (ret);
 }
 
@@ -325,9 +325,9 @@ __ham_dup_convert(hashp, hcp)
 }
 
 static int
-__ham_make_dup(notdup, dup, bufp, sizep)
+__ham_make_dup(notdup, duplicate, bufp, sizep)
 	const DBT *notdup;
-	DBT *dup;
+	DBT *duplicate;
 	void **bufp;
 	u_int32_t *sizep;
 {
@@ -337,22 +337,22 @@ __ham_make_dup(notdup, dup, bufp, sizep)
 
 	item_size = (db_indx_t)notdup->size;
 	tsize = DUP_SIZE(item_size);
-	if ((ret = __ham_init_dbt(dup, tsize, bufp, sizep)) != 0)
+	if ((ret = __ham_init_dbt(duplicate, tsize, bufp, sizep)) != 0)
 		return (ret);
 
-	dup->dlen = 0;
-	dup->flags = notdup->flags;
-	F_SET(dup, DB_DBT_PARTIAL);
+	duplicate->dlen = 0;
+	duplicate->flags = notdup->flags;
+	F_SET(duplicate, DB_DBT_PARTIAL);
 
-	p = dup->data;
+	p = duplicate->data;
 	memcpy(p, &item_size, sizeof(db_indx_t));
 	p += sizeof(db_indx_t);
 	memcpy(p, notdup->data, notdup->size);
 	p += notdup->size;
 	memcpy(p, &item_size, sizeof(db_indx_t));
 
-	dup->doff = 0;
-	dup->dlen = notdup->size;
+	duplicate->doff = 0;
+	duplicate->dlen = notdup->size;
 
 	return (0);
 }
diff --git a/db2/hash/hash_page.c b/db2/hash/hash_page.c
index 0a12c14546..09a4a0c374 100644
--- a/db2/hash/hash_page.c
+++ b/db2/hash/hash_page.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_page.c	10.29 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)hash_page.c	10.31 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 /*
@@ -720,7 +720,7 @@ __ham_del_pair(hashp, cursorp, reclaim_page)
 		chg_pgno = cursorp->pgno;
 		ret = __ham_dirty_page(hashp, p);
 	}
-	__ham_c_update(hashp, cursorp, chg_pgno, 0, 0, 0);
+	__ham_c_update(cursorp, chg_pgno, 0, 0, 0);
 
 	/*
 	 * Since we just deleted a pair from the master page, anything
@@ -1131,7 +1131,8 @@ __ham_add_el(hashp, hcp, key, val, type)
 	const DBT *key, *val;
 	int type;
 {
-	DBT *pkey, *pdata, key_dbt, data_dbt;
+	const DBT *pkey, *pdata;
+	DBT key_dbt, data_dbt;
 	DB_LSN new_lsn;
 	HOFFPAGE doff, koff;
 	db_pgno_t next_pgno;
@@ -1200,7 +1201,7 @@ __ham_add_el(hashp, hcp, key, val, type)
 		pkey = &key_dbt;
 		key_type = H_OFFPAGE;
 	} else {
-		pkey = (DBT *)key;
+		pkey = key;
 		key_type = H_KEYDATA;
 	}
 
@@ -1215,7 +1216,7 @@ __ham_add_el(hashp, hcp, key, val, type)
 		pdata = &data_dbt;
 		data_type = H_OFFPAGE;
 	} else {
-		pdata = (DBT *)val;
+		pdata = val;
 		data_type = type;
 	}
 
@@ -1593,7 +1594,7 @@ __ham_init_ovflpages(hp)
 	db_pgno_t last_pgno, new_pgno;
 	u_int32_t i, curpages, numpages;
 
-	curpages = hp->hdr->spares[hp->hdr->ovfl_point] - 
+	curpages = hp->hdr->spares[hp->hdr->ovfl_point] -
 	    hp->hdr->spares[hp->hdr->ovfl_point - 1];
 	numpages = hp->hdr->ovfl_point + 1 - curpages;
 
diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c
index d239e3d0df..09508251a2 100644
--- a/db2/hash/hash_rec.c
+++ b/db2/hash/hash_rec.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_rec.c	10.14 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)hash_rec.c	10.15 (Sleepycat) 12/4/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -811,7 +811,7 @@ out:	if (getmeta)
 /*
  * __ham_copypage_recover --
  *	Recovery function for copypage.
- * 
+ *
  * PUBLIC: int __ham_copypage_recover
  * PUBLIC:   __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
  */
diff --git a/db2/include/btree_ext.h b/db2/include/btree_ext.h
index 46f2227bdd..9c34c8c6bf 100644
--- a/db2/include/btree_ext.h
+++ b/db2/include/btree_ext.h
@@ -1,4 +1,6 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _btree_ext_h_
+#define _btree_ext_h_
 int __bam_close __P((DB *));
 int __bam_sync __P((DB *, int));
 int __bam_cmp __P((DB *, const DBT *, EPG *));
@@ -11,11 +13,12 @@ int __bam_cursor __P((DB *, DB_TXN *, DBC **));
 int __bam_c_iclose __P((DB *, DBC *));
 int __bam_get __P((DB *, DB_TXN *, DBT *, DBT *, int));
 int __bam_ovfl_chk __P((DB *, CURSOR *, u_int32_t, int));
+int __bam_cprint __P((DB *));
 int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, CURSOR *, int));
 void __bam_ca_di __P((DB *, db_pgno_t, u_int32_t, int));
 void __bam_ca_dup __P((DB *,
    db_pgno_t, u_int32_t, u_int32_t, db_pgno_t, u_int32_t));
-void __bam_ca_move __P((DB *, BTREE *, db_pgno_t, db_pgno_t));
+void __bam_ca_move __P((DB *, db_pgno_t, db_pgno_t));
 void __bam_ca_replace
    __P((DB *, db_pgno_t, u_int32_t, ca_replace_arg));
 void __bam_ca_split __P((DB *,
@@ -29,6 +32,7 @@ int __bam_open __P((DB *, DBTYPE, DB_INFO *));
 int __bam_bdup __P((DB *, DB *));
 int __bam_new __P((DB *, u_int32_t, PAGE **));
 int __bam_free __P((DB *, PAGE *));
+int __bam_lt __P((DB *));
 int __bam_lget __P((DB *, int, db_pgno_t, db_lockmode_t, DB_LOCK *));
 int __bam_lput __P((DB *, DB_LOCK));
 int __bam_pget __P((DB *, PAGE **, db_pgno_t *, int));
@@ -57,6 +61,7 @@ int __ram_cursor __P((DB *, DB_TXN *, DBC **));
 int __ram_close __P((DB *));
 int __ram_c_iclose __P((DB *, DBC *));
 void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
+int __ram_cprint __P((DB *));
 int __ram_getno __P((DB *, const DBT *, db_recno_t *, int));
 int __ram_snapshot __P((DB *));
 int __bam_rsearch __P((DB *, db_recno_t *, u_int, int, int *));
@@ -82,7 +87,7 @@ int __bam_pg_alloc_print
 int __bam_pg_alloc_read __P((void *, __bam_pg_alloc_args **));
 int __bam_pg_free_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    u_int32_t, db_pgno_t, DB_LSN *, DBT *,
+    u_int32_t, db_pgno_t, DB_LSN *, const DBT *,
     db_pgno_t));
 int __bam_pg_free_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
@@ -91,14 +96,14 @@ int __bam_split_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
     DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *,
-    DBT *));
+    const DBT *));
 int __bam_split_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __bam_split_read __P((void *, __bam_split_args **));
 int __bam_rsplit_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    u_int32_t, db_pgno_t, DBT *, db_pgno_t,
-    DBT *, DB_LSN *));
+    u_int32_t, db_pgno_t, const DBT *, db_pgno_t,
+    const DBT *, DB_LSN *));
 int __bam_rsplit_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __bam_rsplit_read __P((void *, __bam_rsplit_args **));
@@ -125,10 +130,11 @@ int __bam_cdel_read __P((void *, __bam_cdel_args **));
 int __bam_repl_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
-    u_int32_t, DBT *, DBT *, u_int32_t,
+    u_int32_t, const DBT *, const DBT *, u_int32_t,
     u_int32_t));
 int __bam_repl_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __bam_repl_read __P((void *, __bam_repl_args **));
 int __bam_init_print __P((DB_ENV *));
 int __bam_init_recover __P((DB_ENV *));
+#endif /* _btree_ext_h_ */
diff --git a/db2/include/clib_ext.h b/db2/include/clib_ext.h
index 91e4a13fa5..eb982bf85f 100644
--- a/db2/include/clib_ext.h
+++ b/db2/include/clib_ext.h
@@ -1,4 +1,6 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _clib_ext_h_
+#define _clib_ext_h_
 #ifdef __STDC__
 void err __P((int eval, const char *, ...));
 #else
@@ -63,3 +65,4 @@ char *strsep __P((char **, const char *));
 #ifndef HAVE_VSNPRINTF
 int vsnprintf();
 #endif
+#endif /* _clib_ext_h_ */
diff --git a/db2/include/common_ext.h b/db2/include/common_ext.h
index 29bc9aa4e2..b362c9c32e 100644
--- a/db2/include/common_ext.h
+++ b/db2/include/common_ext.h
@@ -1,4 +1,6 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _common_ext_h_
+#define _common_ext_h_
 int __db_appname __P((DB_ENV *,
    APPNAME, const char *, const char *, int *, char **));
 int __db_apprec __P((DB_ENV *, int));
@@ -38,5 +40,6 @@ void __db_shalloc_free __P((void *, void *));
 size_t __db_shalloc_count __P((void *));
 size_t __db_shsizeof __P((void *));
 void __db_shalloc_dump __P((FILE *, void *));
-int __db_tablesize __P((int));
+int __db_tablesize __P((u_int));
 void __db_hashinit __P((void *, int));
+#endif /* _common_ext_h_ */
diff --git a/db2/include/db.h.src b/db2/include/db.h.src
index 654eb16425..ebdaa27470 100644
--- a/db2/include/db.h.src
+++ b/db2/include/db.h.src
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db.h.src	10.97 (Sleepycat) 11/28/97
+ *	@(#)db.h.src	10.102 (Sleepycat) 1/18/98
  */
 
 #ifndef _DB_H_
@@ -73,8 +73,8 @@
 
 #define	DB_VERSION_MAJOR	2
 #define	DB_VERSION_MINOR	3
-#define	DB_VERSION_PATCH	14
-#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.14: (11/28/97)"
+#define	DB_VERSION_PATCH	16
+#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.16: (1/19/98)"
 
 typedef	u_int32_t	db_pgno_t;	/* Page number type. */
 typedef	u_int16_t	db_indx_t;	/* Page offset type. */
@@ -241,7 +241,7 @@ struct __db_env {
 	DB_LOCKTAB	*lk_info;	/* Return from lock_open(). */
 	u_int8_t	*lk_conflicts;	/* Two dimensional conflict matrix. */
 	int		 lk_modes;	/* Number of lock modes in table. */
-	unsigned int	 lk_max;	/* Maximum number of locks. */
+	u_int		 lk_max;	/* Maximum number of locks. */
 	u_int32_t	 lk_detect;	/* Deadlock detect on every conflict. */
 
 	/* Logging. */
@@ -461,7 +461,6 @@ struct __db {
 #define	DB_RE_PAD	0x004000	/* DB_PAD (internal). */
 #define	DB_RE_RENUMBER	0x008000	/* DB_RENUMBER (internal). */
 #define	DB_RE_SNAPSHOT	0x010000	/* DB_SNAPSHOT (internal). */
-
 	u_int32_t flags;
 };
 
@@ -532,7 +531,7 @@ int   db_open __P((const char *, DBTYPE, int, int, DB_ENV *, DB_INFO *, DB **));
 int   db_value_set __P((int, int));
 char *db_version __P((int *, int *, int *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -611,7 +610,7 @@ int	  lock_unlink __P((const char *, int, DB_ENV *));
 int	  lock_vec __P((DB_LOCKTAB *,
 	    u_int32_t, int, DB_LOCKREQ *, int, DB_LOCKREQ **));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -650,6 +649,8 @@ struct __db_log_stat {
 	u_int32_t st_scount;		/* Total writes to the log. */
 	u_int32_t st_region_wait;	/* Region lock granted after wait. */
 	u_int32_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_cur_file;		/* Current log file number. */
+	u_int32_t st_cur_offset;	/* Current log file offset. */
 };
 
 #if defined(__cplusplus)
@@ -668,7 +669,7 @@ int	 log_stat __P((DB_LOG *, DB_LOG_STAT **, void *(*)(size_t)));
 int	 log_unlink __P((const char *, int, DB_ENV *));
 int	 log_unregister __P((DB_LOG *, u_int32_t));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -739,7 +740,7 @@ int	memp_sync __P((DB_MPOOL *, DB_LSN *));
 int	memp_trickle __P((DB_MPOOL *, int, int *));
 int	memp_unlink __P((const char *, int, DB_ENV *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
 /*******************************************************
@@ -790,10 +791,13 @@ int	  txn_prepare __P((DB_TXN *));
 int	  txn_stat __P((DB_TXNMGR *, DB_TXN_STAT **, void *(*)(size_t)));
 int	  txn_unlink __P((const char *, int, DB_ENV *));
 #if defined(__cplusplus)
-};
+}
 #endif
 
-#ifdef DB_DBM_HSEARCH
+#ifndef DB_DBM_HSEARCH
+#define	DB_DBM_HSEARCH	0		/* No historic interfaces by default. */
+#endif
+#if DB_DBM_HSEARCH != 0
 /*******************************************************
  * Dbm/Ndbm historic interfaces.
  *******************************************************/
@@ -811,40 +815,74 @@ typedef struct {
 	int dsize;
 } datum;
 
+/*
+ * Translate DBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ *
+ * The global variables dbrdonly, dirf and pagf were not retained when
+ * 4BSD replaced the dbm interface with ndbm, and are not support here.
+ */
+#define	dbminit(a)	__db_dbm_init(a)
+#if !defined(__cplusplus)
+#define	delete(a)	__db_dbm_delete(a)
+#endif
+#define	fetch(a)	__db_dbm_fetch(a)
+#define	firstkey	__db_dbm_firstkey
+#define	nextkey(a)	__db_dbm_nextkey(a)
+#define	store(a, b)	__db_dbm_store(a, b)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
 extern "C" {
 #endif
-int	 dbminit __P((char *));
-#if !defined(__cplusplus)
-int	 delete __P((datum));
+int	 __db_dbm_init __P((char *));
+int	 __db_dbm_delete __P((datum));
+int	 __db_dbm_dbrdonly __P((void));
+int	 __db_dbm_dirf __P((void));
+datum	 __db_dbm_fetch __P((datum));
+datum	 __db_dbm_firstkey __P((void));
+datum	 __db_dbm_nextkey __P((datum));
+int	 __db_dbm_pagf __P((void));
+int	 __db_dbm_store __P((datum, datum));
+#if defined(__cplusplus)
+}
 #endif
-datum	 fetch __P((datum));
-datum	 firstkey __P((void));
-datum	 nextkey __P((datum));
-int	 store __P((datum, datum));
 
 /*
- * !!!
- * Don't prototype:
- *
- *	 dbm_clearerr(DBM *db);
- *	 dbm_dirfno(DBM *db);
- *	 dbm_error(DBM *db);
- *	 dbm_pagfno(DBM *db);
- *	 dbm_rdonly(DBM *db);
- *
- * they weren't documented and were historically implemented as #define's.
+ * Translate NDBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
  */
-void	 dbm_close __P((DBM *));
-int	 dbm_delete __P((DBM *, datum));
-datum	 dbm_fetch __P((DBM *, datum));
-datum	 dbm_firstkey __P((DBM *));
-long	 dbm_forder __P((DBM *, datum));
-datum	 dbm_nextkey __P((DBM *));
-DBM	*dbm_open __P((const char *, int, int));
-int	 dbm_store __P((DBM *, datum, datum, int));
+#define	dbm_clearerr(a)		__db_ndbm_clearerr(a)
+#define	dbm_close(a)		__db_ndbm_close(a)
+#define	dbm_delete(a, b)	__db_ndbm_delete(a, b)
+#define	dbm_dirfno(a)		__db_ndbm_dirfno(a)
+#define	dbm_error(a)		__db_ndbm_error(a)
+#define	dbm_fetch(a, b)		__db_ndbm_fetch(a, b)
+#define	dbm_firstkey(a)		__db_ndbm_firstkey(a)
+#define	dbm_nextkey(a)		__db_ndbm_nextkey(a)
+#define	dbm_open(a, b, c)	__db_ndbm_open(a, b, c)
+#define	dbm_pagfno(a)		__db_ndbm_pagfno(a)
+#define	dbm_rdonly(a)		__db_ndbm_rdonly(a)
+#define	dbm_store(a, b, c, d)	__db_ndbm_store(a, b, c, d)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
-};
+extern "C" {
+#endif
+int	 __db_ndbm_clearerr __P((DBM *));
+void	 __db_ndbm_close __P((DBM *));
+int	 __db_ndbm_delete __P((DBM *, datum));
+int	 __db_ndbm_dirfno __P((DBM *));
+int	 __db_ndbm_error __P((DBM *));
+datum	 __db_ndbm_fetch __P((DBM *, datum));
+datum	 __db_ndbm_firstkey __P((DBM *));
+datum	 __db_ndbm_nextkey __P((DBM *));
+DBM	*__db_ndbm_open __P((const char *, int, int));
+int	 __db_ndbm_pagfno __P((DBM *));
+int	 __db_ndbm_rdonly __P((DBM *));
+int	 __db_ndbm_store __P((DBM *, datum, datum, int));
+#if defined(__cplusplus)
+}
 #endif
 
 /*******************************************************
@@ -859,14 +897,23 @@ typedef struct entry {
 	void *data;
 } ENTRY;
 
+/*
+ * Translate HSEARCH calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ */
+#define	hcreate(a)	__db_hcreate(a)
+#define	hdestroy	__db_hdestroy
+#define	hsearch(a, b)	__db_hsearch(a, b)
+
+/* Prototype the DB calls. */
 #if defined(__cplusplus)
 extern "C" {
 #endif
-int	 hcreate __P((unsigned int));
-void	 hdestroy __P((void));
-ENTRY	*hsearch __P((ENTRY, ACTION));
+int	 __db_hcreate __P((unsigned int));
+void	 __db_hdestroy __P((void));
+ENTRY	*__db_hsearch __P((ENTRY, ACTION));
 #if defined(__cplusplus)
-};
+}
 #endif
 #endif /* DB_DBM_HSEARCH */
 
diff --git a/db2/include/db_185.h.src b/db2/include/db_185.h.src
index 3fbca8bfda..a88eb4e525 100644
--- a/db2/include/db_185.h.src
+++ b/db2/include/db_185.h.src
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)db_185.h.src	8.4 (Sleepycat) 9/16/97
+ *	@(#)db_185.h.src	8.5 (Sleepycat) 1/15/98
  */
 
 #ifndef _DB_185_H_
@@ -173,6 +173,6 @@ extern "C" {
 DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
 
 #if defined(__cplusplus)
-};
+}
 #endif
 #endif /* !_DB_185_H_ */
diff --git a/db2/include/db_am.h b/db2/include/db_am.h
index 0ea24be667..304e3fd959 100644
--- a/db2/include/db_am.h
+++ b/db2/include/db_am.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_am.h	10.7 (Sleepycat) 10/25/97
+ *	@(#)db_am.h	10.8 (Sleepycat) 1/8/98
  */
 #ifndef _DB_AM_H
 #define _DB_AM_H
@@ -79,7 +79,7 @@
 	(void)func(logp, dbtp, lsnp, redo, info);
 #else
 #define	REC_PRINT(func)							\
-	info = info;			/* XXX: Shut the compiler up. */
+	COMPQUIET(info, NULL);
 #endif
 
 #include "db_auto.h"
diff --git a/db2/include/db_ext.h b/db2/include/db_ext.h
index 15eeaf50a3..122d8f13c1 100644
--- a/db2/include/db_ext.h
+++ b/db2/include/db_ext.h
@@ -1,16 +1,18 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _db_ext_h_
+#define _db_ext_h_
 int __db_pgerr __P((DB *, db_pgno_t));
 int __db_pgfmt __P((DB *, db_pgno_t));
 int __db_addrem_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
-    size_t, DBT *, DBT *, DB_LSN *));
+    size_t, const DBT *, const DBT *, DB_LSN *));
 int __db_addrem_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __db_addrem_read __P((void *, __db_addrem_args **));
 int __db_split_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    u_int32_t, u_int32_t, db_pgno_t, DBT *,
+    u_int32_t, u_int32_t, db_pgno_t, const DBT *,
     DB_LSN *));
 int __db_split_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
@@ -18,7 +20,7 @@ int __db_split_read __P((void *, __db_split_args **));
 int __db_big_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
-    db_pgno_t, DBT *, DB_LSN *, DB_LSN *,
+    db_pgno_t, const DBT *, DB_LSN *, DB_LSN *,
     DB_LSN *));
 int __db_big_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
@@ -45,7 +47,7 @@ int __db_addpage_print
 int __db_addpage_read __P((void *, __db_addpage_args **));
 int __db_debug_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    DBT *, u_int32_t, DBT *, DBT *,
+    const DBT *, u_int32_t, const DBT *, const DBT *,
     u_int32_t));
 int __db_debug_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
@@ -65,13 +67,14 @@ int __db_add_recovery __P((DB_ENV *,
 int __db_txnlist_init __P((void *));
 int __db_txnlist_add __P((void *, u_int32_t));
 int __db_txnlist_find __P((void *, u_int32_t));
+void __db_txnlist_print __P((void *));
 void __db_txnlist_end __P((void *));
 int __db_dput __P((DB *,
    DBT *, PAGE **, db_indx_t *, int (*)(DB *, u_int32_t, PAGE **)));
 int __db_drem __P((DB *,
    PAGE **, u_int32_t, int (*)(DB *, PAGE *)));
 int __db_dend __P((DB *, db_pgno_t, PAGE **));
- int __db_ditem __P((DB *, PAGE *, int, u_int32_t));
+ int __db_ditem __P((DB *, PAGE *, u_int32_t, u_int32_t));
 int __db_pitem
     __P((DB *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
 int __db_relink __P((DB *, PAGE *, PAGE **, int));
@@ -113,3 +116,4 @@ int __db_retcopy __P((DBT *,
    void *, u_int32_t, void **, u_int32_t *, void *(*)(size_t)));
 int __db_gethandle __P((DB *, int (*)(DB *, DB *), DB **));
 int __db_puthandle __P((DB *));
+#endif /* _db_ext_h_ */
diff --git a/db2/include/db_int.h.src b/db2/include/db_int.h.src
index 03a882fded..48790d6c9a 100644
--- a/db2/include/db_int.h.src
+++ b/db2/include/db_int.h.src
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_int.h.src	10.37 (Sleepycat) 11/25/97
+ *	@(#)db_int.h.src	10.41 (Sleepycat) 1/8/98
  */
 
 #ifndef _DB_INTERNAL_H_
@@ -18,14 +18,22 @@
 /*******************************************************
  * General purpose constants and macros.
  *******************************************************/
-#define	UINT32_T_MAX	0xffffffff	/* Maximum 32 bit unsigned. */
 #define	UINT16_T_MAX	    0xffff	/* Maximum 16 bit unsigned. */
+#define	UINT32_T_MAX	0xffffffff	/* Maximum 32 bit unsigned. */
 
 #define	DB_MIN_PGSIZE	0x000200	/* Minimum page size. */
 #define	DB_MAX_PGSIZE	0x010000	/* Maximum page size. */
 
 #define	DB_MINCACHE	10		/* Minimum cached pages */
 
+#define	MEGABYTE	1048576
+
+/*
+ * If we are unable to determine the underlying filesystem block size, use
+ * 8K on the grounds that most OS's use less than 8K as their VM page size.
+ */
+#define	DB_DEF_IOSIZE	(8 * 1024)
+
 /*
  * Aligning items to particular sizes or in pages or memory.  ALIGNP is a
  * separate macro, as we've had to cast the pointer to different integral
@@ -109,6 +117,9 @@ typedef struct __fn {
 #undef	DB_LINE
 #define	DB_LINE "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
 
+/* Unused, or not-used-yet variable.  "Shut that bloody compiler up!" */
+#define	COMPQUIET(n, v)	(n) = (v)
+
 /*******************************************************
  * Files.
  *******************************************************/
@@ -155,18 +166,22 @@ typedef struct __fn {
 
 /*
  * The offset of a mutex in memory.
+ *
+ * !!!
+ * Not an off_t, so backing file offsets MUST be less than 4Gb.  See the
+ * off field of the db_mutex_t as well.
  */
-#define	MUTEX_LOCK_OFFSET(a, b)	((off_t)((u_int8_t *)b - (u_int8_t *)a))
+#define	MUTEX_LOCK_OFFSET(a, b)	((u_int32_t)((u_int8_t *)b - (u_int8_t *)a))
 
 typedef struct _db_mutex_t {
 #ifdef HAVE_SPINLOCKS
-	tsl_t	tsl_resource;		/* Resource test and set. */
+	tsl_t	  tsl_resource;		/* Resource test and set. */
 #ifdef DEBUG
-	u_long	pid;			/* Lock holder: 0 or process pid. */
+	u_long	  pid;			/* Lock holder: 0 or process pid. */
 #endif
 #else
-	off_t	off;			/* Backing file offset. */
-	u_long	pid;			/* Lock holder: 0 or process pid. */
+	u_int32_t off;			/* Backing file offset. */
+	u_long	  pid;			/* Lock holder: 0 or process pid. */
 #endif
 	u_int32_t spins;		/* Spins before block. */
 	u_int32_t mutex_set_wait;	/* Granted after wait. */
diff --git a/db2/include/hash_ext.h b/db2/include/hash_ext.h
index 5abbb274f0..9b97d35a42 100644
--- a/db2/include/hash_ext.h
+++ b/db2/include/hash_ext.h
@@ -1,17 +1,19 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _hash_ext_h_
+#define _hash_ext_h_
 int __ham_open __P((DB *, DB_INFO *));
 int  __ham_close __P((DB *));
 int __ham_c_iclose __P((DB *, DBC *));
 int __ham_expand_table __P((HTAB *));
 u_int32_t __ham_call_hash __P((HTAB *, u_int8_t *, int32_t));
 int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *));
-void __ham_c_update __P((HTAB *,
-   HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
+void __ham_c_update
+   __P((HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
 int  __ham_hdup __P((DB *, DB *));
 int __ham_insdel_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
-    DB_LSN *, DBT *, DBT *));
+    DB_LSN *, const DBT *, const DBT *));
 int __ham_insdel_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __ham_insdel_read __P((void *, __ham_insdel_args **));
@@ -31,7 +33,7 @@ int __ham_splitmeta_print
 int __ham_splitmeta_read __P((void *, __ham_splitmeta_args **));
 int __ham_splitdata_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    u_int32_t, u_int32_t, db_pgno_t, DBT *,
+    u_int32_t, u_int32_t, db_pgno_t, const DBT *,
     DB_LSN *));
 int __ham_splitdata_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
@@ -39,7 +41,7 @@ int __ham_splitdata_read __P((void *, __ham_splitdata_args **));
 int __ham_replace_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
-    int32_t, DBT *, DBT *, u_int32_t));
+    int32_t, const DBT *, const DBT *, u_int32_t));
 int __ham_replace_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __ham_replace_read __P((void *, __ham_replace_args **));
@@ -61,7 +63,7 @@ int __ham_ovfl_read __P((void *, __ham_ovfl_args **));
 int __ham_copypage_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
-    DB_LSN *, db_pgno_t, DB_LSN *, DBT *));
+    DB_LSN *, db_pgno_t, DB_LSN *, const DBT *));
 int __ham_copypage_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __ham_copypage_read __P((void *, __ham_copypage_args **));
@@ -128,3 +130,4 @@ int __ham_ovfl_recover
 int __ham_copypage_recover
   __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __ham_stat __P((DB *, FILE *));
+#endif /* _hash_ext_h_ */
diff --git a/db2/include/lock_ext.h b/db2/include/lock_ext.h
index 0d0ba148b6..d983b29069 100644
--- a/db2/include/lock_ext.h
+++ b/db2/include/lock_ext.h
@@ -1,8 +1,14 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _lock_ext_h_
+#define _lock_ext_h_
+void __lock_dump_region __P((DB_LOCKTAB *, u_int));
+int __lock_is_locked
+   __P((DB_LOCKTAB *, u_int32_t, DBT *, db_lockmode_t));
 int __lock_getobj  __P((DB_LOCKTAB *,
-    u_int32_t, DBT *, u_int32_t type, DB_LOCKOBJ **));
-int __lock_cmp __P((DBT *, DB_LOCKOBJ *));
+    u_int32_t, const DBT *, u_int32_t type, DB_LOCKOBJ **));
+int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
 int __lock_locker_cmp __P((u_int32_t, DB_LOCKOBJ *));
-int __lock_ohash __P((DBT *));
+int __lock_ohash __P((const DBT *));
 u_int32_t __lock_locker_hash __P((u_int32_t));
 u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
+#endif /* _lock_ext_h_ */
diff --git a/db2/include/log.h b/db2/include/log.h
index 405daf4148..4e27b038d3 100644
--- a/db2/include/log.h
+++ b/db2/include/log.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)log.h	10.16 (Sleepycat) 11/9/97
+ *	@(#)log.h	10.19 (Sleepycat) 1/17/98
  */
 
 #ifndef _LOG_H_
@@ -15,15 +15,13 @@ struct __hdr;		typedef struct __hdr HDR;
 struct __log;		typedef struct __log LOG;
 struct __log_persist;	typedef struct __log_persist LOGP;
 
-#define	MEGABYTE	(1024 * 1024)
-
 #define	MAXLFNAME	99999		/* Maximum log file name. */
 #define	LFNAME		"log.%05d"	/* Log file name template. */
 
 					/* Default log name. */
 #define DB_DEFAULT_LOG_FILE	"__db_log.share"
 
-#define	DEFAULT_MAX	(10 * 1048576)	/* 10 Mb. */
+#define	DEFAULT_MAX	(10 * MEGABYTE)	/* 10 Mb. */
 
 /* Macros to lock/unlock the region and threads. */
 #define	LOCK_LOGTHREAD(dblp)						\
@@ -125,7 +123,7 @@ struct __log {
 
 	/*
 	 * The s_lsn LSN is the last LSN that we know is on disk, not just
-	 * written, by synced.
+	 * written, but synced.
 	 */
 	DB_LSN	  s_lsn;		/* LSN of the last sync. */
 
@@ -166,6 +164,11 @@ struct __fname {
 	size_t	  name_off;		/* Name offset. */
 };
 
+/* File open/close register log record opcodes. */
+#define	LOG_CHECKPOINT	1		/* Checkpoint: file name/id dump. */
+#define	LOG_CLOSE	2		/* File close. */
+#define	LOG_OPEN	3		/* File open. */
+
 #include "log_auto.h"
 #include "log_ext.h"
 #endif /* _LOG_H_ */
diff --git a/db2/include/log_auto.h b/db2/include/log_auto.h
index 820aac6acf..5717e140d7 100644
--- a/db2/include/log_auto.h
+++ b/db2/include/log_auto.h
@@ -8,20 +8,11 @@ typedef struct _log_register_args {
 	u_int32_t type;
 	DB_TXN *txnid;
 	DB_LSN prev_lsn;
+	u_int32_t	opcode;
 	DBT	name;
 	DBT	uid;
 	u_int32_t	id;
 	DBTYPE	ftype;
 } __log_register_args;
 
-
-#define	DB_log_unregister	(DB_log_BEGIN + 2)
-
-typedef struct _log_unregister_args {
-	u_int32_t type;
-	DB_TXN *txnid;
-	DB_LSN prev_lsn;
-	u_int32_t	id;
-} __log_unregister_args;
-
 #endif
diff --git a/db2/include/log_ext.h b/db2/include/log_ext.h
index c32d1d6af6..8640b134cd 100644
--- a/db2/include/log_ext.h
+++ b/db2/include/log_ext.h
@@ -1,18 +1,15 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
-int __log_find __P((DB_LOG *, int *));
+#ifndef _log_ext_h_
+#define _log_ext_h_
+int __log_find __P((DB_LOG *, int, int *));
 int __log_valid __P((DB_LOG *, LOG *, int));
 int __log_register_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    DBT *, DBT *, u_int32_t, DBTYPE));
+    u_int32_t, const DBT *, const DBT *, u_int32_t,
+    DBTYPE));
 int __log_register_print
    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __log_register_read __P((void *, __log_register_args **));
-int __log_unregister_log
-    __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
-    u_int32_t));
-int __log_unregister_print
-   __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __log_unregister_read __P((void *, __log_unregister_args **));
 int __log_init_print __P((DB_ENV *));
 int __log_init_recover __P((DB_ENV *));
 int __log_findckp __P((DB_LOG *, DB_LSN *));
@@ -21,9 +18,8 @@ int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, int));
 int __log_name __P((DB_LOG *, int, char **));
 int __log_register_recover
     __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __log_unregister_recover
-    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
 int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
 void __log_close_files __P((DB_LOG *));
 void __log_rem_logid __P((DB_LOG *, u_int32_t));
+#endif /* _log_ext_h_ */
diff --git a/db2/include/mp.h b/db2/include/mp.h
index f108246f2c..4efbf9b95e 100644
--- a/db2/include/mp.h
+++ b/db2/include/mp.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)mp.h	10.22 (Sleepycat) 11/28/97
+ *	@(#)mp.h	10.25 (Sleepycat) 1/8/98
  */
 
 struct __bh;		typedef struct __bh BH;
@@ -41,13 +41,17 @@ struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
  *	Acquire the region lock.
  *	Find the buffer header.
  *	Increment the reference count (guarantee the buffer stays).
- *	If the BH_LOCKED flag is set (I/O is going on):
- *		Release the region lock.
- *		Request the buffer lock.
- *		The I/O will complete...
- *		Acquire the buffer lock.
- *		Release the buffer lock.
- *		Acquire the region lock.
+ *	While the BH_LOCKED flag is set (I/O is going on) {
+ *	    Release the region lock.
+ *		Explicitly yield the processor if it's not the first pass
+ *		through this loop, otherwise, we can simply spin because
+ *		we'll be simply switching between the two locks.
+ *	    Request the buffer lock.
+ *	    The I/O will complete...
+ *	    Acquire the buffer lock.
+ *	    Release the buffer lock.
+ *	    Acquire the region lock.
+ *	}
  *	Return the buffer.
  *
  * Reading/writing a buffer:
@@ -57,12 +61,16 @@ struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
  *	Set the BH_LOCKED flag.
  *	Acquire the buffer lock (guaranteed not to block).
  *	Release the region lock.
- *	Do the I/O and/or initialize buffer contents.
+ *	Do the I/O and/or initialize the buffer contents.
+ *	Release the buffer lock.
+ *	    At this point, the buffer lock is available, but the logical
+ *	    operation (flagged by BH_LOCKED) is not yet completed.  For
+ *	    this reason, among others, threads checking the BH_LOCKED flag
+ *	    must loop around their test.
  *	Acquire the region lock.
  *	Clear the BH_LOCKED flag.
  *	Release the region lock.
- *	Release the buffer lock.
- *	If reading, return the buffer.
+ *	Return/discard the buffer.
  *
  * Pointers to DB_MPOOL, MPOOL, DB_MPOOLFILE and MPOOLFILE structures are not
  * reacquired when a region lock is reacquired because they couldn't have been
@@ -70,7 +78,8 @@ struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
  */
 #define	LOCKINIT(dbmp, mutexp)						\
 	if (F_ISSET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION))		\
-		(void)__db_mutex_init(mutexp, (dbmp)->fd)
+		(void)__db_mutex_init(mutexp,				\
+		    MUTEX_LOCK_OFFSET((dbmp)->maddr, mutexp))
 
 #define	LOCKHANDLE(dbmp, mutexp)					\
 	if (F_ISSET(dbmp, MP_LOCKHANDLE))				\
diff --git a/db2/include/mp_ext.h b/db2/include/mp_ext.h
index b78b3423cd..1928820637 100644
--- a/db2/include/mp_ext.h
+++ b/db2/include/mp_ext.h
@@ -1,4 +1,6 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _mp_ext_h_
+#define _mp_ext_h_
 int __memp_bhwrite
     __P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
 int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
@@ -14,3 +16,4 @@ int __memp_ralloc __P((DB_MPOOL *, size_t, size_t *, void *));
 int __memp_ropen
    __P((DB_MPOOL *, const char *, size_t, int, int));
 int __memp_rclose __P((DB_MPOOL *));
+#endif /* _mp_ext_h_ */
diff --git a/db2/include/mutex_ext.h b/db2/include/mutex_ext.h
index cb2d4886af..f0e68f3659 100644
--- a/db2/include/mutex_ext.h
+++ b/db2/include/mutex_ext.h
@@ -1,4 +1,7 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
-void __db_mutex_init __P((db_mutex_t *, off_t));
+#ifndef _mutex_ext_h_
+#define _mutex_ext_h_
+void __db_mutex_init __P((db_mutex_t *, u_int32_t));
 int __db_mutex_lock __P((db_mutex_t *, int));
 int __db_mutex_unlock __P((db_mutex_t *, int));
+#endif /* _mutex_ext_h_ */
diff --git a/db2/include/os_ext.h b/db2/include/os_ext.h
index 2edf2e257d..9c66a248c8 100644
--- a/db2/include/os_ext.h
+++ b/db2/include/os_ext.h
@@ -1,8 +1,11 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _os_ext_h_
+#define _os_ext_h_
 int __db_abspath __P((const char *));
 void *__db_calloc __P((size_t, size_t));
 void *__db_malloc __P((size_t));
 void *__db_realloc __P((void *, size_t));
+int __os_oldwin __P((void));
 int __os_dirlist __P((const char *, char ***, int *));
 void __os_dirfree __P((char **, int));
 int __db_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
@@ -19,5 +22,7 @@ int __os_seek __P((int, size_t, db_pgno_t, u_long, int));
 int __os_sleep __P((u_long, u_long));
 int __os_spin __P((void));
 int __os_exists __P((const char *, int *));
-int __os_ioinfo __P((const char *, int, off_t *, off_t *));
+int __os_ioinfo
+   __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *));
 int __db_unlink __P((const char *));
+#endif /* _os_ext_h_ */
diff --git a/db2/include/os_func.h b/db2/include/os_func.h
index 54b64ffaa2..b825fed5db 100644
--- a/db2/include/os_func.h
+++ b/db2/include/os_func.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)os_func.h	10.4 (Sleepycat) 11/28/97
+ *	@(#)os_func.h	10.5 (Sleepycat) 12/4/97
  */
 
 /* Calls which can be replaced by the application. */
@@ -17,8 +17,8 @@ struct __db_jumptab {
 		    __P((const char *, int *));
 	void	(*db_free) __P((void *));		/* DB_FUNC_FREE */
 	int	(*db_fsync) __P((int));			/* DB_FUNC_FSYNC */
-	int	(*db_ioinfo)				/* DB_FUNC_IOINFO */
-		    __P((const char *, int, off_t *, off_t *));
+	int	(*db_ioinfo) __P((const char *,		/* DB_FUNC_IOINFO */
+		    int, u_int32_t *, u_int32_t *, u_int32_t *));
 	void   *(*db_malloc) __P((size_t));		/* DB_FUNC_MALLOC */
 	int	(*db_map)				/* DB_FUNC_MAP */
 		    __P((int, size_t, int, int, void **));
diff --git a/db2/include/txn_ext.h b/db2/include/txn_ext.h
index 9b617bb68c..7d694f070d 100644
--- a/db2/include/txn_ext.h
+++ b/db2/include/txn_ext.h
@@ -1,4 +1,6 @@
 /* DO NOT EDIT: automatically built by dist/distrib. */
+#ifndef _txn_ext_h_
+#define _txn_ext_h_
 int __txn_regop_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     u_int32_t));
@@ -16,3 +18,4 @@ int __txn_init_recover __P((DB_ENV *));
 int __txn_regop_recover
     __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __txn_ckp_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
+#endif /* _txn_ext_h_ */
diff --git a/db2/lock/lock.c b/db2/lock/lock.c
index 9b1cbc8a08..0846d3c29f 100644
--- a/db2/lock/lock.c
+++ b/db2/lock/lock.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)lock.c	10.41 (Sleepycat) 11/28/97";
+static const char sccsid[] = "@(#)lock.c	10.43 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -79,14 +79,15 @@ __lock_create(path, mode, dbenv)
 	u_int maxlocks;
 	u_int32_t i;
 	int fd, lock_modes, nelements, ret;
-	u_int8_t *conflicts, *curaddr;
+	const u_int8_t *conflicts;
+	u_int8_t *curaddr;
 
 	maxlocks = dbenv == NULL || dbenv->lk_max == 0 ?
 	    DB_LOCK_DEFAULT_N : dbenv->lk_max;
 	lock_modes = dbenv == NULL || dbenv->lk_modes == 0 ?
 	    DB_LOCK_RW_N : dbenv->lk_modes;
 	conflicts = dbenv == NULL || dbenv->lk_conflicts == NULL ?
-	    (u_int8_t *)db_rw_conflicts : dbenv->lk_conflicts;
+	    db_rw_conflicts : dbenv->lk_conflicts;
 
 	if ((ret =
 	    __db_rcreate(dbenv, DB_APP_NONE, path, DB_DEFAULT_LOCK_FILE, mode,
@@ -666,8 +667,7 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp)
 	newl->holder = locker;
 	newl->refcount = 1;
 
-	if ((ret =
-	    __lock_getobj(lt, 0, (DBT *)obj, DB_LOCK_OBJTYPE, &sh_obj)) != 0)
+	if ((ret = __lock_getobj(lt, 0, obj, DB_LOCK_OBJTYPE, &sh_obj)) != 0)
 		return (ret);
 
 	lrp = lt->region;			/* getobj might have grown */
@@ -955,10 +955,15 @@ __lock_grow_region(lt, which, howmuch)
 }
 
 #ifdef DEBUG
+/*
+ * __lock_dump_region --
+ *
+ * PUBLIC: void __lock_dump_region __P((DB_LOCKTAB *, u_int));
+ */
 void
 __lock_dump_region(lt, flags)
 	DB_LOCKTAB *lt;
-	unsigned long flags;
+	u_int flags;
 {
 	struct __db_lock *lp;
 	DB_LOCKOBJ *op;
@@ -1096,6 +1101,12 @@ __lock_dump_object(lt, op)
 	}
 }
 
+/*
+ * __lock_is_locked --
+ *
+ * PUBLIC: int __lock_is_locked
+ * PUBLIC:    __P((DB_LOCKTAB *, u_int32_t, DBT *, db_lockmode_t));
+ */
 int
 __lock_is_locked(lt, locker, dbt, mode)
 	DB_LOCKTAB *lt;
@@ -1135,7 +1146,7 @@ __lock_printlock(lt, lp, ispgno)
 	db_pgno_t pgno;
 	size_t obj;
 	u_int8_t *ptr;
-	char *mode, *stat;
+	const char *mode, *status;
 
 	switch (lp->mode) {
 	case DB_LOCK_IREAD:
@@ -1162,32 +1173,32 @@ __lock_printlock(lt, lp, ispgno)
 	}
 	switch (lp->status) {
 	case DB_LSTAT_ABORTED:
-		stat = "ABORT";
+		status = "ABORT";
 		break;
 	case DB_LSTAT_ERR:
-		stat = "ERROR";
+		status = "ERROR";
 		break;
 	case DB_LSTAT_FREE:
-		stat = "FREE";
+		status = "FREE";
 		break;
 	case DB_LSTAT_HELD:
-		stat = "HELD";
+		status = "HELD";
 		break;
 	case DB_LSTAT_NOGRANT:
-		stat = "NONE";
+		status = "NONE";
 		break;
 	case DB_LSTAT_WAITING:
-		stat = "WAIT";
+		status = "WAIT";
 		break;
 	case DB_LSTAT_PENDING:
-		stat = "PENDING";
+		status = "PENDING";
 		break;
 	default:
-		stat = "UNKNOWN";
+		status = "UNKNOWN";
 		break;
 	}
 	printf("\t%lx\t%s\t%lu\t%s\t",
-	    (u_long)lp->holder, mode, (u_long)lp->refcount, stat);
+	    (u_long)lp->holder, mode, (u_long)lp->refcount, status);
 
 	lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
 	ptr = SH_DBT_PTR(&lockobj->lockobj);
@@ -1202,7 +1213,6 @@ __lock_printlock(lt, lp, ispgno)
 		printf("\n");
 	}
 }
-
 #endif
 
 static int
@@ -1239,13 +1249,13 @@ __lock_count_objs(lrp)
 
 /*
  * PUBLIC: int __lock_getobj  __P((DB_LOCKTAB *,
- * PUBLIC:     u_int32_t, DBT *, u_int32_t type, DB_LOCKOBJ **));
+ * PUBLIC:     u_int32_t, const DBT *, u_int32_t type, DB_LOCKOBJ **));
  */
 int
 __lock_getobj(lt, locker, dbt, type, objp)
 	DB_LOCKTAB *lt;
 	u_int32_t locker, type;
-	DBT *dbt;
+	const DBT *dbt;
 	DB_LOCKOBJ **objp;
 {
 	DB_LOCKREGION *lrp;
diff --git a/db2/lock/lock_util.c b/db2/lock/lock_util.c
index 4063849f28..6c1e30f27c 100644
--- a/db2/lock/lock_util.c
+++ b/db2/lock/lock_util.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)lock_util.c	10.4 (Sleepycat) 7/22/97";
+static const char sccsid[] = "@(#)lock_util.c	10.5 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -35,11 +35,11 @@ static const char sccsid[] = "@(#)lock_util.c	10.4 (Sleepycat) 7/22/97";
  * that it just returns true on equal and 0 on not-equal.  Therefore this
  * cannot be used as a sort function; its purpose is to be used as a
  * hash comparison function.
- * PUBLIC: int __lock_cmp __P((DBT *, DB_LOCKOBJ *));
+ * PUBLIC: int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
  */
 int
 __lock_cmp(dbt, lock_obj)
-	DBT *dbt;
+	const DBT *dbt;
 	DB_LOCKOBJ *lock_obj;
 {
 	void *obj_data;
@@ -69,11 +69,11 @@ __lock_locker_cmp(locker, lock_obj)
 }
 
 /*
- * PUBLIC: int __lock_ohash __P((DBT *));
+ * PUBLIC: int __lock_ohash __P((const DBT *));
  */
 int
 __lock_ohash(dbt)
-	DBT *dbt;
+	const DBT *dbt;
 {
 	return (__ham_func5(dbt->data, dbt->size));
 }
diff --git a/db2/log/log.c b/db2/log/log.c
index a9bf7a95ab..8013d42aef 100644
--- a/db2/log/log.c
+++ b/db2/log/log.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log.c	10.34 (Sleepycat) 11/28/97";
+static const char sccsid[] = "@(#)log.c	10.39 (Sleepycat) 1/17/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -203,28 +203,21 @@ __log_recover(dblp)
 	 * Find a log file.  If none exist, we simply return, leaving
 	 * everything initialized to a new log.
 	 */
-	if ((ret = __log_find(dblp, &cnt)) != 0)
+	if ((ret = __log_find(dblp, 0, &cnt)) != 0)
 		return (ret);
 	if (cnt == 0)
 		return (0);
 
-	/* We have a log file name, find the last one. */
-	while (cnt < MAXLFNAME)
-		if (__log_valid(dblp, lp, ++cnt) != 0) {
-			--cnt;
-			break;
-		}
-
 	/*
 	 * We have the last useful log file and we've loaded any persistent
 	 * information.  Pretend that the log is larger than it can possibly
-	 * be, and read this file, looking for a checkpoint and its end.
+	 * be, and read the last file, looking for the last checkpoint and
+	 * the log's end.
 	 */
-	dblp->c_lsn.file = cnt;
-	dblp->c_lsn.offset = 0;
-	lsn = dblp->c_lsn;
 	lp->lsn.file = cnt + 1;
 	lp->lsn.offset = 0;
+	lsn.file = cnt;
+	lsn.offset = 0;
 
 	/* Set the cursor.  Shouldn't fail, leave error messages on. */
 	memset(&dbt, 0, sizeof(dbt));
@@ -264,9 +257,8 @@ __log_recover(dblp)
 	 * one in the last log file.  Start searching.
 	 */
 	while (!found_checkpoint && cnt > 1) {
-		dblp->c_lsn.file = --cnt;
-		dblp->c_lsn.offset = 0;
-		lsn = dblp->c_lsn;
+		lsn.file = --cnt;
+		lsn.offset = 0;
 
 		/* Set the cursor.  Shouldn't fail, leave error messages on. */
 		if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
@@ -288,36 +280,35 @@ __log_recover(dblp)
 	}
 
 	/* If we never find a checkpoint, that's okay, just 0 it out. */
-	if (!found_checkpoint) {
-		lp->c_lsn.file = 1;
-		lp->c_lsn.offset = 0;
-	}
+	if (!found_checkpoint)
+		ZERO_LSN(lp->c_lsn);
 
 	__db_err(dblp->dbenv,
 	    "Recovering the log: last valid LSN: file: %lu offset %lu",
 	    (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
 
-	/* Reset the cursor.  */
-	ZERO_LSN(dblp->c_lsn);
-
 	return (0);
 }
 
 /*
  * __log_find --
- *	Try to find a log file.
+ *	Try to find a log file.  If find_first is set, valp will contain
+ * the number of the first log file, else it will contain the number of
+ * the last log file.
  *
- * PUBLIC: int __log_find __P((DB_LOG *, int *));
+ * PUBLIC: int __log_find __P((DB_LOG *, int, int *));
  */
 int
-__log_find(dblp, valp)
+__log_find(dblp, find_first, valp)
 	DB_LOG *dblp;
-	int *valp;
+	int find_first, *valp;
 {
 	int cnt, fcnt, logval, ret;
 	const char *dir;
 	char **names, *p, *q;
 
+	*valp = 0;
+
 	/* Find the directory name. */
 	if ((ret = __log_name(dblp, 1, &p)) != 0)
 		return (ret);
@@ -340,21 +331,29 @@ __log_find(dblp, valp)
 	 * Search for a valid log file name, return a value of 0 on
 	 * failure.
 	 */
-	*valp = 0;
 	for (cnt = fcnt, logval = 0; --cnt >= 0;)
 		if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) {
 			logval = atoi(names[cnt] + 4);
 			if (logval != 0 &&
-			    __log_valid(dblp, dblp->lp, logval) == 0) {
-				*valp = logval;
+			    __log_valid(dblp, dblp->lp, logval) == 0)
 				break;
-			}
 		}
 
 	/* Discard the list. */
 	__db_dirfree(names, fcnt);
 
-	return (ret);
+	/* We have a valid log file, find either the first or last one. */
+	if (find_first) {
+		for (; logval > 0; --logval)
+			if (__log_valid(dblp, dblp->lp, logval - 1) != 0)
+				break;
+	} else
+		for (; logval < MAXLFNAME; ++logval)
+			if (__log_valid(dblp, dblp->lp, logval + 1) != 0)
+				break;
+	*valp = logval;
+
+	return (0);
 }
 
 /*
@@ -508,6 +507,10 @@ log_stat(dblp, gspp, db_malloc)
 
 	(*gspp)->st_region_nowait = lp->rlayout.lock.mutex_set_nowait;
 	(*gspp)->st_region_wait = lp->rlayout.lock.mutex_set_wait;
+
+	(*gspp)->st_cur_file = lp->lsn.file;
+	(*gspp)->st_cur_offset = lp->lsn.offset;
+
 	UNLOCK_LOGREGION(dblp);
 
 	return (0);
diff --git a/db2/log/log.src b/db2/log/log.src
index 9f4829179b..f3d9f32b2d 100644
--- a/db2/log/log.src
+++ b/db2/log/log.src
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)log.src	10.3 (Sleepycat) 8/20/97
+ *	@(#)log.src	10.4 (Sleepycat) 1/17/98
  *
  * This is the source file used to create the logging functions for the
  * log package.  Each access method (or set of routines wishing to register
@@ -40,14 +40,11 @@
  */
 PREFIX	log
 
-/* Used for registering new name/id translations. */
+/* Used for registering name/id translations at open or close. */
 BEGIN	register
+ARG	opcode		u_int32_t	lu
 DBT	name		DBT		s
 DBT	uid		DBT		s
 ARG	id		u_int32_t	lu
 ARG	ftype		DBTYPE		lx
 END
-
-BEGIN	unregister
-ARG	id		u_int32_t	lu
-END
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
index 0248e2815c..91ae5abe0b 100644
--- a/db2/log/log_archive.c
+++ b/db2/log/log_archive.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_archive.c	10.29 (Sleepycat) 11/12/97";
+static const char sccsid[] = "@(#)log_archive.c	10.30 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -49,7 +49,7 @@ log_archive(dblp, listp, flags, db_malloc)
 	int array_size, n, ret;
 	char **array, **arrayp, *name, *p, *pref, buf[MAXPATHLEN];
 
-	fnum = 0;				/* XXX: Shut the compiler up. */
+	COMPQUIET(fnum, 0);
 
 #define	OKFLAGS	(DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
 	if (flags != 0) {
diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c
index 61626b090e..2fe17834c3 100644
--- a/db2/log/log_auto.c
+++ b/db2/log/log_auto.c
@@ -20,16 +20,18 @@
 /*
  * PUBLIC: int __log_register_log
  * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     DBT *, DBT *, u_int32_t, DBTYPE));
+ * PUBLIC:     u_int32_t, const DBT *, const DBT *, u_int32_t,
+ * PUBLIC:     DBTYPE));
  */
 int __log_register_log(logp, txnid, ret_lsnp, flags,
-	name, uid, id, ftype)
+	opcode, name, uid, id, ftype)
 	DB_LOG *logp;
 	DB_TXN *txnid;
 	DB_LSN *ret_lsnp;
 	u_int32_t flags;
-	DBT *name;
-	DBT *uid;
+	u_int32_t opcode;
+	const DBT *name;
+	const DBT *uid;
 	u_int32_t id;
 	DBTYPE ftype;
 {
@@ -49,6 +51,7 @@ int __log_register_log(logp, txnid, ret_lsnp, flags,
 	} else
 		lsnp = &txnid->last_lsn;
 	logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
+	    + sizeof(opcode)
 	    + sizeof(u_int32_t) + (name == NULL ? 0 : name->size)
 	    + sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size)
 	    + sizeof(id)
@@ -63,6 +66,8 @@ int __log_register_log(logp, txnid, ret_lsnp, flags,
 	bp += sizeof(txn_num);
 	memcpy(bp, lsnp, sizeof(DB_LSN));
 	bp += sizeof(DB_LSN);
+	memcpy(bp, &opcode, sizeof(opcode));
+	bp += sizeof(opcode);
 	if (name == NULL) {
 		zero = 0;
 		memcpy(bp, &zero, sizeof(u_int32_t));
@@ -129,6 +134,7 @@ __log_register_print(notused1, dbtp, lsnp, notused3, notused4)
 	    (u_long)argp->txnid->txnid,
 	    (u_long)argp->prev_lsn.file,
 	    (u_long)argp->prev_lsn.offset);
+	printf("\topcode: %lu\n", (u_long)argp->opcode);
 	printf("\tname: ");
 	for (i = 0; i < argp->name.size; i++) {
 		c = ((char *)argp->name.data)[i];
@@ -177,6 +183,8 @@ __log_register_read(recbuf, argpp)
 	bp += sizeof(argp->txnid->txnid);
 	memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
 	bp += sizeof(DB_LSN);
+	memcpy(&argp->opcode, bp, sizeof(argp->opcode));
+	bp += sizeof(argp->opcode);
 	memcpy(&argp->name.size, bp, sizeof(u_int32_t));
 	bp += sizeof(u_int32_t);
 	argp->name.data = bp;
@@ -194,124 +202,6 @@ __log_register_read(recbuf, argpp)
 }
 
 /*
- * PUBLIC: int __log_unregister_log
- * PUBLIC:     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC:     u_int32_t));
- */
-int __log_unregister_log(logp, txnid, ret_lsnp, flags,
-	id)
-	DB_LOG *logp;
-	DB_TXN *txnid;
-	DB_LSN *ret_lsnp;
-	u_int32_t flags;
-	u_int32_t id;
-{
-	DBT logrec;
-	DB_LSN *lsnp, null_lsn;
-	u_int32_t rectype, txn_num;
-	int ret;
-	u_int8_t *bp;
-
-	rectype = DB_log_unregister;
-	txn_num = txnid == NULL ? 0 : txnid->txnid;
-	if (txnid == NULL) {
-		null_lsn.file = 0;
-		null_lsn.offset = 0;
-		lsnp = &null_lsn;
-	} else
-		lsnp = &txnid->last_lsn;
-	logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
-	    + sizeof(id);
-	if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
-		return (ENOMEM);
-
-	bp = logrec.data;
-	memcpy(bp, &rectype, sizeof(rectype));
-	bp += sizeof(rectype);
-	memcpy(bp, &txn_num, sizeof(txn_num));
-	bp += sizeof(txn_num);
-	memcpy(bp, lsnp, sizeof(DB_LSN));
-	bp += sizeof(DB_LSN);
-	memcpy(bp, &id, sizeof(id));
-	bp += sizeof(id);
-#ifdef DEBUG
-	if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
-		fprintf(stderr, "Error in log record length");
-#endif
-	ret = __log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
-	if (txnid != NULL)
-		txnid->last_lsn = *ret_lsnp;
-	__db_free(logrec.data);
-	return (ret);
-}
-
-/*
- * PUBLIC: int __log_unregister_print
- * PUBLIC:    __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_unregister_print(notused1, dbtp, lsnp, notused3, notused4)
-	DB_LOG *notused1;
-	DBT *dbtp;
-	DB_LSN *lsnp;
-	int notused3;
-	void *notused4;
-{
-	__log_unregister_args *argp;
-	u_int32_t i;
-	int c, ret;
-
-	i = 0;
-	c = 0;
-	notused1 = NULL;
-	notused3 = 0;
-	notused4 = NULL;
-
-	if ((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
-		return (ret);
-	printf("[%lu][%lu]log_unregister: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
-	    (u_long)lsnp->file,
-	    (u_long)lsnp->offset,
-	    (u_long)argp->type,
-	    (u_long)argp->txnid->txnid,
-	    (u_long)argp->prev_lsn.file,
-	    (u_long)argp->prev_lsn.offset);
-	printf("\tid: %lu\n", (u_long)argp->id);
-	printf("\n");
-	__db_free(argp);
-	return (0);
-}
-
-/*
- * PUBLIC: int __log_unregister_read __P((void *, __log_unregister_args **));
- */
-int
-__log_unregister_read(recbuf, argpp)
-	void *recbuf;
-	__log_unregister_args **argpp;
-{
-	__log_unregister_args *argp;
-	u_int8_t *bp;
-
-	argp = (__log_unregister_args *)__db_malloc(sizeof(__log_unregister_args) +
-	    sizeof(DB_TXN));
-	if (argp == NULL)
-		return (ENOMEM);
-	argp->txnid = (DB_TXN *)&argp[1];
-	bp = recbuf;
-	memcpy(&argp->type, bp, sizeof(argp->type));
-	bp += sizeof(argp->type);
-	memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
-	bp += sizeof(argp->txnid->txnid);
-	memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
-	bp += sizeof(DB_LSN);
-	memcpy(&argp->id, bp, sizeof(argp->id));
-	bp += sizeof(argp->id);
-	*argpp = argp;
-	return (0);
-}
-
-/*
  * PUBLIC: int __log_init_print __P((DB_ENV *));
  */
 int
@@ -323,9 +213,6 @@ __log_init_print(dbenv)
 	if ((ret = __db_add_recovery(dbenv,
 	    __log_register_print, DB_log_register)) != 0)
 		return (ret);
-	if ((ret = __db_add_recovery(dbenv,
-	    __log_unregister_print, DB_log_unregister)) != 0)
-		return (ret);
 	return (0);
 }
 
@@ -341,9 +228,6 @@ __log_init_recover(dbenv)
 	if ((ret = __db_add_recovery(dbenv,
 	    __log_register_recover, DB_log_register)) != 0)
 		return (ret);
-	if ((ret = __db_add_recovery(dbenv,
-	    __log_unregister_recover, DB_log_unregister)) != 0)
-		return (ret);
 	return (0);
 }
 
diff --git a/db2/log/log_get.c b/db2/log/log_get.c
index 2d1512c6b9..ab6f6247cb 100644
--- a/db2/log/log_get.c
+++ b/db2/log/log_get.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_get.c	10.22 (Sleepycat) 11/22/97";
+static const char sccsid[] = "@(#)log_get.c	10.24 (Sleepycat) 1/17/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -122,7 +122,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
 	nlsn = dblp->c_lsn;
 	switch (flags) {
 	case DB_CHECKPOINT:
-		nlsn = dblp->lp->c_lsn;
+		nlsn = lp->c_lsn;
 		if (IS_ZERO_LSN(nlsn)) {
 			__db_err(dblp->dbenv,
 	"log_get: unable to find checkpoint record: no checkpoint set.");
@@ -138,26 +138,18 @@ __log_get(dblp, alsn, dbt, flags, silent)
 		}
 		/* FALLTHROUGH */
 	case DB_FIRST:				/* Find the first log record. */
-		/*
-		 * Find any log file.  Note, we may have only entered records
-		 * in the buffer, and not yet written a log file.
-		 */
-		if ((ret = __log_find(dblp, &cnt)) != 0) {
-			__db_err(dblp->dbenv,
-	"log_get: unable to find the first record: no log files found.");
+		/* Find the first log file. */
+		if ((ret = __log_find(dblp, 1, &cnt)) != 0)
 			goto err2;
-		}
 
-		/* If there's anything in the buffer, it belongs to file 1. */
+		/*
+		 * We may have only entered records in the buffer, and not
+		 * yet written a log file.  If no log files were found and
+		 * there's anything in the buffer, it belongs to file 1.
+		 */
 		if (cnt == 0)
 			cnt = 1;
 
-		/* Now go backwards to find the smallest one. */
-		for (; cnt > 1; --cnt)
-			if (__log_valid(dblp, NULL, cnt) != 0) {
-				++cnt;
-				break;
-			}
 		nlsn.file = cnt;
 		nlsn.offset = 0;
 		break;
diff --git a/db2/log/log_put.c b/db2/log/log_put.c
index 42fec88a7d..65a3990799 100644
--- a/db2/log/log_put.c
+++ b/db2/log/log_put.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_put.c	10.22 (Sleepycat) 11/12/97";
+static const char sccsid[] = "@(#)log_put.c	10.24 (Sleepycat) 1/17/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -82,8 +82,7 @@ __log_put(dblp, lsn, dbt, flags)
 	const DBT *dbt;
 	int flags;
 {
-	DBT t;
-	DBT fid_dbt;
+	DBT fid_dbt, t;
 	DB_LSN r_unused;
 	FNAME *fnp;
 	LOG *lp;
@@ -156,13 +155,15 @@ __log_put(dblp, lsn, dbt, flags)
 
 		for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
 		    fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
+			memset(&t, 0, sizeof(t));
 			t.data = R_ADDR(dblp, fnp->name_off);
 			t.size = strlen(t.data) + 1;
 			memset(&fid_dbt, 0, sizeof(fid_dbt));
 			fid_dbt.data = R_ADDR(dblp, fnp->fileid_off);
 			fid_dbt.size = DB_FILE_ID_LEN;
-			if ((ret = __log_register_log(dblp, NULL, &r_unused,
-			    0, &t, &fid_dbt, fnp->id, fnp->s_type)) != 0)
+			if ((ret = __log_register_log(dblp, NULL, &r_unused, 0,
+			    LOG_CHECKPOINT, &t, &fid_dbt, fnp->id, fnp->s_type))
+			    != 0)
 				return (ret);
 		}
 	}
@@ -280,7 +281,7 @@ __log_flush(dblp, lsn)
 
 	/*
 	 * If the LSN is less than the last-sync'd LSN, we're done.  Note,
-	 * the last-sync LSN saved in s_lsn is the LSN of the first byte 
+	 * the last-sync LSN saved in s_lsn is the LSN of the first byte
 	 * we absolutely know has been written to disk, so the test is <=.
 	 */
 	if (lsn->file < lp->s_lsn.file ||
diff --git a/db2/log/log_rec.c b/db2/log/log_rec.c
index 92b8203990..69334f8bc8 100644
--- a/db2/log/log_rec.c
+++ b/db2/log/log_rec.c
@@ -40,7 +40,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_rec.c	10.14 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)log_rec.c	10.16 (Sleepycat) 1/17/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -80,73 +80,53 @@ __log_register_recover(logp, dbtp, lsnp, redo, info)
 #ifdef DEBUG_RECOVER
 	__log_register_print(logp, dbtp, lsnp, redo, info);
 #endif
-	info = info;				/* XXX: Shut the compiler up. */
-	lsnp = lsnp;
+	COMPQUIET(info, NULL);
+	COMPQUIET(lsnp, NULL);
 
 	F_SET(logp, DB_AM_RECOVER);
 
 	if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
 		goto out;
 
-	ret = __log_open_file(logp,
-	    argp->uid.data, argp->name.data, argp->ftype, argp->id);
-	if (ret == ENOENT) {
-		if (redo == TXN_OPENFILES)
-			__db_err(logp->dbenv,
-			    "warning: file %s not found", argp->name.data);
-		ret = 0;
-	}
-
-out:	F_CLR(logp, DB_AM_RECOVER);
-	if (argp != NULL)
-		__db_free(argp);
-	return (ret);
-}
-
-/*
- * PUBLIC: int __log_unregister_recover
- * PUBLIC:     __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_unregister_recover(logp, dbtp, lsnp, redo, info)
-	DB_LOG *logp;
-	DBT *dbtp;
-	DB_LSN *lsnp;
-	int redo;
-	void *info;
-{
-	__log_unregister_args *argp;
-	int ret;
-
-#ifdef DEBUG_RECOVER
-	__log_unregister_print(logp, dbtp, lsnp, redo, info);
-#endif
-	info = info;				/* XXX: Shut the compiler up. */
-	lsnp = lsnp;
-
-	if (redo == TXN_OPENFILES ||
-	    redo == TXN_BACKWARD_ROLL || redo == TXN_UNDO)
-		return (0);
-
-	F_SET(logp, DB_AM_RECOVER);
-	if ((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
-		goto out;
-
-	/*
-	 * If the file is deleted, then we can just ignore this close.
-	 * Otherwise, we'd better have a valid dbp that we should either
-	 * close or whose reference count should be decremented.
-	 */
-	LOCK_LOGTHREAD(logp);
-	if (logp->dbentry[argp->id].dbp == NULL) {
-		if (!logp->dbentry[argp->id].deleted)
-			ret = EINVAL;
-	} else if (--logp->dbentry[argp->id].refcount == 0) {
-		ret = logp->dbentry[argp->id].dbp->close(
-		    logp->dbentry[argp->id].dbp, 0);
-		logp->dbentry[argp->id].dbp = NULL;
+	if ((argp->opcode == LOG_CHECKPOINT && redo == TXN_OPENFILES) ||
+	    (argp->opcode == LOG_OPEN &&
+	    (redo == TXN_REDO || redo == TXN_OPENFILES || 
+	     redo == TXN_FORWARD_ROLL)) ||
+	    (argp->opcode == LOG_CLOSE &&
+	    (redo == TXN_UNDO || redo == TXN_BACKWARD_ROLL))) {
+		/*
+		 * If we are redoing an open or undoing a close, then we need
+		 * to open a file.
+		 */
+		ret = __log_open_file(logp,
+		    argp->uid.data, argp->name.data, argp->ftype, argp->id);
+		if (ret == ENOENT) {
+			if (redo == TXN_OPENFILES)
+				__db_err(logp->dbenv,
+				    "warning: file %s not found",
+				    argp->name.data);
+			ret = 0;
+		}
+	} else if (argp->opcode != LOG_CHECKPOINT) {
+		/*
+		 * If we are redoing a close or undoing an open, then we need
+		 * to close the file.
+		 *
+		 * If the file is deleted, then we can just ignore this close.
+		 * Otherwise, we'd better have a valid dbp that we should either
+		 * close or whose reference count should be decremented.
+		 */
+		LOCK_LOGTHREAD(logp);
+		if (logp->dbentry[argp->id].dbp == NULL) {
+			if (!logp->dbentry[argp->id].deleted)
+				ret = EINVAL;
+		} else if (--logp->dbentry[argp->id].refcount == 0) {
+			ret = logp->dbentry[argp->id].dbp->close(
+			    logp->dbentry[argp->id].dbp, 0);
+			logp->dbentry[argp->id].dbp = NULL;
+		}
+		UNLOCK_LOGTHREAD(logp);
 	}
-	UNLOCK_LOGTHREAD(logp);
 
 out:	F_CLR(logp, DB_AM_RECOVER);
 	if (argp != NULL)
diff --git a/db2/log/log_register.c b/db2/log/log_register.c
index 2dab361616..9907d6e25a 100644
--- a/db2/log/log_register.c
+++ b/db2/log/log_register.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_register.c	10.12 (Sleepycat) 9/29/97";
+static const char sccsid[] = "@(#)log_register.c	10.14 (Sleepycat) 1/19/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -35,8 +35,7 @@ log_register(dblp, dbp, name, type, idp)
 	DBTYPE type;
 	u_int32_t *idp;
 {
-	DBT r_name;
-	DBT fid_dbt;
+	DBT fid_dbt, r_name;
 	DB_LSN r_unused;
 	FNAME *fnp;
 	size_t len;
@@ -75,10 +74,7 @@ log_register(dblp, dbp, name, type, idp)
 		    R_ADDR(dblp, fnp->fileid_off), DB_FILE_ID_LEN)) {
 			++fnp->ref;
 			fid = fnp->id;
-			if (!F_ISSET(dblp, DB_AM_RECOVER) &&
-			    (ret = __log_add_logid(dblp, dbp, fid) != 0))
-				goto err;
-			goto ret1;
+			goto found;
 		}
 	}
 
@@ -107,7 +103,7 @@ log_register(dblp, dbp, name, type, idp)
 	SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
 	inserted = 1;
 
-	/* Log the registry. */
+found:	/* Log the registry. */
 	if (!F_ISSET(dblp, DB_AM_RECOVER)) {
 		r_name.data = (void *)name;		/* XXX: Yuck! */
 		r_name.size = strlen(name) + 1;
@@ -115,7 +111,7 @@ log_register(dblp, dbp, name, type, idp)
 		fid_dbt.data = dbp->lock.fileid;
 		fid_dbt.size = DB_FILE_ID_LEN;
 		if ((ret = __log_register_log(dblp, NULL, &r_unused,
-		    0, &r_name, &fid_dbt, fid, type)) != 0)
+		    0, LOG_OPEN, &r_name, &fid_dbt, fid, type)) != 0)
 			goto err;
 		if ((ret = __log_add_logid(dblp, dbp, fid)) != 0)
 			goto err;
@@ -136,7 +132,7 @@ err:		/*
 			__db_shalloc_free(dblp->addr, fnp);
 	}
 
-ret1:	UNLOCK_LOGREGION(dblp);
+	UNLOCK_LOGREGION(dblp);
 
 	if (fullname != NULL)
 		FREES(fullname);
@@ -155,6 +151,7 @@ log_unregister(dblp, fid)
 	DB_LOG *dblp;
 	u_int32_t fid;
 {
+	DBT fid_dbt, r_name;
 	DB_LSN r_unused;
 	FNAME *fnp;
 	int ret;
@@ -162,11 +159,6 @@ log_unregister(dblp, fid)
 	ret = 0;
 	LOCK_LOGREGION(dblp);
 
-	/* Unlog the registry. */
-	if (!F_ISSET(dblp, DB_AM_RECOVER) &&
-	    (ret = __log_unregister_log(dblp, NULL, &r_unused, 0, fid)) != 0)
-		return (ret);
-
 	/* Find the entry in the log. */
 	for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
 	    fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname))
@@ -178,17 +170,31 @@ log_unregister(dblp, fid)
 		goto ret1;
 	}
 
-	/* If more than 1 reference, decrement the reference and return. */
-	if (fnp->ref > 1) {
-		--fnp->ref;
-		goto ret1;
+	/* Unlog the registry. */
+	if (!F_ISSET(dblp, DB_AM_RECOVER)) {
+		memset(&r_name, 0, sizeof(r_name));
+		r_name.data = R_ADDR(dblp, fnp->name_off);
+		r_name.size = strlen(r_name.data) + 1;
+		memset(&fid_dbt, 0, sizeof(fid_dbt));
+		fid_dbt.data =  R_ADDR(dblp, fnp->fileid_off);
+		fid_dbt.size = DB_FILE_ID_LEN;
+		if ((ret = __log_register_log(dblp, NULL, &r_unused,
+		    0, LOG_CLOSE, &r_name, &fid_dbt, fid, fnp->s_type)) != 0)
+			goto ret1;
 	}
 
-	/* Free the unique file information, name and structure. */
-	__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->fileid_off));
-	__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
-	SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
-	__db_shalloc_free(dblp->addr, fnp);
+	/*
+	 * If more than 1 reference, just decrement the reference and return.
+	 * Otherwise, free the unique file information, name and structure.
+	 */
+	if (fnp->ref > 1)
+		--fnp->ref;
+	else {
+		__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->fileid_off));
+		__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
+		SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
+		__db_shalloc_free(dblp->addr, fnp);
+	}
 
 	/*
 	 * Remove from the process local table.  If this operation is taking
@@ -199,6 +205,5 @@ log_unregister(dblp, fid)
 		__log_rem_logid(dblp, fid);
 
 ret1:	UNLOCK_LOGREGION(dblp);
-
 	return (ret);
 }
diff --git a/db2/makedb.c b/db2/makedb.c
index 6c9d0a1234..d7821036f8 100644
--- a/db2/makedb.c
+++ b/db2/makedb.c
@@ -233,7 +233,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1996, 1997");
+"), "1996, 1997, 1998");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
@@ -303,7 +303,7 @@ process_input (input, inname, output, to_lowercase, be_quiet)
 	++cp;
 
       val.data = cp;
-      val.size = &line[n] - cp;
+      val.size = (&line[n] - cp) + 1;
 
       /* Store the value.  */
       status = output->put (output, &key, &val, R_NOOVERWRITE);
@@ -349,7 +349,7 @@ print_database (db)
   no_more = db->seq (db, &key, &val, R_FIRST);
   while (!no_more)
     {
-      printf ("%.*s %.*s\n", (int) key.size, (char *) key.data, (int) val.size,
+      printf ("%.*s %s\n", (int) key.size, (char *) key.data,
 	      (char *) val.data);
 
       no_more = db->seq (db, &key, &val, R_NEXT);
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
index 578abedcb6..c23abdda24 100644
--- a/db2/mp/mp_bh.c
+++ b/db2/mp/mp_bh.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_bh.c	10.23 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_bh.c	10.28 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -193,30 +193,28 @@ __memp_pgread(dbmfp, bhp, can_create)
 	/* Call any pgin function. */
 pgin:	ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1);
 
-	/* Reacquire the region lock. */
+	/* Unlock the buffer and reacquire the region lock. */
+err:	UNLOCKBUFFER(dbmp, bhp);
 	LOCKREGION(dbmp);
 
-	/* If the pgin function succeeded, the data is now valid. */
-	if (ret == 0)
+	/*
+	 * If no errors occurred, the data is now valid, clear the BH_TRASH
+	 * flag; regardless, clear the lock bit and let other threads proceed.
+	 */
+	F_CLR(bhp, BH_LOCKED);
+	if (ret == 0) {
 		F_CLR(bhp, BH_TRASH);
 
-	/* Update the statistics. */
-	if (can_create) {
-		++dbmp->mp->stat.st_page_create;
-		++mfp->stat.st_page_create;
-	} else {
-		++dbmp->mp->stat.st_page_in;
-		++mfp->stat.st_page_in;
-	}
-
-	if (0) {
-err:		LOCKREGION(dbmp);
+		/* Update the statistics. */
+		if (can_create) {
+			++dbmp->mp->stat.st_page_create;
+			++mfp->stat.st_page_create;
+		} else {
+			++dbmp->mp->stat.st_page_in;
+			++mfp->stat.st_page_in;
+		}
 	}
 
-	/* Release the buffer. */
-	F_CLR(bhp, BH_LOCKED);
-	UNLOCKBUFFER(dbmp, bhp);
-
 	return (ret);
 }
 
@@ -240,7 +238,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	MPOOLFILE *mfp;
 	size_t pagesize;
 	ssize_t nw;
-	int callpgin, ret;
+	int callpgin, ret, syncfail;
 	const char *fail;
 
 	dbmp = dbmfp->dbmp;
@@ -255,8 +253,32 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	callpgin = 0;
 	pagesize = mfp->stat.st_pagesize;
 
-	F_SET(bhp, BH_LOCKED);
+	/*
+	 * Check the dirty bit -- this buffer may have been written since we
+	 * decided to write it.
+	 */
+	if (!F_ISSET(bhp, BH_DIRTY)) {
+		if (wrotep != NULL)
+			*wrotep = 1;
+		return (0);
+	}
+
 	LOCKBUFFER(dbmp, bhp);
+
+	/*
+	 * If there were two writers, we may have just been waiting while the
+	 * other writer completed I/O on this buffer.  Check the dirty bit one
+	 * more time.
+	 */
+	if (!F_ISSET(bhp, BH_DIRTY)) {
+		UNLOCKBUFFER(dbmp, bhp);
+
+		if (wrotep != NULL)
+			*wrotep = 1;
+		return (0);
+	}
+
+	F_SET(bhp, BH_LOCKED);
 	UNLOCKREGION(dbmp);
 
 	if (restartp != NULL)
@@ -272,8 +294,9 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 		goto err;
 
 	/*
-	 * Call any pgout function.  We set the callpgin flag so that on
-	 * error we flag that the contents of the buffer may be trash.
+	 * Call any pgout function.  We set the callpgin flag so that we flag
+	 * that the contents of the buffer will need to be passed through pgin
+	 * before they are reused.
 	 */
 	if (mfp->ftype == 0)
 		ret = 0;
@@ -307,7 +330,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 		 * between the failing clauses to __db_lseek and __db_write and
 		 * this ret != 0.
 		 */
-		fail = NULL;
+		COMPQUIET(fail, NULL);
 		goto syserr;
 	}
 
@@ -320,18 +343,20 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	if (wrotep != NULL)
 		*wrotep = 1;
 
-	/* Reacquire the region lock. */
+	/* Unlock the buffer and reacquire the region lock. */
+	UNLOCKBUFFER(dbmp, bhp);
 	LOCKREGION(dbmp);
 
-	/* Clean up the flags based on a successful write. */
-	F_SET(bhp, BH_CALLPGIN);
+	/*
+	 * Clean up the flags based on a successful write.
+	 *
+	 * If we rewrote the page, it will need processing by the pgin
+	 * routine before reuse.
+	 */
+	if (callpgin)
+		F_SET(bhp, BH_CALLPGIN);
 	F_CLR(bhp, BH_DIRTY | BH_LOCKED);
 
-	++mp->stat.st_page_clean;
-	--mp->stat.st_page_dirty;
-
-	UNLOCKBUFFER(dbmp, bhp);
-
 	/*
 	 * If we write a buffer for which a checkpoint is waiting, update
 	 * the count of pending buffers (both in the mpool as a whole and
@@ -344,23 +369,36 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	 *
 	 * XXX:
 	 * We ignore errors from the sync -- it makes no sense to return an
-	 * error to the calling process, so set a flag causing the sync to
-	 * be retried later.
-	 *
-	 * If the buffer we wrote has a LSN larger than the current largest
-	 * we've written for this checkpoint, update the saved value.
+	 * error to the calling process, so set a flag causing the checkpoint
+	 * to be retried later.
 	 */
 	if (F_ISSET(bhp, BH_WRITE)) {
+		if (mfp->lsn_cnt == 1) {
+			UNLOCKREGION(dbmp);
+			syncfail = __db_fsync(dbmfp->fd) != 0;
+			LOCKREGION(dbmp);
+			if (syncfail)
+				F_SET(mp, MP_LSN_RETRY);
+
+		}
+
+		F_CLR(bhp, BH_WRITE);
+
+		/*
+		 * If the buffer just written has a larger LSN than the current
+		 * max LSN written for this checkpoint, update the saved value.
+		 */
 		if (log_compare(&lsn, &mp->lsn) > 0)
 			mp->lsn = lsn;
-		F_CLR(bhp, BH_WRITE);
 
 		--mp->lsn_cnt;
-
-		if (--mfp->lsn_cnt == 0 && __db_fsync(dbmfp->fd) != 0)
-			F_SET(mp, MP_LSN_RETRY);
+		--mfp->lsn_cnt;
 	}
 
+	/* Update the page clean/dirty statistics. */
+	++mp->stat.st_page_clean;
+	--mp->stat.st_page_dirty;
+
 	/* Update I/O statistics. */
 	++mp->stat.st_page_out;
 	++mfp->stat.st_page_out;
@@ -370,11 +408,20 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 syserr:	__db_err(dbenv, "%s: %s failed for page %lu",
 	    __memp_fn(dbmfp), fail, (u_long)bhp->pgno);
 
-err:	UNLOCKBUFFER(dbmp, bhp);
+err:	/* Unlock the buffer and reacquire the region lock. */
+	UNLOCKBUFFER(dbmp, bhp);
 	LOCKREGION(dbmp);
+
+	/*
+	 * Clean up the flags based on a failure.
+	 *
+	 * The page remains dirty but we remove our lock.  If we rewrote the
+	 * page, it will need processing by the pgin routine before reuse.
+	 */
 	if (callpgin)
 		F_SET(bhp, BH_CALLPGIN);
 	F_CLR(bhp, BH_LOCKED);
+
 	return (ret);
 }
 
diff --git a/db2/mp/mp_fget.c b/db2/mp/mp_fget.c
index 1010751c92..f5955c4c6f 100644
--- a/db2/mp/mp_fget.c
+++ b/db2/mp/mp_fget.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fget.c	10.32 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_fget.c	10.33 (Sleepycat) 12/2/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -272,8 +272,17 @@ found:		/* Increment the reference count. */
 		 * discarded we know the buffer can't move and its contents
 		 * can't change.
 		 */
-		if (F_ISSET(bhp, BH_LOCKED)) {
+		for (cnt = 0; F_ISSET(bhp, BH_LOCKED); ++cnt) {
 			UNLOCKREGION(dbmp);
+
+			/*
+			 * Sleep so that we don't simply spin, switching locks.
+			 * (See the comment in include/mp.h.)
+			 */
+			if (cnt != 0 &&
+			    (__db_yield == NULL || __db_yield() != 0))
+				__db_sleep(0, 1);
+
 			LOCKBUFFER(dbmp, bhp);
 			/* Waiting for I/O to finish... */
 			UNLOCKBUFFER(dbmp, bhp);
diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c
index bdc4713863..0f41122373 100644
--- a/db2/mp/mp_fopen.c
+++ b/db2/mp/mp_fopen.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fopen.c	10.32 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_fopen.c	10.37 (Sleepycat) 1/18/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -28,8 +28,8 @@ static const char sccsid[] = "@(#)mp_fopen.c	10.32 (Sleepycat) 11/26/97";
 #include "common_ext.h"
 
 static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *));
-static int __memp_mf_open __P((DB_MPOOL *, DB_MPOOLFILE *,
-    const char *, int, size_t, off_t, int, DBT *, u_int8_t *, MPOOLFILE **));
+static int __memp_mf_open __P((DB_MPOOL *, const char *,
+    int, size_t, db_pgno_t, int, DBT *, u_int8_t *, MPOOLFILE **));
 
 /*
  * memp_fopen --
@@ -84,7 +84,9 @@ __memp_fopen(dbmp, mfp, path,
 {
 	DB_ENV *dbenv;
 	DB_MPOOLFILE *dbmfp;
-	off_t size;
+	db_pgno_t last_pgno;
+	size_t size;
+	u_int32_t mbytes, bytes;
 	int ret;
 	u_int8_t idbuf[DB_FILE_ID_LEN];
 	char *rpath;
@@ -120,6 +122,7 @@ __memp_fopen(dbmp, mfp, path,
 			goto err;
 		}
 		size = 0;
+		last_pgno = 0;
 	} else {
 		/* Get the real name for this file and open it. */
 		if ((ret = __db_appname(dbenv,
@@ -133,17 +136,20 @@ __memp_fopen(dbmp, mfp, path,
 		}
 
 		/* Don't permit files that aren't a multiple of the pagesize. */
-		if ((ret = __db_ioinfo(rpath, dbmfp->fd, &size, NULL)) != 0) {
+		if ((ret = __db_ioinfo(rpath,
+		    dbmfp->fd, &mbytes, &bytes, NULL)) != 0) {
 			__db_err(dbenv, "%s: %s", rpath, strerror(ret));
 			goto err;
 		}
-		if (size % pagesize) {
+		if (bytes % pagesize) {
 			__db_err(dbenv,
 			    "%s: file size not a multiple of the pagesize",
 			    rpath);
 			ret = EINVAL;
 			goto err;
 		}
+		size = mbytes * MEGABYTE + bytes;
+		last_pgno = size == 0 ? 0 : (size - 1) / pagesize;
 
 		/*
 		 * Get the file id if we weren't given one.  Generated file id's
@@ -155,6 +161,7 @@ __memp_fopen(dbmp, mfp, path,
 				goto err;
 			fileid = idbuf;
 		}
+		FREES(rpath);
 	}
 
 	/*
@@ -166,8 +173,8 @@ __memp_fopen(dbmp, mfp, path,
 		LOCKREGION(dbmp);
 
 	if (mfp == NULL)
-		ret = __memp_mf_open(dbmp, dbmfp, path,
-		    ftype, pagesize, size, lsn_offset, pgcookie, fileid, &mfp);
+		ret = __memp_mf_open(dbmp, path, ftype,
+		    pagesize, last_pgno, lsn_offset, pgcookie, fileid, &mfp);
 	else {
 		++mfp->ref;
 		ret = 0;
@@ -216,7 +223,7 @@ __memp_fopen(dbmp, mfp, path,
 		if (LF_ISSET(DB_NOMMAP))
 			F_CLR(mfp, MP_CAN_MMAP);
 		if (size > (dbenv == NULL || dbenv->mp_mmapsize == 0 ?
-		    DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize))
+		    DB_MAXMMAPSIZE : dbenv->mp_mmapsize))
 			F_CLR(mfp, MP_CAN_MMAP);
 	}
 	dbmfp->addr = NULL;
@@ -253,14 +260,13 @@ err:	/*
  *	Open an MPOOLFILE.
  */
 static int
-__memp_mf_open(dbmp, dbmfp, path,
-    ftype, pagesize, size, lsn_offset, pgcookie, fileid, retp)
+__memp_mf_open(dbmp, path,
+    ftype, pagesize, last_pgno, lsn_offset, pgcookie, fileid, retp)
 	DB_MPOOL *dbmp;
-	DB_MPOOLFILE *dbmfp;
 	const char *path;
 	int ftype, lsn_offset;
 	size_t pagesize;
-	off_t size;
+	db_pgno_t last_pgno;
 	DBT *pgcookie;
 	u_int8_t *fileid;
 	MPOOLFILE **retp;
@@ -314,7 +320,7 @@ __memp_mf_open(dbmp, dbmfp, path,
 	 * it away.
 	 */
 	mfp->stat.st_pagesize = pagesize;
-	mfp->last_pgno = size == 0 ? 0 : (size - 1) / mfp->stat.st_pagesize;
+	mfp->last_pgno = last_pgno;
 
 	F_SET(mfp, MP_CAN_MMAP);
 	if (ISTEMPORARY)
diff --git a/db2/mp/mp_fput.c b/db2/mp/mp_fput.c
index 38e86b8ac5..335ee9ff16 100644
--- a/db2/mp/mp_fput.c
+++ b/db2/mp/mp_fput.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fput.c	10.16 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_fput.c	10.17 (Sleepycat) 12/20/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -105,7 +105,7 @@ memp_fput(dbmfp, pgaddr, flags)
 #ifdef DEBUG
 	if (bhp->ref == 0) {
 		__db_err(dbmp->dbenv,
-		    "Internal error: bhp->ref on page %lu went negative.",
+    "Unpinned page returned: reference count on page %lu went negative.",
 		    (u_long)bhp->pgno);
 		abort();
 	}
diff --git a/db2/mp/mp_pr.c b/db2/mp/mp_pr.c
index 6ff1131b6e..13a6c62d35 100644
--- a/db2/mp/mp_pr.c
+++ b/db2/mp/mp_pr.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_pr.c	10.20 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_pr.c	10.21 (Sleepycat) 1/6/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -25,8 +25,6 @@ static const char sccsid[] = "@(#)mp_pr.c	10.20 (Sleepycat) 11/26/97";
 #include "db_shash.h"
 #include "mp.h"
 
-void __memp_debug __P((DB_MPOOL *, FILE *, int));
-
 static void __memp_pbh __P((FILE *, DB_MPOOL *, BH *, int));
 static void __memp_pdbmf __P((FILE *, DB_MPOOLFILE *, int));
 static void __memp_pmf __P((FILE *, MPOOLFILE *, int));
diff --git a/db2/mp/mp_sync.c b/db2/mp/mp_sync.c
index 47a7f2ebca..6d16cf3cd4 100644
--- a/db2/mp/mp_sync.c
+++ b/db2/mp/mp_sync.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_sync.c	10.17 (Sleepycat) 11/26/97";
+static const char sccsid[] = "@(#)mp_sync.c	10.19 (Sleepycat) 12/3/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -39,7 +39,7 @@ memp_sync(dbmp, lsnp)
 	DB_ENV *dbenv;
 	MPOOL *mp;
 	MPOOLFILE *mfp;
-	int ar_cnt, cnt, nalloc, next, notused, ret, wrote;
+	int ar_cnt, cnt, nalloc, next, ret, wrote;
 
 	dbenv = dbmp->dbenv;
 
@@ -180,32 +180,28 @@ memp_sync(dbmp, lsnp)
 
 		/* Write the buffer. */
 		mfp = R_ADDR(dbmp, bharray[next]->mf_offset);
-		ret =
-		    __memp_bhwrite(dbmp, mfp, bharray[next], &notused, &wrote);
+		ret = __memp_bhwrite(dbmp, mfp, bharray[next], NULL, &wrote);
 
 		/* Release the buffer. */
 		--bharray[next]->ref;
 
 		/* If there's an error, release the rest of the buffers. */
 		if (ret != 0 || !wrote) {
-			while (++next < ar_cnt)
-				--bharray[next]->ref;
-
-			if (ret != 0)
-				goto err;
-
 			/*
 			 * Any process syncing the shared memory buffer pool
 			 * had better be able to write to any underlying file.
 			 * Be understanding, but firm, on this point.
 			 */
-			if (!wrote) {
+			if (ret == 0) {
 				__db_err(dbenv, "%s: unable to flush page: %lu",
 				    __memp_fns(dbmp, mfp),
 				    (u_long)bharray[next]->pgno);
 				ret = EPERM;
-				goto err;
 			}
+
+			while (++next < ar_cnt)
+				--bharray[next]->ref;
+			goto err;
 		}
 	}
 	ret = mp->lsn_cnt ? DB_INCOMPLETE : 0;
@@ -242,7 +238,7 @@ memp_fsync(dbmfp)
 	BH *bhp, **bharray;
 	DB_MPOOL *dbmp;
 	size_t mf_offset;
-	int ar_cnt, cnt, nalloc, next, pincnt, notused, ret, wrote;
+	int ar_cnt, cnt, nalloc, next, pincnt, ret, wrote;
 
 	dbmp = dbmfp->dbmp;
 
@@ -333,7 +329,7 @@ memp_fsync(dbmfp)
 		}
 
 		/* Write the buffer. */
-		ret = __memp_pgwrite(dbmfp, bharray[next], &notused, &wrote);
+		ret = __memp_pgwrite(dbmfp, bharray[next], NULL, &wrote);
 
 		/* Release the buffer. */
 		--bharray[next]->ref;
@@ -379,7 +375,7 @@ memp_trickle(dbmp, pct, nwrotep)
 	MPOOL *mp;
 	MPOOLFILE *mfp;
 	u_long total;
-	int notused, ret, wrote;
+	int ret, wrote;
 
 	mp = dbmp->mp;
 	if (nwrotep != NULL)
@@ -423,8 +419,7 @@ loop:	total = mp->stat.st_page_clean + mp->stat.st_page_dirty;
 		if (F_ISSET(mfp, MP_TEMP))
 			continue;
 
-		if ((ret =
-		    __memp_bhwrite(dbmp, mfp, bhp, &notused, &wrote)) != 0)
+		if ((ret = __memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0)
 			goto err;
 
 		/*
diff --git a/db2/mutex/mutex.c b/db2/mutex/mutex.c
index 6e87c5f215..6dca323113 100644
--- a/db2/mutex/mutex.c
+++ b/db2/mutex/mutex.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mutex.c	10.29 (Sleepycat) 11/25/97";
+static const char sccsid[] = "@(#)mutex.c	10.32 (Sleepycat) 1/16/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -105,12 +105,12 @@ static const char sccsid[] = "@(#)mutex.c	10.29 (Sleepycat) 11/25/97";
  * __db_mutex_init --
  *	Initialize a DB mutex structure.
  *
- * PUBLIC: void __db_mutex_init __P((db_mutex_t *, off_t));
+ * PUBLIC: void __db_mutex_init __P((db_mutex_t *, u_int32_t));
  */
 void
 __db_mutex_init(mp, off)
 	db_mutex_t *mp;
-	off_t off;
+	u_int32_t off;
 {
 #ifdef DEBUG
 	if ((ALIGNTYPE)mp & (MUTEX_ALIGNMENT - 1)) {
@@ -123,6 +123,8 @@ __db_mutex_init(mp, off)
 	memset(mp, 0, sizeof(db_mutex_t));
 
 #ifdef HAVE_SPINLOCKS
+	COMPQUIET(off, 0);
+
 	TSL_INIT(&mp->tsl_resource);
 	mp->spins = __os_spin();
 #else
@@ -149,6 +151,8 @@ __db_mutex_lock(mp, fd)
 #ifdef HAVE_SPINLOCKS
 	int nspins;
 
+	COMPQUIET(fd, 0);
+
 	for (usecs = MS(10);;) {
 		/* Try and acquire the uncontested resource lock for N spins. */
 		for (nspins = mp->spins; nspins > 0; --nspins)
@@ -202,7 +206,7 @@ __db_mutex_lock(mp, fd)
 		/* Acquire an exclusive kernel lock. */
 		k_lock.l_type = F_WRLCK;
 		if (fcntl(fd, F_SETLKW, &k_lock))
-			return (1);
+			return (errno);
 
 		/* If the resource tsl is still available, it's ours. */
 		if (mp->pid == 0) {
@@ -213,7 +217,7 @@ __db_mutex_lock(mp, fd)
 		/* Release the kernel lock. */
 		k_lock.l_type = F_UNLCK;
 		if (fcntl(fd, F_SETLK, &k_lock))
-			return (1);
+			return (errno);
 
 		/*
 		 * If we got the resource tsl we're done.
@@ -251,6 +255,8 @@ __db_mutex_unlock(mp, fd)
 #endif
 
 #ifdef HAVE_SPINLOCKS
+	COMPQUIET(fd, 0);
+
 #ifdef DEBUG
 	mp->pid = 0;
 #endif
diff --git a/db2/os/os_alloc.c b/db2/os/os_alloc.c
new file mode 100644
index 0000000000..27abffbf0d
--- /dev/null
+++ b/db2/os/os_alloc.c
@@ -0,0 +1,75 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997
+ *	Sleepycat Software.  All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)os_alloc.c	10.1 (Sleepycat) 12/1/97";
+#endif /* not lint */
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+
+/*
+ * XXX
+ * Correct for systems that return NULL when you allocate 0 bytes of memory.
+ * There are several places in DB where we allocate the number of bytes held
+ * by the key/data item, and it can be 0.  Correct here so that malloc never
+ * returns a NULL for that reason (which behavior is permitted by ANSI).  We
+ * could make these calls macros on non-Alpha architectures (that's where we
+ * saw the problem), but it's probably not worth the autoconf complexity.
+ */
+/*
+ * __db_calloc --
+ *	The calloc(3) function for DB.
+ *
+ * PUBLIC: void *__db_calloc __P((size_t, size_t));
+ */
+void *
+__db_calloc(num, size)
+	size_t num, size;
+{
+	void *p;
+
+	size *= num;
+	if ((p = __db_jump.db_malloc(size == 0 ? 1 : size)) != NULL)
+		memset(p, 0, size);
+	return (p);
+}
+
+/*
+ * __db_malloc --
+ *	The malloc(3) function for DB.
+ *
+ * PUBLIC: void *__db_malloc __P((size_t));
+ */
+void *
+__db_malloc(size)
+	size_t size;
+{
+	return (__db_jump.db_malloc(size == 0 ? 1 : size));
+}
+
+/*
+ * __db_realloc --
+ *	The realloc(3) function for DB.
+ *
+ * PUBLIC: void *__db_realloc __P((void *, size_t));
+ */
+void *
+__db_realloc(ptr, size)
+	void *ptr;
+	size_t size;
+{
+	return (__db_jump.db_realloc(ptr, size == 0 ? 1 : size));
+}
diff --git a/db2/os/os_config.c b/db2/os/os_config.c
index ecb4f1c2e7..7a89ba58ab 100644
--- a/db2/os/os_config.c
+++ b/db2/os/os_config.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_config.c	10.9 (Sleepycat) 11/28/97";
+static const char sccsid[] = "@(#)os_config.c	10.12 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -20,6 +20,22 @@ static const char sccsid[] = "@(#)os_config.c	10.9 (Sleepycat) 11/28/97";
 #include "db_int.h"
 
 /*
+ * __os_oldwin --
+ *	Return if Windows 95 (as opposed to Windows NT).
+ *
+ * PUBLIC: int __os_oldwin __P((void));
+ */
+int
+__os_oldwin()
+{
+#ifdef _WIN32
+	return ((GetVersion() & 0x80000000) != 0);
+#else
+	return (0);
+#endif
+}
+
+/*
  * XXX
  * We provide our own extern declarations so that we don't collide with
  * systems that get them wrong, e.g., SunOS.
@@ -41,7 +57,6 @@ imported extern char	*strdup __P((const char *));
 imported extern void    *realloc __P((void *, size_t));
 imported extern int	 unlink __P((const char *));
 imported extern ssize_t	 write __P((int, const void *, size_t));
-imported extern void	*memset __P((void *, int, size_t));
 
 /*
  * __db_jump --
@@ -110,8 +125,8 @@ db_jump_set(func, which)
 		__db_jump.db_fsync = (int (*) __P((int)))func;
 		break;
 	case DB_FUNC_IOINFO:
-		__db_jump.db_ioinfo =
-		    (int (*) __P((const char *, int, off_t *, off_t *)))func;
+		__db_jump.db_ioinfo = (int (*) __P((const char *,
+		    int, u_int32_t *, u_int32_t *, u_int32_t *)))func;
 		break;
 	case DB_FUNC_MALLOC:
 		__db_jump.db_malloc = (void *(*) __P((size_t)))func;
@@ -178,55 +193,3 @@ db_value_set(value, which)
 	}
 	return (0);
 }
-
-/*
- * XXX
- * Correct for systems that return NULL when you allocate 0 bytes of memory.
- * There are several places in DB where we allocate the number of bytes held
- * by the key/data item, and it can be 0.  Correct here so that malloc never
- * returns a NULL for that reason.
- */
-/*
- * __db_calloc --
- *	The calloc(3) function for DB.
- *
- * PUBLIC: void *__db_calloc __P((size_t, size_t));
- */
-void *
-__db_calloc(num, size)
-	size_t num, size;
-{
-	void *p;
-
-	size *= num;
-	if ((p = __db_jump.db_malloc(size == 0 ? 1 : size)) != NULL)
-		memset(p, 0, size);
-	return (p);
-}
-
-/*
- * __db_malloc --
- *	The malloc(3) function for DB.
- *
- * PUBLIC: void *__db_malloc __P((size_t));
- */
-void *
-__db_malloc(size)
-	size_t size;
-{
-	return (__db_jump.db_malloc(size == 0 ? 1 : size));
-}
-
-/*
- * __db_realloc --
- *	The realloc(3) function for DB.
- *
- * PUBLIC: void *__db_realloc __P((void *, size_t));
- */
-void *
-__db_realloc(ptr, size)
-	void *ptr;
-	size_t size;
-{
-	return (__db_jump.db_realloc(ptr, size == 0 ? 1 : size));
-}
diff --git a/db2/os/os_stat.c b/db2/os/os_stat.c
index ee84ab0588..73600b6336 100644
--- a/db2/os/os_stat.c
+++ b/db2/os/os_stat.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_stat.c	10.8 (Sleepycat) 10/25/97";
+static const char sccsid[] = "@(#)os_stat.c	10.11 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -47,34 +47,35 @@ __os_exists(path, isdirp)
  *	Return file size and I/O size; abstracted to make it easier
  *	to replace.
  *
- * PUBLIC: int __os_ioinfo __P((const char *, int, off_t *, off_t *));
+ * PUBLIC: int __os_ioinfo
+ * PUBLIC:    __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *));
  */
 int
-__os_ioinfo(path, fd, sizep, iop)
+__os_ioinfo(path, fd, mbytesp, bytesp, iosizep)
 	const char *path;
 	int fd;
-	off_t *sizep, *iop;
+	u_int32_t *mbytesp, *bytesp, *iosizep;
 {
 	struct stat sb;
 
+	COMPQUIET(path, NULL);
+
 	if (fstat(fd, &sb) == -1)
 		return (errno);
 
 	/* Return the size of the file. */
-	if (sizep != NULL)
-		*sizep = sb.st_size;
+	if (mbytesp != NULL)
+		*mbytesp = sb.st_size / MEGABYTE;
+	if (bytesp != NULL)
+		*bytesp = sb.st_size % MEGABYTE;
 
-	/*
-	 * Return the underlying filesystem blocksize, if available.  Default
-	 * to 8K on the grounds that most OS's use less than 8K as their VM
-	 * page size.
-	 */
+	/* Return the underlying filesystem blocksize, if available. */
 #ifdef HAVE_ST_BLKSIZE
-	if (iop != NULL)
-		*iop = sb.st_blksize;
+	if (iosizep != NULL)
+		*iosizep = sb.st_blksize;
 #else
-	if (iop != NULL)
-		*iop = 8 * 1024;
+	if (iosizep != NULL)
+		*iosizep = DB_DEF_IOSIZE;
 #endif
 	return (0);
 }
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
index b2a692bba9..3157a52666 100644
--- a/db2/progs/db_checkpoint/db_checkpoint.c
+++ b/db2/progs/db_checkpoint/db_checkpoint.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_checkpoint.c	10.12 (Sleepycat) 9/4/97";
+static const char sccsid[] = "@(#)db_checkpoint.c	10.14 (Sleepycat) 1/17/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -46,7 +46,6 @@ void	 siginit __P((void));
 void	 usage __P((void));
 
 int	 interrupted;
-time_t	 now;					/* Checkpoint time. */
 const char
 	*progname = "db_checkpoint";		/* Program name. */
 
@@ -203,7 +202,7 @@ logpid(fname, is_open)
 		}
 		(void)time(&now);
 		fprintf(fp,
-		    "%s: %lu %s", progname, (u_long)getpid(), ctime(&now));
+		    "%.24s: %lu %s", progname, (u_long)getpid(), ctime(&now));
 		fclose(fp);
 	} else
 		(void)remove(fname);
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
index 473e5b9cb2..97fa8ca4f6 100644
--- a/db2/progs/db_deadlock/db_deadlock.c
+++ b/db2/progs/db_deadlock/db_deadlock.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_deadlock.c	10.16 (Sleepycat) 10/14/97";
+static const char sccsid[] = "@(#)db_deadlock.c	10.17 (Sleepycat) 1/15/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -192,7 +192,7 @@ logpid(fname, is_open)
 		}
 		(void)time(&now);
 		fprintf(fp,
-		    "%s: %lu %s", progname, (u_long)getpid(), ctime(&now));
+		    "%.24s: %lu %s", progname, (u_long)getpid(), ctime(&now));
 		fclose(fp);
 	} else
 		(void)remove(fname);
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
index 6597f10e10..afa5730c25 100644
--- a/db2/progs/db_load/db_load.c
+++ b/db2/progs/db_load/db_load.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_load.c	10.14 (Sleepycat) 10/19/97";
+static const char sccsid[] = "@(#)db_load.c	10.15 (Sleepycat) 12/29/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -51,11 +51,11 @@ main(argc, argv)
 	extern int optind;
 	DB *dbp;
 	DBT key, data;
-	DBTYPE argtype, headertype;
+	DBTYPE argtype, dbtype;
 	DB_ENV *dbenv;
 	DB_INFO dbinfo;
 	db_recno_t recno;
-	int ch, pflag;
+	int ch, no_header, pflag;
 	char **clist, **clp, *home;
 
 	/* Allocate enough room for configuration arguments. */
@@ -63,8 +63,9 @@ main(argc, argv)
 		err(1, NULL);
 
 	home = NULL;
-	argtype = DB_UNKNOWN;
-	while ((ch = getopt(argc, argv, "c:f:h:t:")) != EOF)
+	no_header = 0;
+	argtype = dbtype = DB_UNKNOWN;
+	while ((ch = getopt(argc, argv, "c:f:h:Tt:")) != EOF)
 		switch (ch) {
 		case 'c':
 			*clp++ = optarg;
@@ -76,6 +77,9 @@ main(argc, argv)
 		case 'h':
 			home = optarg;
 			break;
+		case 'T':
+			no_header = pflag = 1;
+			break;
 		case 't':
 			if (strcmp(optarg, "btree") == 0) {
 				argtype = DB_BTREE;
@@ -85,6 +89,10 @@ main(argc, argv)
 				argtype = DB_HASH;
 				break;
 			}
+			if (strcmp(optarg, "recno") == 0) {
+				argtype = DB_RECNO;
+				break;
+			}
 			usage();
 			/* NOTREACHED */
 		case '?':
@@ -101,21 +109,31 @@ main(argc, argv)
 	dbenv = db_init(home);
 	memset(&dbinfo, 0, sizeof(DB_INFO));
 
-	/* Read the header. */
-	rheader(&headertype, &pflag, &dbinfo);
+	/*
+	 * Read the header.  If there isn't any header, we're expecting flat
+	 * text, set the pflag appropriately.
+	 */
+	if (no_header)
+		dbtype = argtype;
+	else {
+		rheader(&dbtype, &pflag, &dbinfo);
+		if (argtype != DB_UNKNOWN) {
+			/* Conversion to/from recno is prohibited. */
+			if ((dbtype == DB_RECNO && argtype != DB_RECNO) ||
+			    (argtype == DB_RECNO && dbtype != DB_RECNO))
+				errx(1,
+			    "databases of type recno may not be converted");
+			dbtype = argtype;
+		}
+	}
+	if (dbtype == DB_UNKNOWN)
+		errx(1, "no database type specified");
 
 	/* Apply command-line configuration changes. */
 	configure(&dbinfo, clist);
 
-	/* Conversion to/from recno is prohibited. */
-	if (argtype != DB_UNKNOWN) {
-		if (headertype == DB_RECNO)
-			errx(1, "databases of type recno may not be converted");
-		headertype = argtype;
-	}
-
 	/* Open the DB file. */
-	if ((errno = db_open(argv[0], headertype, DB_CREATE | DB_TRUNCATE,
+	if ((errno = db_open(argv[0], dbtype, DB_CREATE | DB_TRUNCATE,
 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
 	    dbenv, &dbinfo, &dbp)) != 0)
 		err(1, "%s", argv[0]);
@@ -133,7 +151,7 @@ main(argc, argv)
 	}
 
 	/* Get each key/data pair and add them to the database. */
-	if (headertype == DB_RECNO) {
+	if (dbtype == DB_RECNO) {
 		key.data = &recno;
 		key.size = sizeof(recno);
 		for (recno = 1;; ++recno) {
@@ -273,8 +291,11 @@ rheader(dbtypep, pflagp, dbinfop)
 	*pflagp = 0;
 
 	for (lineno = 1;; ++lineno) {
+		/* If we don't see the expected information, it's an error. */
 		if (fscanf(stdin, "%[^=]=%s\n", name, value) != 2)
 			errx(1, "line %lu: unexpected format", lineno);
+
+		/* Check for the end of the header lines. */
 		if (strcmp(name, "HEADER") == 0)
 			break;
 
@@ -455,6 +476,6 @@ void
 usage()
 {
 	(void)fprintf(stderr,
-"usage: db_load [-c name=value] [-f file] [-h home] [-t btree | hash] db_file\n");
+"usage: db_load [-T]\n\t[-c name=value] [-f file] [-h home] [-t btree | hash] db_file\n");
 	exit(1);
 }
diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c
index 6bbd118b1b..24554bcd14 100644
--- a/db2/progs/db_printlog/db_printlog.c
+++ b/db2/progs/db_printlog/db_printlog.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_printlog.c	10.10 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_printlog.c	10.11 (Sleepycat) 1/8/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -150,7 +150,8 @@ void
 onint(signo)
 	int signo;
 {
-	signo = 1;			/* XXX: Shut the compiler up. */
+	COMPQUIET(signo, 0);
+
 	interrupted = 1;
 }
 
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
index 5a39d320f8..f902fed8c0 100644
--- a/db2/progs/db_recover/db_recover.c
+++ b/db2/progs/db_recover/db_recover.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_recover.c	10.16 (Sleepycat) 10/28/97";
+static const char sccsid[] = "@(#)db_recover.c	10.17 (Sleepycat) 1/15/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -73,7 +73,7 @@ main(argc, argv)
 
 	dbenv = db_init(home, flags, verbose);
 	if (verbose) {
-		__db_err(dbenv, "Recovery complete at %s", ctime(&now));
+		__db_err(dbenv, "Recovery complete at %.24s", ctime(&now));
 		__db_err(dbenv, "%s %lu %s [%lu][%lu]",
 		    "Maximum transaction id",
 		    (u_long)dbenv->tx_info->region->last_txnid,
diff --git a/db2/progs/db_stat/db_stat.c b/db2/progs/db_stat/db_stat.c
index b1f1615fa9..5295f011a6 100644
--- a/db2/progs/db_stat/db_stat.c
+++ b/db2/progs/db_stat/db_stat.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_stat.c	8.26 (Sleepycat) 11/2/97";
+static const char sccsid[] = "@(#)db_stat.c	8.30 (Sleepycat) 1/8/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -31,9 +31,6 @@ static const char sccsid[] = "@(#)db_stat.c	8.26 (Sleepycat) 11/2/97";
 
 #undef stat
 
-#define	MB	1048576
-#define	DIVIDER	"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
-
 typedef enum { T_NOTSET, T_DB, T_LOG, T_MPOOL, T_TXN } test_t;
 
 void	btree_stats __P((DB *));
@@ -232,6 +229,8 @@ void
 hash_stats(dbp)
 	DB *dbp;
 {
+	COMPQUIET(dbp, NULL);
+
 	return;
 }
 
@@ -251,8 +250,9 @@ log_stats(dbenv)
 	printf("%#lx\tLog magic number.\n", (u_long)sp->st_magic);
 	printf("%lu\tLog version number.\n", (u_long)sp->st_version);
 	printf("%#o\tLog file mode.\n", sp->st_mode);
-	if (sp->st_lg_max % MB == 0)
-		printf("%luMb\tLog file size.\n", (u_long)sp->st_lg_max / MB);
+	if (sp->st_lg_max % MEGABYTE == 0)
+		printf("%luMb\tLog file size.\n",
+		    (u_long)sp->st_lg_max / MEGABYTE);
 	else if (sp->st_lg_max % 1024 == 0)
 		printf("%luKb\tLog file size.\n", (u_long)sp->st_lg_max / 1024);
 	else
@@ -263,6 +263,8 @@ log_stats(dbenv)
 	    (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes);
 	printf("%lu\tTotal log file writes.\n", (u_long)sp->st_wcount);
 	printf("%lu\tTotal log file flushes.\n", (u_long)sp->st_scount);
+	printf("%lu\tCurrent log file number.\n", (u_long)sp->st_cur_file);
+	printf("%lu\tCurrent log file offset.\n", (u_long)sp->st_cur_offset);
 	printf("%lu\tThe number of region locks granted without waiting.\n",
 	    (u_long)sp->st_region_nowait);
 	printf("%lu\tThe number of region locks granted after waiting.\n",
@@ -325,7 +327,7 @@ mpool_stats(dbenv)
 	    (u_long)gsp->st_region_wait);
 
 	for (; fsp != NULL && *fsp != NULL; ++fsp) {
-		printf("%s\n", DIVIDER);
+		printf("%s\n", DB_LINE);
 		printf("%s\n", (*fsp)->file_name);
 		printf("%lu\tPage size.\n", (u_long)(*fsp)->st_pagesize);
 		printf("%lu\tRequested pages found in the cache",
@@ -513,7 +515,8 @@ void
 onint(signo)
 	int signo;
 {
-	signo = 1;			/* XXX: Shut the compiler up. */
+	COMPQUIET(signo, 0);
+
 	interrupted = 1;
 }
 
diff --git a/db2/txn/txn.c b/db2/txn/txn.c
index e7a1798350..2a2e3da97b 100644
--- a/db2/txn/txn.c
+++ b/db2/txn/txn.c
@@ -43,7 +43,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)txn.c	10.37 (Sleepycat) 11/28/97";
+static const char sccsid[] = "@(#)txn.c	10.39 (Sleepycat) 1/8/98";
 #endif /* not lint */
 
 
@@ -205,7 +205,12 @@ retry1:	if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE,
 		LOCK_TXNREGION(tmgrp);
 		if ((ret = __db_shalloc(tmgrp->mem, sizeof(db_mutex_t),
 		    MUTEX_ALIGNMENT, &tmgrp->mutexp)) == 0)
-			__db_mutex_init(tmgrp->mutexp, -1);
+			/*
+			 * Since we only get here if threading is turned on, we
+			 * know that we have spinlocks, so the offset is going
+			 * to be ignored.  We put 0 here as a valid placeholder.
+			 */
+			__db_mutex_init(tmgrp->mutexp, 0);
 		UNLOCK_TXNREGION(tmgrp);
 		if (ret != 0)
 			goto out;
@@ -735,8 +740,7 @@ __txn_grow_region(tp)
 	DB_TXNMGR *tp;
 {
 	size_t incr;
-	off_t mutex_offset;
-	u_int32_t oldmax;
+	u_int32_t mutex_offset, oldmax;
 	u_int8_t *curaddr;
 	int ret;