summaryrefslogtreecommitdiff
path: root/db/btree
diff options
context:
space:
mode:
Diffstat (limited to 'db/btree')
-rw-r--r--db/btree/bt_compare.c18
-rw-r--r--db/btree/bt_conv.c8
-rw-r--r--db/btree/bt_curadj.c36
-rw-r--r--db/btree/bt_cursor.c292
-rw-r--r--db/btree/bt_delete.c142
-rw-r--r--db/btree/bt_method.c60
-rw-r--r--db/btree/bt_open.c121
-rw-r--r--db/btree/bt_put.c8
-rw-r--r--db/btree/bt_rec.c302
-rw-r--r--db/btree/bt_reclaim.c8
-rw-r--r--db/btree/bt_recno.c68
-rw-r--r--db/btree/bt_rsearch.c58
-rw-r--r--db/btree/bt_search.c101
-rw-r--r--db/btree/bt_split.c75
-rw-r--r--db/btree/bt_stat.c398
-rw-r--r--db/btree/bt_upgrade.c8
-rw-r--r--db/btree/bt_verify.c142
-rw-r--r--db/btree/btree.src31
-rw-r--r--db/btree/btree_auto.c1876
-rw-r--r--db/btree/btree_autop.c514
20 files changed, 2375 insertions, 1891 deletions
diff --git a/db/btree/bt_compare.c b/db/btree/bt_compare.c
index a329d8044..81ffe098b 100644
--- a/db/btree/bt_compare.c
+++ b/db/btree/bt_compare.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_compare.c,v 11.20 2004/02/21 15:54:44 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_compare.c,v 11.18 2003/01/08 04:00:56 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -204,8 +202,12 @@ __bam_defpfx(dbp, a, b)
return (cnt);
/*
- * We know that a->size must be <= b->size, or they wouldn't be
- * in this order.
+ * They match up to the smaller of the two sizes.
+ * Collate the longer after the shorter.
*/
- return (a->size < b->size ? a->size + 1 : a->size);
+ if (a->size < b->size)
+ return (a->size + 1);
+ if (b->size < a->size)
+ return (b->size + 1);
+ return (b->size);
}
diff --git a/db/btree/bt_conv.c b/db/btree/bt_conv.c
index fd80d8a4c..39a9d8253 100644
--- a/db/btree/bt_conv.c
+++ b/db/btree/bt_conv.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_conv.c,v 11.15 2004/01/28 03:35:48 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_conv.c,v 11.14 2003/01/08 04:00:56 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
diff --git a/db/btree/bt_curadj.c b/db/btree/bt_curadj.c
index 3da200c27..477f00b8f 100644
--- a/db/btree/bt_curadj.c
+++ b/db/btree/bt_curadj.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_curadj.c,v 11.37 2004/03/13 14:11:33 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_curadj.c,v 11.34 2003/07/09 02:32:24 margo Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -21,30 +19,6 @@ static const char revid[] = "$Id: bt_curadj.c,v 11.34 2003/07/09 02:32:24 margo
static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t));
-#ifdef DEBUG
-/*
- * __bam_cprint --
- * Display the current internal cursor.
- *
- * PUBLIC: void __bam_cprint __P((DBC *));
- */
-void
-__bam_cprint(dbc)
- DBC *dbc;
-{
- BTREE_CURSOR *cp;
-
- cp = (BTREE_CURSOR *)dbc->internal;
-
- fprintf(stderr, "\tinternal: ovflsize: %lu", (u_long)cp->ovflsize);
- if (dbc->dbtype == DB_RECNO)
- fprintf(stderr, " recno: %lu", (u_long)cp->recno);
- if (F_ISSET(cp, C_DELETED))
- fprintf(stderr, " (deleted)");
- fprintf(stderr, "\n");
-}
-#endif
-
/*
* Cursor adjustments are logged if they are for subtransactions. This is
* because it's possible for a subtransaction to adjust cursors which will
@@ -219,8 +193,8 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
if (found != 0 && DBC_LOGGING(my_dbc)) {
- if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
- &lsn, 0, DB_CA_DI, pgno, 0, 0, adjust, indx, 0)) != 0)
+ if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
+ DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0)
return (ret);
}
diff --git a/db/btree/bt_cursor.c b/db/btree/bt_cursor.c
index 067da53be..82d6cc435 100644
--- a/db/btree/bt_cursor.c
+++ b/db/btree/bt_cursor.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_cursor.c,v 11.190 2004/09/22 21:46:32 ubell Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_cursor.c,v 11.169 2003/11/19 18:41:06 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -53,11 +51,11 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
* don't -- we don't duplicate locks when we duplicate cursors if we are
* running in a transaction environment as there's no point if locks are
* never discarded. This means that the cursor may or may not hold a lock.
- * In the case where we are decending the tree we always want to
- * unlock the held interior page so we use ACQUIRE_COUPLE.
+ * In the case where we are descending the tree we always want to unlock
+ * the held interior page so we use ACQUIRE_COUPLE.
*/
#undef ACQUIRE
-#define ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, ret) { \
+#define ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, ret) do { \
DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \
if ((pagep) != NULL) { \
ret = __memp_fput(__mpf, pagep, 0); \
@@ -68,10 +66,10 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
ret = __db_lget(dbc, LCK_COUPLE, lpgno, mode, 0, &(lock));\
if ((ret) == 0) \
ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \
-}
+} while (0)
#undef ACQUIRE_COUPLE
-#define ACQUIRE_COUPLE(dbc, mode, lpgno, lock, fpgno, pagep, ret) { \
+#define ACQUIRE_COUPLE(dbc, mode, lpgno, lock, fpgno, pagep, ret) do { \
DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \
if ((pagep) != NULL) { \
ret = __memp_fput(__mpf, pagep, 0); \
@@ -83,37 +81,37 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
LCK_COUPLE_ALWAYS, lpgno, mode, 0, &(lock)); \
if ((ret) == 0) \
ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \
-}
+} while (0)
/* Acquire a new page/lock for a cursor. */
#undef ACQUIRE_CUR
-#define ACQUIRE_CUR(dbc, mode, p, ret) { \
+#define ACQUIRE_CUR(dbc, mode, p, ret) do { \
BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \
- if (p != __cp->pgno) \
- __cp->pgno = PGNO_INVALID; \
+ if (p != __cp->pgno) \
+ __cp->pgno = PGNO_INVALID; \
ACQUIRE(dbc, mode, p, __cp->lock, p, __cp->page, ret); \
if ((ret) == 0) { \
__cp->pgno = p; \
__cp->lock_mode = (mode); \
} \
-}
+} while (0)
/*
* Acquire a new page/lock for a cursor and release the previous.
- * This is typically used when decending a tree and we do not
+ * This is typically used when descending a tree and we do not
* want to hold the interior nodes locked.
*/
#undef ACQUIRE_CUR_COUPLE
-#define ACQUIRE_CUR_COUPLE(dbc, mode, p, ret) { \
+#define ACQUIRE_CUR_COUPLE(dbc, mode, p, ret) do { \
BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \
- if (p != __cp->pgno) \
- __cp->pgno = PGNO_INVALID; \
+ if (p != __cp->pgno) \
+ __cp->pgno = PGNO_INVALID; \
ACQUIRE_COUPLE(dbc, mode, p, __cp->lock, p, __cp->page, ret); \
if ((ret) == 0) { \
__cp->pgno = p; \
__cp->lock_mode = (mode); \
} \
-}
+} while (0)
/*
* Acquire a write lock if we don't already have one.
@@ -122,7 +120,7 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
* See ACQUIRE macro on why we handle cursors that don't have locks.
*/
#undef ACQUIRE_WRITE_LOCK
-#define ACQUIRE_WRITE_LOCK(dbc, ret) { \
+#define ACQUIRE_WRITE_LOCK(dbc, ret) do { \
BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \
ret = 0; \
if (STD_LOCKING(dbc) && \
@@ -131,25 +129,27 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
LOCK_ISSET(__cp->lock) ? LCK_COUPLE : 0, \
__cp->pgno, DB_LOCK_WRITE, 0, &__cp->lock)) == 0) \
__cp->lock_mode = DB_LOCK_WRITE; \
-}
+} while (0)
/* Discard the current page/lock for a cursor. */
#undef DISCARD_CUR
-#define DISCARD_CUR(dbc, ret) { \
+#define DISCARD_CUR(dbc, ret) do { \
BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \
DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \
int __t_ret; \
if ((__cp->page) != NULL) { \
- ret = __memp_fput(__mpf, __cp->page, 0); \
+ __t_ret = __memp_fput(__mpf, __cp->page, 0); \
__cp->page = NULL; \
} else \
- ret = 0; \
+ __t_ret = 0; \
+ if (__t_ret != 0 && (ret) == 0) \
+ ret = __t_ret; \
__t_ret = __TLPUT((dbc), __cp->lock); \
if (__t_ret != 0 && (ret) == 0) \
ret = __t_ret; \
if ((ret) == 0 && !LOCK_ISSET(__cp->lock)) \
__cp->lock_mode = DB_LOCK_NG; \
-}
+} while (0)
/* If on-page item is a deleted record. */
#undef IS_DELETED
@@ -308,7 +308,7 @@ __bam_c_close(dbc, root_pgno, rmroot)
DBC *dbc_opd, *dbc_c;
DB_MPOOLFILE *mpf;
PAGE *h;
- int cdb_lock, ret, t_ret;
+ int cdb_lock, ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@@ -426,8 +426,8 @@ __bam_c_close(dbc, root_pgno, rmroot)
case DB_QUEUE:
case DB_UNKNOWN:
default:
- return (__db_unknown_type(dbp->dbenv,
- "__bam_c_close", dbc->dbtype));
+ return (__db_unknown_type(
+ dbp->dbenv, "__bam_c_close", dbc->dbtype));
}
}
goto done;
@@ -448,32 +448,31 @@ lock: cp_c = (BTREE_CURSOR *)dbc_c->internal;
goto err;
cdb_lock = 1;
}
- if ((ret = __memp_fget(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0)
- goto err;
goto delete;
}
/*
* The variable dbc_c has been initialized to reference the cursor in
- * which we're going to do the delete. Initialize the cursor's page
- * and lock structures as necessary.
+ * which we're going to do the delete. Initialize the cursor's lock
+ * structures as necessary.
*
* First, we may not need to acquire any locks. If we're in case #3,
* that is, the primary database isn't a btree database, our caller
* is responsible for acquiring any necessary locks before calling us.
*/
- if (F_ISSET(dbc, DBC_OPD)) {
- if ((ret = __memp_fget(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0)
- goto err;
+ if (F_ISSET(dbc, DBC_OPD))
goto delete;
- }
/*
- * Otherwise, acquire a write lock. If the cursor that did the initial
- * logical deletion (and which had a write lock) is not the same as the
- * cursor doing the physical deletion (which may have only ever had a
- * read lock on the item), we need to upgrade. The confusion comes as
- * follows:
+ * Otherwise, acquire a write lock on the primary database's page.
+ *
+ * Lock the primary database page, regardless of whether we're deleting
+ * an item on a primary database page or an off-page duplicates page.
+ *
+ * If the cursor that did the initial logical deletion (and had a write
+ * lock) is not the same cursor doing the physical deletion (which may
+ * have only ever had a read lock on the item), we need to upgrade to a
+ * write lock. The confusion comes as follows:
*
* C1 created, acquires item read lock
* C2 dup C1, create C2, also has item read lock.
@@ -483,29 +482,37 @@ lock: cp_c = (BTREE_CURSOR *)dbc_c->internal;
*
* If we're in a TXN, we know that C2 will be able to acquire the write
* lock, because no locker other than the one shared by C1 and C2 can
- * acquire a write lock -- the original write lock C1 acquire was never
+ * acquire a write lock -- the original write lock C1 acquired was never
* discarded.
*
* If we're not in a TXN, it's nastier. Other cursors might acquire
* read locks on the item after C1 closed, discarding its write lock,
* and such locks would prevent C2 from acquiring a read lock. That's
- * OK, though, we'll simply wait until we can acquire a read lock, or
+ * OK, though, we'll simply wait until we can acquire a write lock, or
* we'll deadlock. (Which better not happen, since we're not in a TXN.)
*
- * Lock the primary database page, regardless of whether we're deleting
- * an item on a primary database page or an off-page duplicates page.
+ * There are similar scenarios with dirty reads, where the cursor may
+ * have downgraded its write lock to a was-write lock.
*/
- ACQUIRE(dbc, DB_LOCK_WRITE,
- cp->pgno, cp_c->lock, cp_c->pgno, cp_c->page, ret);
- if (ret != 0)
- goto err;
+ if (STD_LOCKING(dbc))
+ if ((ret = __db_lget(dbc,
+ LCK_COUPLE, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0)
+ goto err;
delete: /*
- * If the delete occurred in a btree, delete the on-page physical item
- * referenced by the cursor.
+ * If the delete occurred in a Btree, we're going to look at the page
+ * to see if the item has to be physically deleted. Otherwise, we do
+ * not need the actual page (and it may not even exist, it might have
+ * been truncated from the file after an allocation aborted).
+ *
+ * Delete the on-page physical item referenced by the cursor.
*/
- if (dbc_c->dbtype == DB_BTREE && (ret = __bam_c_physdel(dbc_c)) != 0)
- goto err;
+ if (dbc_c->dbtype == DB_BTREE) {
+ if ((ret = __memp_fget(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0)
+ goto err;
+ if ((ret = __bam_c_physdel(dbc_c)) != 0)
+ goto err;
+ }
/*
* If we're not working in an off-page duplicate tree, then we're
@@ -526,6 +533,9 @@ delete: /*
if ((ret = __memp_fget(mpf, &root_pgno, 0, &h)) != 0)
goto err;
if (NUM_ENT(h) == 0) {
+ DISCARD_CUR(dbc_c, ret);
+ if (ret != 0)
+ goto err;
if ((ret = __db_free(dbc, h)) != 0)
goto err;
} else {
@@ -558,14 +568,9 @@ done: /*
* Discard the page references and locks, and confirm that the stack
* has been emptied.
*/
- if (dbc_opd != NULL) {
- DISCARD_CUR(dbc_opd, t_ret);
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
- }
- DISCARD_CUR(dbc, t_ret);
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
+ if (dbc_opd != NULL)
+ DISCARD_CUR(dbc_opd, ret);
+ DISCARD_CUR(dbc, ret);
/* Downgrade any CDB lock we acquired. */
if (cdb_lock)
@@ -785,11 +790,11 @@ __bam_c_dup(orig_dbc, new_dbc)
* holding inside a transaction because all the locks are retained
* until the transaction commits or aborts.
*/
- if (LOCK_ISSET(orig->lock) && orig_dbc->txn == NULL) {
+ if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock))
if ((ret = __db_lget(new_dbc,
0, new->pgno, new->lock_mode, 0, &new->lock)) != 0)
return (ret);
- }
+
new->ovflsize = orig->ovflsize;
new->recno = orig->recno;
new->flags = orig->flags;
@@ -1064,9 +1069,9 @@ __bam_bulk(dbc, data, flags)
cp = (BTREE_CURSOR *)dbc->internal;
/*
- * dp tracks the beginging of the page in the buffer.
+ * dp tracks the beginning of the page in the buffer.
* np is the next place to copy things into the buffer.
- * dbuf always stays at the beging of the buffer.
+ * dbuf always stays at the beginning of the buffer.
*/
dbuf = data->data;
np = dp = dbuf;
@@ -1172,10 +1177,11 @@ next_pg:
get_key_space:
/* Nothing added, then error. */
if (offp == endp) {
- data->size =
- ALIGN(size +
+ data->size = (u_int32_t)
+ DB_ALIGN(size +
pagesize, 1024);
- return (ENOMEM);
+ return
+ (DB_BUFFER_SMALL);
}
/*
* We need to back up to the
@@ -1246,7 +1252,7 @@ get_key_space:
if ((ret = __bam_bulk_duplicates(dbc, bo->pgno,
dbuf, is_key ? offp + P_INDX : NULL,
&offp, &np, &space, no_dup)) != 0) {
- if (ret == ENOMEM) {
+ if (ret == DB_BUFFER_SMALL) {
size = space;
space = 0;
/* If nothing was added, then error. */
@@ -1307,9 +1313,10 @@ get_space:
if (offp >=
(is_key ? &endp[-1] : endp) ||
F_ISSET(dbc, DBC_TRANSIENT)) {
- data->size = ALIGN(size +
+ data->size = (u_int32_t)
+ DB_ALIGN(size +
data->ulen - space, 1024);
- return (ENOMEM);
+ return (DB_BUFFER_SMALL);
}
break;
}
@@ -1339,8 +1346,8 @@ get_space:
indx += adj;
}
/*
- * Stop when we either run off the page or we
- * move to the next key and we are not returning mulitple keys.
+ * Stop when we either run off the page or we move to the next key and
+ * we are not returning multiple keys.
*/
} while ((indx += adj) < NUM_ENT(pg) &&
(next_key || pg_keyoff == inp[indx]));
@@ -1365,14 +1372,14 @@ get_space:
if (ret == 0 && indx < pg->entries &&
F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) {
data->size = (data->ulen - space) + size;
- return (ENOMEM);
+ return (DB_BUFFER_SMALL);
}
/*
* Must leave the index pointing at the last record fetched.
* If we are not fetching keys, we may have stepped to the
* next key.
*/
- if (ret == ENOMEM || next_key || pg_keyoff == inp[indx])
+ if (ret == DB_BUFFER_SMALL || next_key || pg_keyoff == inp[indx])
cp->indx = indx;
else
cp->indx = indx - P_INDX;
@@ -1462,7 +1469,7 @@ __bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
/*
* np is the next place to put data.
- * dp is the begining of the current page in the buffer.
+ * dp is the beginning of the current page in the buffer.
*/
np = dp = *dpp;
first = 1;
@@ -1489,7 +1496,7 @@ __bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
/* Did space underflow? */
if (space > *spacep) {
- ret = ENOMEM;
+ ret = DB_BUFFER_SMALL;
if (first == 1) {
/* Get the absolute value. */
space = -(int32_t)space;
@@ -1503,7 +1510,7 @@ __bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
bo = (BOVERFLOW *)bk;
size = bo->tlen;
if (size > space) {
- ret = ENOMEM;
+ ret = DB_BUFFER_SMALL;
space = *spacep + size;
break;
}
@@ -1522,7 +1529,7 @@ __bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
dp = np;
size = pagesize - HOFFSET(pg);
if (space < size) {
- ret = ENOMEM;
+ ret = DB_BUFFER_SMALL;
/* Return space required. */
space = *spacep + size;
break;
@@ -1565,7 +1572,7 @@ contin:
* If we ran out of space back up the pointer.
* If we did not return any dups or reached the end, close the opd.
*/
- if (ret == ENOMEM) {
+ if (ret == DB_BUFFER_SMALL) {
if (opd->dbtype == DB_RECNO) {
if (--cp->recno == 0)
goto close_opd;
@@ -1780,6 +1787,7 @@ __bam_c_put(dbc, key, data, flags, pgnop)
u_int32_t flags;
db_pgno_t *pgnop;
{
+ BTREE *t;
BTREE_CURSOR *cp;
DB *dbp;
DBT dbt;
@@ -1796,39 +1804,16 @@ __bam_c_put(dbc, key, data, flags, pgnop)
split: ret = stack = 0;
switch (flags) {
+ case DB_CURRENT:
+ if (F_ISSET(cp, C_DELETED))
+ return (DB_NOTFOUND);
+ /* FALLTHROUGH */
+
case DB_AFTER:
case DB_BEFORE:
- case DB_CURRENT:
iiop = flags;
own = 1;
- /*
- * If the Btree has record numbers (and we're not replacing an
- * existing record), we need a complete stack so that we can
- * adjust the record counts. The check for flags == DB_CURRENT
- * is superfluous but left in for clarity. (If C_RECNUM is set
- * we know that flags must be DB_CURRENT, as DB_AFTER/DB_BEFORE
- * are illegal in a Btree unless it's configured for duplicates
- * and you cannot configure a Btree for both record renumbering
- * and duplicates.)
- */
- if (flags == DB_CURRENT &&
- F_ISSET(cp, C_RECNUM) && F_ISSET(cp, C_DELETED)) {
- if ((ret = __bam_c_getstack(dbc)) != 0)
- goto err;
- /*
- * Initialize the cursor from the stack. Don't take
- * the page number or page index, they should already
- * be set.
- */
- cp->page = cp->csp->page;
- cp->lock = cp->csp->lock;
- cp->lock_mode = cp->csp->lock_mode;
-
- stack = 1;
- break;
- }
-
/* Acquire the current page with a write lock. */
ACQUIRE_WRITE_LOCK(dbc, ret);
if (ret != 0)
@@ -1996,12 +1981,11 @@ split: ret = stack = 0;
/*
* SR [#6059]
- * If we do not own a lock on the page anymore then
- * clear the cursor so we don't point at it.
- * Even if we call __bam_stkrel above we still
- * may have entered the routine with the cursor
- * posistioned to a particular record. This
- * is in the case where C_RECNUM is set.
+ * If we do not own a lock on the page any more, then clear the
+ * cursor so we don't point at it. Even if we call __bam_stkrel
+ * above we still may have entered the routine with the cursor
+ * positioned to a particular record. This is in the case
+ * where C_RECNUM is set.
*/
if (own == 0) {
cp->pgno = PGNO_INVALID;
@@ -2019,6 +2003,33 @@ split: ret = stack = 0;
err:
done: /*
+ * If we inserted a key into the first or last slot of the tree,
+ * remember where it was so we can do it more quickly next time.
+ * If the tree has record numbers, we need a complete stack so
+ * that we can adjust the record counts, so skipping the tree search
+ * isn't possible. For subdatabases we need to be careful that the
+ * page does not move from one db to another, so we track its LSN.
+ *
+ * If there are duplicates and we are inserting into the last slot,
+ * the cursor will point _to_ the last item, not after it, which
+ * is why we subtract P_INDX below.
+ */
+
+ t = dbp->bt_internal;
+ if (ret == 0 && TYPE(cp->page) == P_LBTREE &&
+ (flags == DB_KEYFIRST || flags == DB_KEYLAST) &&
+ !F_ISSET(cp, C_RECNUM) &&
+ (!F_ISSET(dbp, DB_AM_SUBDB) ||
+ (LOGGING_ON(dbp->dbenv) && !F_ISSET(dbp, DB_AM_NOT_DURABLE))) &&
+ ((NEXT_PGNO(cp->page) == PGNO_INVALID &&
+ cp->indx >= NUM_ENT(cp->page) - P_INDX) ||
+ (PREV_PGNO(cp->page) == PGNO_INVALID && cp->indx == 0))) {
+ t->bt_lpgno = cp->pgno;
+ if (F_ISSET(dbp, DB_AM_SUBDB))
+ t->bt_llsn = LSN(cp->page);
+ } else
+ t->bt_lpgno = PGNO_INVALID;
+ /*
* Discard any pages pinned in the tree and their locks, except for
* the leaf page. Note, the leaf page participated in any stack we
* acquired, and so we have to adjust the stack as necessary. If
@@ -2371,7 +2382,7 @@ __bam_c_search(dbc, root_pgno, key, flags, exactp)
db_pgno_t bt_lpgno;
db_recno_t recno;
u_int32_t sflags;
- int cmp, ret;
+ int cmp, ret, t_ret;
dbp = dbc->dbp;
cp = (BTREE_CURSOR *)dbc->internal;
@@ -2415,12 +2426,8 @@ fast_search: /*
* If the application has a history of inserting into the first
* or last pages of the database, we check those pages first to
* avoid doing a full search.
- *
- * If the tree has record numbers, we need a complete stack so
- * that we can adjust the record counts, so fast_search isn't
- * possible.
*/
- if (F_ISSET(cp, C_RECNUM))
+ if (F_ISSET(dbc, DBC_OPD))
goto search;
/*
@@ -2440,14 +2447,24 @@ fast_search: /*
if (bt_lpgno == PGNO_INVALID)
goto search;
- /* Lock and retrieve the page on which we last inserted. */
+ /*
+ * Lock and retrieve the page on which we last inserted.
+ *
+ * The page may not exist: if a transaction created the page
+ * and then aborted, the page might have been truncated from
+ * the end of the file.
+ */
h = NULL;
ACQUIRE_CUR(dbc, DB_LOCK_WRITE, bt_lpgno, ret);
- if (ret != 0)
+ if (ret != 0) {
+ if (ret == DB_PAGE_NOTFOUND)
+ ret = 0;
goto fast_miss;
+ }
h = cp->page;
inp = P_INP(dbp, h);
+
/*
* It's okay if the page type isn't right or it's empty, it
* just means that the world changed.
@@ -2455,6 +2472,10 @@ fast_search: /*
if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0)
goto fast_miss;
+ /* Verify that this page cannot have moved to another db. */
+ if (F_ISSET(dbp, DB_AM_SUBDB) &&
+ log_compare(&t->bt_llsn, &LSN(h)) != 0)
+ goto fast_miss;
/*
* What we do here is test to see if we're at the beginning or
* end of the tree and if the new item sorts before/after the
@@ -2537,10 +2558,13 @@ fast_hit: /* Set the exact match flag, we may have found a duplicate. */
fast_miss: /*
* This was not the right page, so we do not need to retain
* the lock even in the presence of transactions.
+ *
+ * This is also an error path, so ret may have been set.
*/
DISCARD_CUR(dbc, ret);
cp->pgno = PGNO_INVALID;
- (void)__LPUT(dbc, cp->lock);
+ if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0)
+ ret = t_ret;
if (ret != 0)
return (ret);
@@ -2559,20 +2583,6 @@ search: if ((ret = __bam_search(dbc, root_pgno,
cp->lock = cp->csp->lock;
cp->lock_mode = cp->csp->lock_mode;
- /*
- * If we inserted a key into the first or last slot of the tree,
- * remember where it was so we can do it more quickly next time.
- * If there are duplicates and we are inserting into the last slot,
- * the cursor will point _to_ the last item, not after it, which
- * is why we subtract P_INDX below.
- */
- if (TYPE(cp->page) == P_LBTREE &&
- (flags == DB_KEYFIRST || flags == DB_KEYLAST))
- t->bt_lpgno =
- (NEXT_PGNO(cp->page) == PGNO_INVALID &&
- cp->indx >= NUM_ENT(cp->page) - P_INDX) ||
- (PREV_PGNO(cp->page) == PGNO_INVALID &&
- cp->indx == 0) ? cp->pgno : PGNO_INVALID;
return (0);
}
@@ -2661,6 +2671,10 @@ __bam_c_physdel(dbc)
}
if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
return (ret);
+
+ /* Clear the deleted flag, the item is gone. */
+ F_CLR(cp, C_DELETED);
+
if (!empty_page)
if ((ret = __bam_ca_di(dbc, PGNO(cp->page), cp->indx, -1)) != 0)
return (ret);
@@ -2760,6 +2774,8 @@ __bam_c_physdel(dbc)
* stack and page locks without further damage.
*/
if (ret == 0)
+ DISCARD_CUR(dbc, ret);
+ if (ret == 0)
ret = __bam_dpages(dbc, cp->sp);
else
(void)__bam_stkrel(dbc, 0);
diff --git a/db/btree/bt_delete.c b/db/btree/bt_delete.c
index ef6e34caf..018c8ef49 100644
--- a/db/btree/bt_delete.c
+++ b/db/btree/bt_delete.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_delete.c,v 11.49 2004/02/27 12:38:28 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_delete.c,v 11.46 2003/06/30 17:19:29 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -263,7 +261,8 @@ __bam_dpages(dbc, stack_epg)
for (epg = cp->sp; epg < stack_epg; ++epg) {
if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, epg->lock);
+ if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+ ret = t_ret;
}
if (ret != 0)
goto err;
@@ -277,7 +276,7 @@ __bam_dpages(dbc, stack_epg)
* It will deadlock here. Before we unlink the subtree, we relink the
* leaf page chain.
*/
- if ((ret = __db_relink(dbc, DB_REM_PAGE, cp->csp->page, NULL, 1)) != 0)
+ if ((ret = __bam_relink(dbc, cp->csp->page, NULL)) != 0)
goto err;
/*
@@ -296,9 +295,11 @@ __bam_dpages(dbc, stack_epg)
pgno = PGNO(epg->page);
nitems = NUM_ENT(epg->page);
- if ((ret = __memp_fput(mpf, epg->page, 0)) != 0)
+ ret = __memp_fput(mpf, epg->page, 0);
+ if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
goto err_inc;
- (void)__TLPUT(dbc, epg->lock);
/* Free the rest of the pages in the stack. */
while (++epg <= cp->csp) {
@@ -315,11 +316,12 @@ __bam_dpages(dbc, stack_epg)
goto err;
}
- if ((ret = __db_free(dbc, epg->page)) != 0) {
- epg->page = NULL;
+ ret = __db_free(dbc, epg->page);
+ epg->page = NULL;
+ if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
goto err_inc;
- }
- (void)__TLPUT(dbc, epg->lock);
}
if (0) {
@@ -447,11 +449,13 @@ err: for (; epg <= cp->csp; ++epg) {
if (0) {
stop: done = 1;
}
- (void)__TLPUT(dbc, p_lock);
+ if ((t_ret = __TLPUT(dbc, p_lock)) != 0 && ret == 0)
+ ret = t_ret;
if (parent != NULL &&
(t_ret = __memp_fput(mpf, parent, 0)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, c_lock);
+ if ((t_ret = __TLPUT(dbc, c_lock)) != 0 && ret == 0)
+ ret = t_ret;
if (child != NULL &&
(t_ret = __memp_fput(mpf, child, 0)) != 0 && ret == 0)
ret = t_ret;
@@ -459,3 +463,111 @@ stop: done = 1;
return (ret);
}
+
+/*
+ * __bam_relink --
+ * Relink around a deleted page.
+ *
+ * PUBLIC: int __bam_relink __P((DBC *, PAGE *, PAGE **));
+ */
+int
+__bam_relink(dbc, pagep, new_next)
+ DBC *dbc;
+ PAGE *pagep, **new_next;
+{
+ DB *dbp;
+ PAGE *np, *pp;
+ DB_LOCK npl, ppl;
+ DB_LSN *nlsnp, *plsnp, ret_lsn;
+ DB_MPOOLFILE *mpf;
+ int ret, t_ret;
+
+ dbp = dbc->dbp;
+ np = pp = NULL;
+ LOCK_INIT(npl);
+ LOCK_INIT(ppl);
+ nlsnp = plsnp = NULL;
+ mpf = dbp->mpf;
+ ret = 0;
+
+ /*
+ * Retrieve and lock the one/two pages. For a remove, we may need
+ * two pages (the before and after). For an add, we only need one
+ * because, the split took care of the prev.
+ */
+ if (pagep->next_pgno != PGNO_INVALID) {
+ if ((ret = __db_lget(dbc,
+ 0, pagep->next_pgno, DB_LOCK_WRITE, 0, &npl)) != 0)
+ goto err;
+ if ((ret = __memp_fget(mpf, &pagep->next_pgno, 0, &np)) != 0) {
+ ret = __db_pgerr(dbp, pagep->next_pgno, ret);
+ goto err;
+ }
+ nlsnp = &np->lsn;
+ }
+ if (pagep->prev_pgno != PGNO_INVALID) {
+ if ((ret = __db_lget(dbc,
+ 0, pagep->prev_pgno, DB_LOCK_WRITE, 0, &ppl)) != 0)
+ goto err;
+ if ((ret = __memp_fget(mpf, &pagep->prev_pgno, 0, &pp)) != 0) {
+ ret = __db_pgerr(dbp, pagep->prev_pgno, ret);
+ goto err;
+ }
+ plsnp = &pp->lsn;
+ }
+
+ /* Log the change. */
+ if (DBC_LOGGING(dbc)) {
+ if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0,
+ pagep->pgno, &pagep->lsn, pagep->prev_pgno, plsnp,
+ pagep->next_pgno, nlsnp)) != 0)
+ goto err;
+ } else
+ LSN_NOT_LOGGED(ret_lsn);
+ if (np != NULL)
+ np->lsn = ret_lsn;
+ if (pp != NULL)
+ pp->lsn = ret_lsn;
+ pagep->lsn = ret_lsn;
+
+ /*
+ * Modify and release the two pages.
+ *
+ * !!!
+ * The parameter new_next gets set to the page following the page we
+ * are removing. If there is no following page, then new_next gets
+ * set to NULL.
+ */
+ if (np != NULL) {
+ np->prev_pgno = pagep->prev_pgno;
+ if (new_next == NULL)
+ ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
+ else {
+ *new_next = np;
+ ret = __memp_fset(mpf, np, DB_MPOOL_DIRTY);
+ }
+ if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ goto err;
+ } else if (new_next != NULL)
+ *new_next = NULL;
+
+ if (pp != NULL) {
+ pp->next_pgno = pagep->next_pgno;
+ ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY);
+ if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ goto err;
+ }
+ return (0);
+
+err: if (np != NULL)
+ (void)__memp_fput(mpf, np, 0);
+ (void)__TLPUT(dbc, npl);
+ if (pp != NULL)
+ (void)__memp_fput(mpf, pp, 0);
+ (void)__TLPUT(dbc, ppl);
+ return (ret);
+}
diff --git a/db/btree/bt_method.c b/db/btree/bt_method.c
index 84abe96a2..0b67da91e 100644
--- a/db/btree/bt_method.c
+++ b/db/btree/bt_method.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2003
+ * Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_method.c,v 11.38 2004/09/22 03:31:26 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_method.c,v 11.34 2003/06/30 17:19:32 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -21,15 +19,12 @@ static const char revid[] = "$Id: bt_method.c,v 11.34 2003/06/30 17:19:32 bostic
#include "dbinc/qam.h"
static int __bam_set_bt_maxkey __P((DB *, u_int32_t));
-static int __bam_get_bt_minkey __P((DB *, u_int32_t *));
static int __bam_set_bt_minkey __P((DB *, u_int32_t));
static int __bam_set_bt_prefix
__P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
static int __ram_get_re_delim __P((DB *, int *));
static int __ram_set_re_delim __P((DB *, int));
-static int __ram_get_re_len __P((DB *, u_int32_t *));
static int __ram_set_re_len __P((DB *, u_int32_t));
-static int __ram_get_re_pad __P((DB *, int *));
static int __ram_set_re_pad __P((DB *, int));
static int __ram_get_re_source __P((DB *, const char **));
static int __ram_set_re_source __P((DB *, const char *));
@@ -241,8 +236,10 @@ __bam_set_bt_maxkey(dbp, bt_maxkey)
/*
* __db_get_bt_minkey --
* Get the minimum keys per page.
+ *
+ * PUBLIC: int __bam_get_bt_minkey __P((DB *, u_int32_t *));
*/
-static int
+int
__bam_get_bt_minkey(dbp, bt_minkeyp)
DB *dbp;
u_int32_t *bt_minkeyp;
@@ -389,17 +386,34 @@ __ram_set_re_delim(dbp, re_delim)
/*
* __db_get_re_len --
* Get the variable-length input record length.
+ *
+ * PUBLIC: int __ram_get_re_len __P((DB *, u_int32_t *));
*/
-static int
+int
__ram_get_re_len(dbp, re_lenp)
DB *dbp;
u_int32_t *re_lenp;
{
BTREE *t;
+ QUEUE *q;
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
- t = dbp->bt_internal;
- *re_lenp = t->re_len;
+
+ /*
+ * This has to work for all access methods, before or after opening the
+ * database. When the record length is set with __ram_set_re_len, the
+ * value in both the BTREE and QUEUE structs will be correct.
+ * Otherwise, this only makes sense after the database in opened, in
+ * which case we know the type.
+ */
+ if (dbp->type == DB_QUEUE) {
+ q = dbp->q_internal;
+ *re_lenp = q->re_len;
+ } else {
+ t = dbp->bt_internal;
+ *re_lenp = t->re_len;
+ }
+
return (0);
}
@@ -432,18 +446,34 @@ __ram_set_re_len(dbp, re_len)
/*
* __db_get_re_pad --
* Get the fixed-length record pad character.
+ *
+ * PUBLIC: int __ram_get_re_pad __P((DB *, int *));
*/
-static int
+int
__ram_get_re_pad(dbp, re_padp)
DB *dbp;
int *re_padp;
{
BTREE *t;
+ QUEUE *q;
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
- t = dbp->bt_internal;
- *re_padp = t->re_pad;
+ /*
+ * This has to work for all access methods, before or after opening the
+ * database. When the record length is set with __ram_set_re_pad, the
+ * value in both the BTREE and QUEUE structs will be correct.
+ * Otherwise, this only makes sense after the database in opened, in
+ * which case we know the type.
+ */
+ if (dbp->type == DB_QUEUE) {
+ q = dbp->q_internal;
+ *re_padp = q->re_pad;
+ } else {
+ t = dbp->bt_internal;
+ *re_padp = t->re_pad;
+ }
+
return (0);
}
diff --git a/db/btree/bt_open.c b/db/btree/bt_open.c
index 20f594fe5..e890c5dd7 100644
--- a/db/btree/bt_open.c
+++ b/db/btree/bt_open.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_open.c,v 11.92 2004/04/29 14:39:47 ubell Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_open.c,v 11.87 2003/07/17 01:39:09 margo Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -286,6 +284,7 @@ __bam_read_root(dbp, txn, base_pgno, flags)
DB_MPOOLFILE *mpf;
int ret, t_ret;
+ COMPQUIET(flags, 0);
meta = NULL;
t = dbp->bt_internal;
LOCK_INIT(metalock);
@@ -335,19 +334,6 @@ __bam_read_root(dbp, txn, base_pgno, flags)
*/
t->bt_lpgno = PGNO_INVALID;
- /*
- * We must initialize last_pgno, it could be stale.
- * We update this without holding the meta page write
- * locked. This is ok since two threads in the code
- * must be setting it to the same value. SR #7159.
- */
- if (!LF_ISSET(DB_RDONLY) && dbp->meta_pgno == PGNO_BASE_MD) {
- __memp_last_pgno(mpf, &meta->dbmeta.last_pgno);
- ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
- } else
- ret = __memp_fput(mpf, meta, 0);
- meta = NULL;
-
err: /* Put the metadata page back. */
if (meta != NULL &&
(t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
@@ -449,74 +435,76 @@ __bam_new_file(dbp, txn, fhp, name)
mpf = dbp->mpf;
root = NULL;
meta = NULL;
- memset(&pdbt, 0, sizeof(pdbt));
buf = NULL;
- /* Build meta-data page. */
-
if (name == NULL) {
+ /* Build the meta-data page. */
pgno = PGNO_BASE_MD;
- ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta);
+ if ((ret =
+ __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta)) != 0)
+ return (ret);
+ LSN_NOT_LOGGED(lsn);
+ __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+ meta->root = 1;
+ meta->dbmeta.last_pgno = 1;
+ ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
+ meta = NULL;
+ if (ret != 0)
+ goto err;
+
+ /* Build the root page. */
+ pgno = 1;
+ if ((ret =
+ __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0)
+ goto err;
+ P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
+ LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
+ LSN_NOT_LOGGED(root->lsn);
+ ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
+ root = NULL;
+ if (ret != 0)
+ goto err;
} else {
+ memset(&pdbt, 0, sizeof(pdbt));
+
+ /* Build the meta-data page. */
pginfo.db_pagesize = dbp->pgsize;
pginfo.flags =
F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
pginfo.type = dbp->type;
pdbt.data = &pginfo;
pdbt.size = sizeof(pginfo);
- ret = __os_calloc(dbp->dbenv, 1, dbp->pgsize, &buf);
+ if ((ret = __os_calloc(dbenv, 1, dbp->pgsize, &buf)) != 0)
+ return (ret);
meta = (BTMETA *)buf;
- }
- if (ret != 0)
- return (ret);
-
- LSN_NOT_LOGGED(lsn);
- __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
- meta->root = 1;
- meta->dbmeta.last_pgno = 1;
-
- if (name == NULL)
- ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
- else {
+ LSN_NOT_LOGGED(lsn);
+ __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+ meta->root = 1;
+ meta->dbmeta.last_pgno = 1;
if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0)
goto err;
- ret = __fop_write(dbenv, txn, name,
- DB_APP_DATA, fhp, dbp->pgsize, 0, 0, buf, dbp->pgsize, 1,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
- }
- if (ret != 0)
- goto err;
- meta = NULL;
-
- /* Now build root page. */
- if (name == NULL) {
- pgno = 1;
- if ((ret =
- __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0)
+ if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
+ dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET(
+ dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
goto err;
- } else {
+ meta = NULL;
+
+ /* Build the root page. */
#ifdef DIAGNOSTIC
memset(buf, CLEAR_BYTE, dbp->pgsize);
#endif
root = (PAGE *)buf;
- }
-
- P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
- LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
- LSN_NOT_LOGGED(root->lsn);
-
- if (name == NULL)
- ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
- else {
+ P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
+ LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
+ LSN_NOT_LOGGED(root->lsn);
if ((ret = __db_pgout(dbenv, root->pgno, root, &pdbt)) != 0)
goto err;
- ret = __fop_write(dbenv, txn, name,
- DB_APP_DATA, fhp, dbp->pgsize, 1, 0, buf, dbp->pgsize, 1,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
+ if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
+ dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET(
+ dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
+ goto err;
+ root = NULL;
}
- if (ret != 0)
- goto err;
- root = NULL;
err: if (buf != NULL)
__os_free(dbenv, buf);
@@ -604,9 +592,8 @@ err:
if (root != NULL)
if ((t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
ret = t_ret;
- if (LOCK_ISSET(metalock))
- if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
- ret = t_ret;
+ if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+ ret = t_ret;
if (dbc != NULL)
if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret;
diff --git a/db/btree/bt_put.c b/db/btree/bt_put.c
index b98c6c579..060e8970f 100644
--- a/db/btree/bt_put.c
+++ b/db/btree/bt_put.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_put.c,v 11.79 2004/01/28 03:35:49 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_put.c,v 11.78 2003/10/31 15:07:40 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
diff --git a/db/btree/bt_rec.c b/db/btree/bt_rec.c
index 1587028b3..e3fa7363c 100644
--- a/db/btree/bt_rec.c
+++ b/db/btree/bt_rec.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_rec.c,v 11.70 2004/09/24 00:43:12 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_rec.c,v 11.64 2003/09/13 18:48:58 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -51,7 +49,7 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp;
db_pgno_t pgno, root_pgno;
u_int32_t ptype;
- int cmp, l_update, p_update, r_update, rc, ret, ret_l, rootsplit, t_ret;
+ int cmp, l_update, p_update, r_update, rc, ret, rootsplit, t_ret;
COMPQUIET(info, NULL);
REC_PRINT(__bam_split_print);
@@ -83,50 +81,40 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
pgno = PGNO(sp);
root_pgno = argp->root_pgno;
rootsplit = root_pgno != PGNO_INVALID;
- if ((ret_l = __memp_fget(mpf, &argp->left, 0, &lp)) != 0)
- lp = NULL;
- if (__memp_fget(mpf, &argp->right, 0, &rp) != 0)
- rp = NULL;
+ REC_FGET(mpf, argp->left, &lp, right);
+right: REC_FGET(mpf, argp->right, &rp, redo);
- if (DB_REDO(op)) {
+redo: if (DB_REDO(op)) {
l_update = r_update = p_update = 0;
/*
* Decide if we need to resplit the page.
*
- * If this is a root split, then the root has to exist, it's
- * the page we're splitting and it gets modified. If this is
- * not a root split, then the left page has to exist, for the
- * same reason.
+ * If this is a root split, then the root has to exist unless
+ * we have truncated it due to a future deallocation.
*/
if (rootsplit) {
- if ((ret = __memp_fget(mpf, &pgno, 0, &pp)) != 0) {
- ret = __db_pgerr(file_dbp, pgno, ret);
- pp = NULL;
- goto out;
- }
- cmp = log_compare(&LSN(pp), &LSN(argp->pg.data));
- CHECK_LSN(op, cmp, &LSN(pp), &LSN(argp->pg.data));
+ REC_FGET(mpf, root_pgno, &pp, do_left);
+ cmp =
+ log_compare(&LSN(pp), &LSN(argp->pg.data));
+ CHECK_LSN(op,
+ cmp, &LSN(pp), &LSN(argp->pg.data));
p_update = cmp == 0;
- } else if (lp == NULL) {
- ret = __db_pgerr(file_dbp, argp->left, ret_l);
- goto out;
}
- if (lp != NULL) {
+do_left: if (lp != NULL) {
cmp = log_compare(&LSN(lp), &argp->llsn);
CHECK_LSN(op, cmp, &LSN(lp), &argp->llsn);
if (cmp == 0)
l_update = 1;
- } else
- l_update = 1;
+ }
if (rp != NULL) {
cmp = log_compare(&LSN(rp), &argp->rlsn);
CHECK_LSN(op, cmp, &LSN(rp), &argp->rlsn);
if (cmp == 0)
r_update = 1;
- } else
- r_update = 1;
+ }
+
if (!p_update && !l_update && !r_update)
goto check_next;
@@ -159,13 +147,6 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
NUM_ENT(sp))) != 0)
goto out;
- /* If the left child is wrong, update it. */
- if (lp == NULL && (ret = __memp_fget(
- mpf, &argp->left, DB_MPOOL_CREATE, &lp)) != 0) {
- ret = __db_pgerr(file_dbp, argp->left, ret);
- lp = NULL;
- goto out;
- }
if (l_update) {
memcpy(lp, _lp, file_dbp->pgsize);
lp->lsn = *lsnp;
@@ -174,13 +155,6 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
lp = NULL;
}
- /* If the right child is wrong, update it. */
- if (rp == NULL && (ret = __memp_fget(
- mpf, &argp->right, DB_MPOOL_CREATE, &rp)) != 0) {
- ret = __db_pgerr(file_dbp, argp->right, ret);
- rp = NULL;
- goto out;
- }
if (r_update) {
memcpy(rp, _rp, file_dbp->pgsize);
rp->lsn = *lsnp;
@@ -222,12 +196,19 @@ check_next: /*
* previous-page pointer updated to our new page. The next
* page must exist because we're redoing the operation.
*/
- if (!rootsplit && !IS_ZERO_LSN(argp->nlsn)) {
+ if (!rootsplit && argp->npgno != PGNO_INVALID) {
if ((ret =
__memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
- ret = __db_pgerr(file_dbp, argp->npgno, ret);
- np = NULL;
- goto out;
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(
+ file_dbp, argp->npgno, ret);
+ goto out;
+ } else
+ goto done;
}
cmp = log_compare(&LSN(np), &argp->nlsn);
CHECK_LSN(op, cmp, &LSN(np), &argp->nlsn);
@@ -294,7 +275,7 @@ lrundo: if ((rootsplit && lp != NULL) || rp != NULL) {
* 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 (!rootsplit && argp->npgno != PGNO_INVALID) {
if ((ret =
__memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
np = NULL;
@@ -366,17 +347,17 @@ __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
/* Fix the root page. */
pgno = root_pgno = argp->root_pgno;
if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) {
- /* The root page must always exist if we are going forward. */
- if (DB_REDO(op)) {
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
ret = __db_pgerr(file_dbp, pgno, ret);
goto out;
- }
- /* This must be the root of an OPD tree. */
- DB_ASSERT(root_pgno !=
- ((BTREE *)file_dbp->bt_internal)->bt_root);
- ret = 0;
- goto do_page;
+ } else
+ goto do_page;
}
+
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->rootlsn);
@@ -408,10 +389,15 @@ do_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 (DB_UNDO(op))
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
goto done;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
}
modified = 0;
(void)__ua_memcpy(&copy_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN));
@@ -468,10 +454,15 @@ __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
/* 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 (DB_UNDO(op))
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
goto done;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
}
modified = 0;
@@ -537,10 +528,15 @@ __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
/* 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 (DB_UNDO(op))
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
goto done;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
}
modified = 0;
@@ -621,10 +617,15 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
/* 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 (DB_UNDO(op))
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
goto done;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
}
modified = 0;
@@ -692,10 +693,15 @@ __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
/* 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 (DB_UNDO(op))
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
goto done;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
}
bk = GET_BKEYDATA(file_dbp, pagep, argp->indx);
@@ -796,8 +802,11 @@ __bam_root_recover(dbenv, dbtp, lsnp, op, info)
REC_INTRO(__bam_root_read, 0);
if ((ret = __memp_fget(mpf, &argp->meta_pgno, 0, &meta)) != 0) {
- /* The metadata page must always exist on redo. */
- if (DB_REDO(op)) {
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
ret = __db_pgerr(file_dbp, argp->meta_pgno, ret);
goto out;
} else
@@ -973,3 +982,148 @@ out: if (rdbc != NULL && (t_ret = __db_c_close(rdbc)) != 0 && ret == 0)
ret = t_ret;
REC_CLOSE;
}
+
+/*
+ * __bam_relink_recover --
+ * Recovery function for relink.
+ *
+ * PUBLIC: int __bam_relink_recover
+ * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
+ */
+int
+__bam_relink_recover(dbenv, dbtp, lsnp, op, info)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops op;
+ void *info;
+{
+ __bam_relink_args *argp;
+ DB *file_dbp;
+ DBC *dbc;
+ DB_MPOOLFILE *mpf;
+ PAGE *pagep;
+ int cmp_n, cmp_p, modified, ret;
+
+ pagep = NULL;
+ COMPQUIET(info, NULL);
+ REC_PRINT(__bam_relink_print);
+ REC_INTRO(__bam_relink_read, 1);
+
+ /*
+ * There are up to three pages we need to check -- the page, and the
+ * previous and next pages, if they existed. For a page add operation,
+ * the current page is the result of a split and is being recovered
+ * elsewhere, so all we need do is recover the next page.
+ */
+ if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ } else
+ goto next2;
+ }
+ modified = 0;
+
+ cmp_p = log_compare(&LSN(pagep), &argp->lsn);
+ CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
+ if (cmp_p == 0 && DB_REDO(op)) {
+ /* Redo the relink. */
+ pagep->lsn = *lsnp;
+ modified = 1;
+ } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
+ /* Undo the relink. */
+ pagep->next_pgno = argp->next;
+ pagep->prev_pgno = argp->prev;
+
+ pagep->lsn = argp->lsn;
+ modified = 1;
+ }
+ if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+ goto out;
+ pagep = NULL;
+
+next2: if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->next, ret);
+ goto out;
+ } else
+ goto prev;
+ }
+
+ modified = 0;
+ cmp_n = log_compare(lsnp, &LSN(pagep));
+ cmp_p = log_compare(&LSN(pagep), &argp->lsn_next);
+ CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_next);
+ if (cmp_p == 0 && DB_REDO(op)) {
+ /* Redo the remove or undo the add. */
+ pagep->prev_pgno = argp->prev;
+
+ modified = 1;
+ } else if (cmp_n == 0 && DB_UNDO(op)) {
+ /* Undo the remove or redo the add. */
+ pagep->prev_pgno = argp->pgno;
+
+ modified = 1;
+ }
+ if (modified == 1) {
+ if (DB_UNDO(op))
+ pagep->lsn = argp->lsn_next;
+ else
+ pagep->lsn = *lsnp;
+ }
+ if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+ goto out;
+ pagep = NULL;
+
+prev: if ((ret = __memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
+ if (ret != DB_PAGE_NOTFOUND
+#ifndef HAVE_FTRUNCATE
+ || DB_REDO(op)
+#endif
+ ) {
+ ret = __db_pgerr(file_dbp, argp->prev, ret);
+ goto out;
+ } else
+ goto done;
+ }
+
+ modified = 0;
+ cmp_p = log_compare(&LSN(pagep), &argp->lsn_prev);
+ CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_prev);
+ if (cmp_p == 0 && DB_REDO(op)) {
+ /* Redo the relink. */
+ pagep->next_pgno = argp->next;
+
+ modified = 1;
+ } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
+ /* Undo the relink. */
+ pagep->next_pgno = argp->pgno;
+
+ modified = 1;
+ }
+ if (modified == 1) {
+ if (DB_UNDO(op))
+ pagep->lsn = argp->lsn_prev;
+ else
+ pagep->lsn = *lsnp;
+ }
+ if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+ goto out;
+ pagep = NULL;
+
+done: *lsnp = argp->prev_lsn;
+ ret = 0;
+
+out: if (pagep != NULL)
+ (void)__memp_fput(mpf, pagep, 0);
+ REC_CLOSE;
+}
diff --git a/db/btree/bt_reclaim.c b/db/btree/bt_reclaim.c
index bc85bd2d3..ee722a30f 100644
--- a/db/btree/bt_reclaim.c
+++ b/db/btree/bt_reclaim.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1998-2003
+ * Copyright (c) 1998-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_reclaim.c,v 11.15 2004/01/28 03:35:49 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_reclaim.c,v 11.14 2003/06/30 17:19:33 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
diff --git a/db/btree/bt_recno.c b/db/btree/bt_recno.c
index 2098e4d94..78f149dd6 100644
--- a/db/btree/bt_recno.c
+++ b/db/btree/bt_recno.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997-2003
+ * Copyright (c) 1997-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_recno.c,v 11.117 2004/03/28 17:01:01 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_recno.c,v 11.113 2003/06/30 17:19:34 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -89,11 +87,13 @@ static int __ram_update __P((DBC *, db_recno_t, int));
* After a search, copy the found page into the cursor, discarding any
* currently held lock.
*/
-#define STACK_TO_CURSOR(cp) { \
+#define STACK_TO_CURSOR(cp, ret) { \
+ int __t_ret; \
(cp)->page = (cp)->csp->page; \
(cp)->pgno = (cp)->csp->page->pgno; \
(cp)->indx = (cp)->csp->indx; \
- (void)__TLPUT(dbc, (cp)->lock); \
+ if ((__t_ret = __TLPUT(dbc, (cp)->lock)) != 0 && (ret) == 0) \
+ ret = __t_ret; \
(cp)->lock = (cp)->csp->lock; \
(cp)->lock_mode = (cp)->csp->lock_mode; \
}
@@ -235,7 +235,9 @@ __ram_c_del(dbc)
stack = 1;
/* Copy the page into the cursor. */
- STACK_TO_CURSOR(cp);
+ STACK_TO_CURSOR(cp, ret);
+ if (ret != 0)
+ goto err;
/*
* If re-numbering records, the on-page deleted flag can only mean
@@ -495,7 +497,9 @@ retry: switch (flags) {
}
/* Copy the page into the cursor. */
- STACK_TO_CURSOR(cp);
+ STACK_TO_CURSOR(cp, ret);
+ if (ret != 0)
+ goto err;
/*
* If re-numbering records, the on-page deleted flag means this
@@ -653,7 +657,9 @@ split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0)
DB_ASSERT(exact || CD_ISSET(cp));
/* Copy the page into the cursor. */
- STACK_TO_CURSOR(cp);
+ STACK_TO_CURSOR(cp, ret);
+ if (ret != 0)
+ goto err;
ret = __bam_iitem(dbc, key, data, iiflags, 0);
t_ret = __bam_stkrel(dbc, STK_CLRDBC);
@@ -988,7 +994,7 @@ __ram_source(dbp)
* when it comes time to write the database back to the source.
*/
if ((t->re_fp = fopen(t->re_source, "r")) == NULL) {
- ret = errno;
+ ret = __os_get_errno();
__db_err(dbp->dbenv, "%s: %s", t->re_source, db_strerror(ret));
return (ret);
}
@@ -1065,13 +1071,13 @@ __ram_writeback(dbp)
*/
if (t->re_fp != NULL) {
if (fclose(t->re_fp) != 0) {
- ret = errno;
+ ret = __os_get_errno();
goto err;
}
t->re_fp = NULL;
}
if ((fp = fopen(t->re_source, "w")) == NULL) {
- ret = errno;
+ ret = __os_get_errno();
__db_err(dbenv, "%s: %s", t->re_source, db_strerror(ret));
goto err;
}
@@ -1093,23 +1099,24 @@ __ram_writeback(dbp)
* and the pad character if we're doing fixed-length records.
*/
delim = t->re_delim;
- if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
- if ((ret = __os_malloc(dbenv, t->re_len, &pad)) != 0)
- goto err;
- memset(pad, t->re_pad, t->re_len);
- }
for (keyno = 1;; ++keyno) {
switch (ret = __db_get(dbp, NULL, &key, &data, 0)) {
case 0:
- if (data.size != 0 && (u_int32_t)fwrite(
- data.data, 1, data.size, fp) != data.size)
+ if (data.size != 0 &&
+ fwrite(data.data, 1, data.size, fp) != data.size)
goto write_err;
break;
case DB_KEYEMPTY:
- if (F_ISSET(dbp, DB_AM_FIXEDLEN) &&
- (u_int32_t)fwrite(pad, 1, t->re_len, fp) !=
- t->re_len)
- goto write_err;
+ if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
+ if (pad == NULL) {
+ if ((ret = __os_malloc(
+ dbenv, t->re_len, &pad)) != 0)
+ goto err;
+ memset(pad, t->re_pad, t->re_len);
+ }
+ if (fwrite(pad, 1, t->re_len, fp) != t->re_len)
+ goto write_err;
+ }
break;
case DB_NOTFOUND:
ret = 0;
@@ -1119,8 +1126,8 @@ __ram_writeback(dbp)
}
if (!F_ISSET(dbp, DB_AM_FIXEDLEN) &&
fwrite(&delim, 1, 1, fp) != 1) {
-write_err: ret = errno;
- __db_err(dbp->dbenv,
+write_err: ret = __os_get_errno();
+ __db_err(dbenv,
"%s: write failed to backing file: %s",
t->re_source, strerror(ret));
goto err;
@@ -1130,9 +1137,10 @@ write_err: ret = errno;
err:
done: /* Close the file descriptor. */
if (fp != NULL && fclose(fp) != 0) {
+ t_ret = __os_get_errno();
if (ret == 0)
- ret = errno;
- __db_err(dbenv, "%s: %s", t->re_source, db_strerror(errno));
+ ret = t_ret;
+ __db_err(dbenv, "%s: %s", t->re_source, db_strerror(t_ret));
}
/* Discard the cursor. */
@@ -1275,7 +1283,9 @@ retry: /* Find the slot for insertion. */
stack = 1;
/* Copy the page into the cursor. */
- STACK_TO_CURSOR(cp);
+ STACK_TO_CURSOR(cp, ret);
+ if (ret != 0)
+ goto err;
/*
* The application may modify the data based on the selected record
diff --git a/db/btree/bt_rsearch.c b/db/btree/bt_rsearch.c
index 92eb82144..0027ec9e4 100644
--- a/db/btree/bt_rsearch.c
+++ b/db/btree/bt_rsearch.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -35,14 +35,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_rsearch.c,v 11.40 2004/07/23 17:21:09 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_rsearch.c,v 11.37 2003/06/30 17:19:34 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -78,11 +76,12 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
db_lockmode_t lock_mode;
db_pgno_t pg;
db_recno_t recno, t_recno, total;
- int ret, stack;
+ int ret, stack, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal;
+ h = NULL;
BT_STK_CLR(cp);
@@ -123,8 +122,11 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
if (!stack &&
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
- (void)__memp_fput(mpf, h, 0);
- (void)__LPUT(dbc, lock);
+ ret = __memp_fput(mpf, h, 0);
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ return (ret);
lock_mode = DB_LOCK_WRITE;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret);
@@ -167,9 +169,11 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
* eliminate any concurrency. A possible fix
* would be to lock the last leaf page instead.
*/
- (void)__memp_fput(mpf, h, 0);
- (void)__TLPUT(dbc, lock);
- return (DB_NOTFOUND);
+ ret = __memp_fput(mpf, h, 0);
+ if ((t_ret =
+ __TLPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ return (ret == 0 ? DB_NOTFOUND : ret);
}
}
}
@@ -201,9 +205,13 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
*exactp = 0;
if (!LF_ISSET(S_PAST_EOF) ||
recno > t_recno + 1) {
- (void)__memp_fput(mpf, h, 0);
- (void)__TLPUT(dbc, lock);
- ret = DB_NOTFOUND;
+ ret = __memp_fput(mpf, h, 0);
+ h = NULL;
+ if ((t_ret = __TLPUT(dbc,
+ lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret == 0)
+ ret = DB_NOTFOUND;
goto err;
}
}
@@ -265,6 +273,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
cp, h, indx, lock, lock_mode, ret);
if (ret != 0)
goto err;
+ h = NULL;
lock_mode = DB_LOCK_WRITE;
if ((ret =
@@ -281,7 +290,9 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
(h->level - 1) == LEAFLEVEL)
stack = 1;
- (void)__memp_fput(mpf, h, 0);
+ if ((ret = __memp_fput(mpf, h, 0)) != 0)
+ goto err;
+ h = NULL;
lock_mode = stack &&
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
@@ -292,7 +303,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
* is OK because this only happens when we are
* descending the tree holding read-locks.
*/
- __LPUT(dbc, lock);
+ (void)__LPUT(dbc, lock);
goto err;
}
}
@@ -302,8 +313,12 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
}
/* NOTREACHED */
-err: BT_STK_POP(cp);
+err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
+
+ BT_STK_POP(cp);
__bam_stkrel(dbc, 0);
+
return (ret);
}
@@ -378,7 +393,7 @@ __bam_nrecs(dbc, rep)
DB_MPOOLFILE *mpf;
PAGE *h;
db_pgno_t pgno;
- int ret;
+ int ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@@ -391,10 +406,11 @@ __bam_nrecs(dbc, rep)
*rep = RE_NREC(h);
- (void)__memp_fput(mpf, h, 0);
- (void)__TLPUT(dbc, lock);
+ ret = __memp_fput(mpf, h, 0);
+ if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
- return (0);
+ return (ret);
}
/*
diff --git a/db/btree/bt_search.c b/db/btree/bt_search.c
index dc35c7c68..4fb07f446 100644
--- a/db/btree/bt_search.c
+++ b/db/btree/bt_search.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_search.c,v 11.50 2004/07/23 17:21:09 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_search.c,v 11.47 2003/06/30 17:19:35 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -85,12 +83,13 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
db_lockmode_t lock_mode;
db_pgno_t pg;
db_recno_t recno;
- int adjust, cmp, deloffset, ret, stack;
+ int adjust, cmp, deloffset, ret, stack, t_ret;
int (*func) __P((DB *, const DBT *, const DBT *));
dbp = dbc->dbp;
mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal;
+ h = NULL;
t = dbp->bt_internal;
recno = 0;
@@ -135,8 +134,11 @@ try_again:
if (!stack &&
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
- (void)__memp_fput(mpf, h, 0);
- (void)__LPUT(dbc, lock);
+ ret = __memp_fput(mpf, h, 0);
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ return (ret);
lock_mode = DB_LOCK_WRITE;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret);
@@ -149,8 +151,11 @@ try_again:
(u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
/* Someone else split the root, start over. */
- (void)__memp_fput(mpf, h, 0);
- (void)__LPUT(dbc, lock);
+ ret = __memp_fput(mpf, h, 0);
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ return (ret);
goto try_again;
}
stack = 1;
@@ -198,13 +203,19 @@ try_again:
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) {
*exactp = 0;
- if (LF_ISSET(S_EXACT))
- goto notfound;
+ if (LF_ISSET(S_EXACT)) {
+ ret = DB_NOTFOUND;
+ goto err;
+ }
if (LF_ISSET(S_STK_ONLY)) {
BT_STK_NUM(dbp->dbenv, cp, h, base, ret);
- __LPUT(dbc, lock);
- (void)__memp_fput(mpf, h, 0);
+ if ((t_ret =
+ __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret =
+ __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
return (ret);
}
@@ -244,12 +255,17 @@ next: if (recnop != NULL)
if (LF_ISSET(S_STK_ONLY)) {
if (stop == h->level) {
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
- __LPUT(dbc, lock);
- (void)__memp_fput(mpf, h, 0);
+ if ((t_ret =
+ __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret =
+ __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
return (ret);
}
BT_STK_NUMPUSH(dbp->dbenv, cp, h, indx, ret);
(void)__memp_fput(mpf, h, 0);
+ h = NULL;
if ((ret = __db_lget(dbc,
LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
/*
@@ -257,7 +273,7 @@ next: if (recnop != NULL)
* is OK because it only happens when descending
* the tree holding read-locks.
*/
- __LPUT(dbc, lock);
+ (void)__LPUT(dbc, lock);
return (ret);
}
} else if (stack) {
@@ -273,6 +289,7 @@ next: if (recnop != NULL)
cp, h, indx, lock, lock_mode, ret);
if (ret != 0)
goto err;
+ h = NULL;
lock_mode = DB_LOCK_WRITE;
if ((ret =
@@ -289,7 +306,9 @@ next: if (recnop != NULL)
(h->level - 1) == LEAFLEVEL)
stack = 1;
- (void)__memp_fput(mpf, h, 0);
+ if ((ret = __memp_fput(mpf, h, 0)) != 0)
+ goto err;
+ h = NULL;
lock_mode = stack &&
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
@@ -300,7 +319,7 @@ next: if (recnop != NULL)
* is OK because this only happens when we are
* descending the tree holding read-locks.
*/
- __LPUT(dbc, lock);
+ (void)__LPUT(dbc, lock);
goto err;
}
}
@@ -357,8 +376,10 @@ found: *exactp = 1;
* If we weren't able to find a non-deleted duplicate, return
* DB_NOTFOUND.
*/
- if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type))
- goto notfound;
+ if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) {
+ ret = DB_NOTFOUND;
+ goto err;
+ }
/*
* Increment the record counter to point to the found element.
@@ -381,23 +402,27 @@ found: *exactp = 1;
if (LF_ISSET(S_STK_ONLY)) {
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
- __LPUT(dbc, lock);
- (void)__memp_fput(mpf, h, 0);
- } else {
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
+ } else
BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret);
- if (ret != 0)
- goto err;
- }
+ if (ret != 0)
+ goto err;
+
return (0);
-notfound:
- /* Keep the page locked for serializability. */
- (void)__memp_fput(mpf, h, 0);
- (void)__TLPUT(dbc, lock);
- ret = DB_NOTFOUND;
+err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
+
+ /* Keep any not-found page locked for serializability. */
+ if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
-err: BT_STK_POP(cp);
+ BT_STK_POP(cp);
__bam_stkrel(dbc, 0);
+
return (ret);
}
@@ -446,10 +471,12 @@ __bam_stkrel(dbc, flags)
*/
epg->page = NULL;
}
- if (LF_ISSET(STK_NOLOCK))
- (void)__LPUT(dbc, epg->lock);
- else
- (void)__TLPUT(dbc, epg->lock);
+ if (LF_ISSET(STK_NOLOCK)) {
+ if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
+ ret = t_ret;
+ } else
+ if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+ ret = t_ret;
}
/* Clear the stack, all pages have been released. */
diff --git a/db/btree/bt_split.c b/db/btree/bt_split.c
index 8c5066aed..3e2cb4e6d 100644
--- a/db/btree/bt_split.c
+++ b/db/btree/bt_split.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -35,18 +35,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: bt_split.c,v 11.66 2004/10/01 13:00:21 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_split.c,v 11.60 2003/06/30 17:19:35 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
-#include <limits.h>
#include <string.h>
#endif
@@ -120,7 +117,7 @@ __bam_split(dbc, arg, root_pgnop)
arg, S_WRPAIR, level, NULL, &exact) :
__bam_rsearch(dbc,
(db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0)
- return (ret);
+ break;
if (root_pgnop != NULL)
*root_pgnop = cp->csp[0].page->pgno == root_pgno ?
@@ -134,7 +131,7 @@ __bam_split(dbc, arg, root_pgnop)
if (2 * B_MAXSIZEONPAGE(cp->ovflsize)
<= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) {
__bam_stkrel(dbc, STK_NOLOCK);
- return (0);
+ break;
}
ret = cp->csp[0].page->pgno == root_pgno ?
__bam_root(dbc, &cp->csp[0]) :
@@ -162,10 +159,13 @@ __bam_split(dbc, arg, root_pgnop)
dir = UP;
break;
default:
- return (ret);
+ goto err;
}
}
- /* NOTREACHED */
+
+err: if (root_pgnop != NULL)
+ *root_pgnop = cp->root;
+ return (ret);
}
/*
@@ -184,10 +184,11 @@ __bam_root(dbc, cp)
PAGE *lp, *rp;
db_indx_t split;
u_int32_t opflags;
- int ret;
+ int ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
+ lp = rp = NULL;
/* Yeah, right. */
if (cp->page->level >= MAXBTREELEVEL) {
@@ -198,7 +199,6 @@ __bam_root(dbc, cp)
}
/* Create new left and right pages for the split. */
- lp = rp = NULL;
if ((ret = __db_new(dbc, TYPE(cp->page), &lp)) != 0 ||
(ret = __db_new(dbc, TYPE(cp->page), &rp)) != 0)
goto err;
@@ -238,24 +238,21 @@ __bam_root(dbc, cp)
goto err;
/* Adjust any cursors. */
- if ((ret = __bam_ca_split(dbc,
- cp->page->pgno, lp->pgno, rp->pgno, split, 1)) != 0)
- goto err;
-
- /* Success -- write the real pages back to the store. */
- (void)__memp_fput(mpf, cp->page, DB_MPOOL_DIRTY);
- (void)__TLPUT(dbc, cp->lock);
- (void)__memp_fput(mpf, lp, DB_MPOOL_DIRTY);
- (void)__memp_fput(mpf, rp, DB_MPOOL_DIRTY);
+ ret = __bam_ca_split(dbc, cp->page->pgno, lp->pgno, rp->pgno, split, 1);
- return (0);
+ /* Success or error: release pages and locks. */
+err: if ((t_ret =
+ __memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (lp != NULL &&
+ (t_ret = __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
+ ret = t_ret;
+ if (rp != NULL &&
+ (t_ret = __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
+ ret = t_ret;
-err: if (lp != NULL)
- (void)__memp_fput(mpf, lp, 0);
- if (rp != NULL)
- (void)__memp_fput(mpf, rp, 0);
- (void)__memp_fput(mpf, cp->page, 0);
- (void)__TLPUT(dbc, cp->lock);
return (ret);
}
@@ -371,9 +368,13 @@ __bam_page(dbc, pp, cp)
goto err;
/*
- * Lock the new page. We need to do this because someone
- * could get here through bt_lpgno if this page was recently
- * dealocated. They can't look at it before we commit.
+ * Lock the new page. We need to do this for two reasons: first, the
+ * fast-lookup code might have a reference to this page in bt_lpgno if
+ * the page was recently deleted from the tree, and that code doesn't
+ * walk the tree and so won't encounter the parent's page lock.
+ * Second, a dirty reader could get to this page via the parent or old
+ * page after the split is done but before the transaction is committed
+ * or aborted.
*/
if ((ret = __db_lget(dbc,
0, PGNO(alloc_rp), DB_LOCK_WRITE, 0, &rplock)) != 0)
@@ -460,20 +461,24 @@ __bam_page(dbc, pp, cp)
if ((t_ret =
__memp_fput(mpf, alloc_rp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, rplock);
+ if ((t_ret = __TLPUT(dbc, rplock)) != 0 && ret == 0)
+ ret = t_ret;
if ((t_ret =
__memp_fput(mpf, pp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, pp->lock);
+ if ((t_ret = __TLPUT(dbc, pp->lock)) != 0 && ret == 0)
+ ret = t_ret;
if ((t_ret =
__memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, cp->lock);
+ if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0)
+ ret = t_ret;
if (tp != NULL) {
if ((t_ret =
__memp_fput(mpf, tp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
- (void)__TLPUT(dbc, tplock);
+ if ((t_ret = __TLPUT(dbc, tplock)) != 0 && ret == 0)
+ ret = t_ret;
}
return (ret);
diff --git a/db/btree/bt_stat.c b/db/btree/bt_stat.c
index 0e8cff37f..9d99ee2c4 100644
--- a/db/btree/bt_stat.c
+++ b/db/btree/bt_stat.c
@@ -1,19 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_stat.c,v 11.78 2004/09/22 03:31:26 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_stat.c,v 11.61 2003/09/13 18:52:21 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
+#include <ctype.h>
#include <string.h>
#endif
@@ -24,6 +23,7 @@ static const char revid[] = "$Id: bt_stat.c,v 11.61 2003/09/13 18:52:21 bostic E
#include "dbinc/lock.h"
#include "dbinc/mp.h"
+#ifdef HAVE_STATISTICS
/*
* __bam_stat --
* Gather/print the btree statistics
@@ -103,10 +103,12 @@ __bam_stat(dbc, spp, flags)
sp->bt_levels = h->level;
/* Discard the root page. */
- if ((ret = __memp_fput(mpf, h, 0)) != 0)
- goto err;
+ ret = __memp_fput(mpf, h, 0);
h = NULL;
- __LPUT(dbc, lock);
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ goto err;
/* Walk the tree. */
if ((ret = __bam_traverse(dbc,
@@ -120,10 +122,12 @@ __bam_stat(dbc, spp, flags)
write_meta = !F_ISSET(dbp, DB_AM_RDONLY);
meta_only:
if (t->bt_meta != PGNO_BASE_MD || write_meta != 0) {
- if ((ret = __memp_fput(mpf, meta, 0)) != 0)
- goto err;
+ ret = __memp_fput(mpf, meta, 0);
meta = NULL;
- __LPUT(dbc, metalock);
+ if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+ ret = t_ret;
+ if (ret != 0)
+ goto err;
if ((ret = __db_lget(dbc,
0, t->bt_meta, write_meta == 0 ?
@@ -138,14 +142,15 @@ meta_only:
if ((ret = __db_lget(dbc, 0,
cp->root, DB_LOCK_READ, 0, &lock)) != 0)
goto err;
- if ((ret =
- __memp_fget(mpf, &cp->root, 0, (PAGE **)&h)) != 0)
+ if ((ret = __memp_fget(mpf, &cp->root, 0, &h)) != 0)
goto err;
sp->bt_nkeys = RE_NREC(h);
} else
sp->bt_nkeys = meta->dbmeta.key_count;
- sp->bt_ndata = meta->dbmeta.record_count;
+
+ sp->bt_ndata = dbp->type == DB_RECNO ?
+ sp->bt_nkeys : meta->dbmeta.record_count;
}
/* Get metadata page statistics. */
@@ -166,12 +171,14 @@ meta_only:
*(DB_BTREE_STAT **)spp = sp;
err: /* Discard the second page. */
- __LPUT(dbc, lock);
+ if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
ret = t_ret;
/* Discard the metadata page. */
- __LPUT(dbc, metalock);
+ if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+ ret = t_ret;
if (meta != NULL && (t_ret = __memp_fput(
mpf, meta, write_meta == 0 ? 0 : DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
@@ -185,106 +192,113 @@ err: /* Discard the second page. */
}
/*
- * __bam_traverse --
- * Walk a Btree database.
+ * __bam_stat_print --
+ * Display btree/recno statistics.
*
- * PUBLIC: int __bam_traverse __P((DBC *, db_lockmode_t,
- * PUBLIC: db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
+ * PUBLIC: int __bam_stat_print __P((DBC *, u_int32_t));
*/
int
-__bam_traverse(dbc, mode, root_pgno, callback, cookie)
+__bam_stat_print(dbc, flags)
DBC *dbc;
- db_lockmode_t mode;
- db_pgno_t root_pgno;
- int (*callback)__P((DB *, PAGE *, void *, int *));
- void *cookie;
+ u_int32_t flags;
{
- BINTERNAL *bi;
- BKEYDATA *bk;
+ static const FN fn[] = {
+ { BTM_DUP, "duplicates" },
+ { BTM_RECNO, "recno" },
+ { BTM_RECNUM, "record-numbers" },
+ { BTM_FIXEDLEN, "fixed-length" },
+ { BTM_RENUMBER, "renumber" },
+ { BTM_SUBDB, "multiple-databases" },
+ { BTM_DUPSORT, "sorted duplicates" },
+ { 0, NULL }
+ };
DB *dbp;
- DB_LOCK lock;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- RINTERNAL *ri;
- db_indx_t indx;
- int already_put, ret, t_ret;
+ DB_BTREE_STAT *sp;
+ DB_ENV *dbenv;
+ int lorder, ret;
+ const char *s;
dbp = dbc->dbp;
- mpf = dbp->mpf;
- already_put = 0;
+ dbenv = dbp->dbenv;
- if ((ret = __db_lget(dbc, 0, root_pgno, mode, 0, &lock)) != 0)
- return (ret);
- if ((ret = __memp_fget(mpf, &root_pgno, 0, &h)) != 0) {
- __LPUT(dbc, lock);
+ if ((ret = __bam_stat(dbc, &sp, 0)) != 0)
return (ret);
+
+ if (LF_ISSET(DB_STAT_ALL)) {
+ __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
+ __db_msg(dbenv, "Default Btree/Recno database information:");
}
- switch (TYPE(h)) {
- case P_IBTREE:
- for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
- bi = GET_BINTERNAL(dbp, h, indx);
- if (B_TYPE(bi->type) == B_OVERFLOW &&
- (ret = __db_traverse_big(dbp,
- ((BOVERFLOW *)bi->data)->pgno,
- callback, cookie)) != 0)
- goto err;
- if ((ret = __bam_traverse(
- dbc, mode, bi->pgno, callback, cookie)) != 0)
- goto err;
- }
- break;
- case P_IRECNO:
- for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
- ri = GET_RINTERNAL(dbp, h, indx);
- if ((ret = __bam_traverse(
- dbc, mode, ri->pgno, callback, cookie)) != 0)
- goto err;
- }
- break;
- case P_LBTREE:
- for (indx = 0; indx < NUM_ENT(h); indx += P_INDX) {
- bk = GET_BKEYDATA(dbp, h, indx);
- if (B_TYPE(bk->type) == B_OVERFLOW &&
- (ret = __db_traverse_big(dbp,
- GET_BOVERFLOW(dbp, h, indx)->pgno,
- callback, cookie)) != 0)
- goto err;
- bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
- if (B_TYPE(bk->type) == B_DUPLICATE &&
- (ret = __bam_traverse(dbc, mode,
- GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
- callback, cookie)) != 0)
- goto err;
- if (B_TYPE(bk->type) == B_OVERFLOW &&
- (ret = __db_traverse_big(dbp,
- GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
- callback, cookie)) != 0)
- goto err;
- }
+ __db_msg(dbenv, "%lx\tBtree magic number", (u_long)sp->bt_magic);
+ __db_msg(dbenv, "%lu\tBtree version number", (u_long)sp->bt_version);
+
+ (void)__db_get_lorder(dbp, &lorder);
+ switch (lorder) {
+ case 1234:
+ s = "Little-endian";
break;
- case P_LDUP:
- case P_LRECNO:
- for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
- bk = GET_BKEYDATA(dbp, h, indx);
- if (B_TYPE(bk->type) == B_OVERFLOW &&
- (ret = __db_traverse_big(dbp,
- GET_BOVERFLOW(dbp, h, indx)->pgno,
- callback, cookie)) != 0)
- goto err;
- }
+ case 4321:
+ s = "Big-endian";
break;
default:
- return (__db_pgfmt(dbp->dbenv, h->pgno));
+ s = "Unrecognized byte order";
+ break;
}
+ __db_msg(dbenv, "%s\tByte order", s);
+ __db_prflags(dbenv, NULL, sp->bt_metaflags, fn, NULL, "\tFlags");
+ if (dbp->type == DB_BTREE) {
+#ifdef NOT_IMPLEMENTED
+ __db_dl(dbenv, "Maximum keys per-page", (u_long)sp->bt_maxkey);
+#endif
+ __db_dl(dbenv, "Minimum keys per-page", (u_long)sp->bt_minkey);
+ }
+ if (dbp->type == DB_RECNO) {
+ __db_dl(dbenv,
+ "Fixed-length record size", (u_long)sp->bt_re_len);
+ __db_dl(dbenv,
+ "%#x\tFixed-length record pad", (u_int)sp->bt_re_pad);
+ }
+ __db_dl(dbenv,
+ "Underlying database page size", (u_long)sp->bt_pagesize);
+ __db_dl(dbenv, "Number of levels in the tree", (u_long)sp->bt_levels);
+ __db_dl(dbenv, dbp->type == DB_BTREE ?
+ "Number of unique keys in the tree" :
+ "Number of records in the tree", (u_long)sp->bt_nkeys);
+ __db_dl(dbenv,
+ "Number of data items in the tree", (u_long)sp->bt_ndata);
+
+ __db_dl(dbenv,
+ "Number of tree internal pages", (u_long)sp->bt_int_pg);
+ __db_dl_pct(dbenv,
+ "Number of bytes free in tree internal pages",
+ (u_long)sp->bt_int_pgfree,
+ DB_PCT_PG(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of tree leaf pages", (u_long)sp->bt_leaf_pg);
+ __db_dl_pct(dbenv, "Number of bytes free in tree leaf pages",
+ (u_long)sp->bt_leaf_pgfree, DB_PCT_PG(
+ sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of tree duplicate pages", (u_long)sp->bt_dup_pg);
+ __db_dl_pct(dbenv,
+ "Number of bytes free in tree duplicate pages",
+ (u_long)sp->bt_dup_pgfree,
+ DB_PCT_PG(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of tree overflow pages", (u_long)sp->bt_over_pg);
+ __db_dl_pct(dbenv, "Number of bytes free in tree overflow pages",
+ (u_long)sp->bt_over_pgfree, DB_PCT_PG(
+ sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize), "ff");
+ __db_dl(dbenv, "Number of empty pages", (u_long)sp->bt_empty_pg);
+
+ __db_dl(dbenv, "Number of pages on the free list", (u_long)sp->bt_free);
+
+ __os_ufree(dbenv, sp);
- ret = callback(dbp, h, cookie, &already_put);
-
-err: if (!already_put && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret != 0)
- ret = t_ret;
- __LPUT(dbc, lock);
-
- return (ret);
+ return (0);
}
/*
@@ -316,6 +330,9 @@ __bam_stat_callback(dbp, h, cookie, putp)
sp->bt_int_pgfree += P_FREESPACE(dbp, h);
break;
case P_LBTREE:
+ if (top == 0)
+ ++sp->bt_empty_pg;
+
/* Correct for on-page duplicates and deleted items. */
for (indx = 0; indx < top; indx += P_INDX) {
type = GET_BKEYDATA(dbp, h, indx + O_INDX)->type;
@@ -337,24 +354,28 @@ __bam_stat_callback(dbp, h, cookie, putp)
sp->bt_leaf_pgfree += P_FREESPACE(dbp, h);
break;
case P_LRECNO:
+ if (top == 0)
+ ++sp->bt_empty_pg;
+
/*
* If walking a recno tree, then each of these items is a key.
* Otherwise, we're walking an off-page duplicate set.
*/
if (dbp->type == DB_RECNO) {
- sp->bt_nkeys += top;
-
/*
- * Correct for deleted items in non-renumbering
- * Recno databases.
+ * Correct for deleted items in non-renumbering Recno
+ * databases.
*/
- if (F_ISSET(dbp, DB_AM_RENUMBER))
+ if (F_ISSET(dbp, DB_AM_RENUMBER)) {
+ sp->bt_nkeys += top;
sp->bt_ndata += top;
- else
+ } else
for (indx = 0; indx < top; indx += O_INDX) {
type = GET_BKEYDATA(dbp, h, indx)->type;
- if (!B_DISSET(type))
+ if (!B_DISSET(type)) {
++sp->bt_ndata;
+ ++sp->bt_nkeys;
+ }
}
++sp->bt_leaf_pg;
@@ -367,6 +388,9 @@ __bam_stat_callback(dbp, h, cookie, putp)
}
break;
case P_LDUP:
+ if (top == 0)
+ ++sp->bt_empty_pg;
+
/* Correct for deleted items. */
for (indx = 0; indx < top; indx += O_INDX)
if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type))
@@ -386,6 +410,60 @@ __bam_stat_callback(dbp, h, cookie, putp)
}
/*
+ * __bam_print_cursor --
+ * Display the current internal cursor.
+ *
+ * PUBLIC: void __bam_print_cursor __P((DBC *));
+ */
+void
+__bam_print_cursor(dbc)
+ DBC *dbc;
+{
+ static const FN fn[] = {
+ { C_DELETED, "C_DELETED" },
+ { C_RECNUM, "C_RECNUM" },
+ { C_RENUMBER, "C_RENUMBER" },
+ { 0, NULL }
+ };
+ DB_ENV *dbenv;
+ BTREE_CURSOR *cp;
+
+ dbenv = dbc->dbp->dbenv;
+ cp = (BTREE_CURSOR *)dbc->internal;
+
+ STAT_ULONG("Overflow size", cp->ovflsize);
+ if (dbc->dbtype == DB_RECNO)
+ STAT_ULONG("Recno", cp->recno);
+ STAT_ULONG("Order", cp->order);
+ __db_prflags(dbenv, NULL, cp->flags, fn, NULL, "\tInternal Flags");
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__bam_stat(dbc, spp, flags)
+ DBC *dbc;
+ void *spp;
+ u_int32_t flags;
+{
+ COMPQUIET(spp, NULL);
+ COMPQUIET(flags, 0);
+
+ return (__db_stat_not_built(dbc->dbp->dbenv));
+}
+
+int
+__bam_stat_print(dbc, flags)
+ DBC *dbc;
+ u_int32_t flags;
+{
+ COMPQUIET(flags, 0);
+
+ return (__db_stat_not_built(dbc->dbp->dbenv));
+}
+#endif
+
+/*
* __bam_key_range --
* Return proportion of keys relative to given key. The numbers are
* slightly skewed due to on page duplicates.
@@ -455,3 +533,111 @@ __bam_key_range(dbc, dbt, kp, flags)
return (0);
}
+
+/*
+ * __bam_traverse --
+ * Walk a Btree database.
+ *
+ * PUBLIC: int __bam_traverse __P((DBC *, db_lockmode_t,
+ * PUBLIC: db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
+ */
+int
+__bam_traverse(dbc, mode, root_pgno, callback, cookie)
+ DBC *dbc;
+ db_lockmode_t mode;
+ db_pgno_t root_pgno;
+ int (*callback)__P((DB *, PAGE *, void *, int *));
+ void *cookie;
+{
+ BINTERNAL *bi;
+ BKEYDATA *bk;
+ DB *dbp;
+ DB_LOCK lock;
+ DB_MPOOLFILE *mpf;
+ PAGE *h;
+ RINTERNAL *ri;
+ db_indx_t indx, *inp;
+ int already_put, ret, t_ret;
+
+ dbp = dbc->dbp;
+ mpf = dbp->mpf;
+ already_put = 0;
+
+ if ((ret = __db_lget(dbc, 0, root_pgno, mode, 0, &lock)) != 0)
+ return (ret);
+ if ((ret = __memp_fget(mpf, &root_pgno, 0, &h)) != 0) {
+ (void)__TLPUT(dbc, lock);
+ return (ret);
+ }
+
+ switch (TYPE(h)) {
+ case P_IBTREE:
+ for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+ bi = GET_BINTERNAL(dbp, h, indx);
+ if (B_TYPE(bi->type) == B_OVERFLOW &&
+ (ret = __db_traverse_big(dbp,
+ ((BOVERFLOW *)bi->data)->pgno,
+ callback, cookie)) != 0)
+ goto err;
+ if ((ret = __bam_traverse(
+ dbc, mode, bi->pgno, callback, cookie)) != 0)
+ goto err;
+ }
+ break;
+ case P_IRECNO:
+ for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+ ri = GET_RINTERNAL(dbp, h, indx);
+ if ((ret = __bam_traverse(
+ dbc, mode, ri->pgno, callback, cookie)) != 0)
+ goto err;
+ }
+ break;
+ case P_LBTREE:
+ inp = P_INP(dbp, h);
+ for (indx = 0; indx < NUM_ENT(h); indx += P_INDX) {
+ bk = GET_BKEYDATA(dbp, h, indx);
+ if (B_TYPE(bk->type) == B_OVERFLOW &&
+ (indx + P_INDX >= NUM_ENT(h) ||
+ inp[indx] != inp[indx + P_INDX])) {
+ if ((ret = __db_traverse_big(dbp,
+ GET_BOVERFLOW(dbp, h, indx)->pgno,
+ callback, cookie)) != 0)
+ goto err;
+ }
+ bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
+ if (B_TYPE(bk->type) == B_DUPLICATE &&
+ (ret = __bam_traverse(dbc, mode,
+ GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
+ callback, cookie)) != 0)
+ goto err;
+ if (B_TYPE(bk->type) == B_OVERFLOW &&
+ (ret = __db_traverse_big(dbp,
+ GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
+ callback, cookie)) != 0)
+ goto err;
+ }
+ break;
+ case P_LDUP:
+ case P_LRECNO:
+ for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+ bk = GET_BKEYDATA(dbp, h, indx);
+ if (B_TYPE(bk->type) == B_OVERFLOW &&
+ (ret = __db_traverse_big(dbp,
+ GET_BOVERFLOW(dbp, h, indx)->pgno,
+ callback, cookie)) != 0)
+ goto err;
+ }
+ break;
+ default:
+ return (__db_pgfmt(dbp->dbenv, h->pgno));
+ }
+
+ ret = callback(dbp, h, cookie, &already_put);
+
+err: if (!already_put && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+ ret = t_ret;
+
+ return (ret);
+}
diff --git a/db/btree/bt_upgrade.c b/db/btree/bt_upgrade.c
index 71ee84222..f89901789 100644
--- a/db/btree/bt_upgrade.c
+++ b/db/btree/bt_upgrade.c
@@ -1,15 +1,13 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: bt_upgrade.c,v 11.30 2004/01/28 03:35:49 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_upgrade.c,v 11.29 2003/05/18 18:10:11 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
diff --git a/db/btree/bt_verify.c b/db/btree/bt_verify.c
index cd8c57a4d..6b78cbd17 100644
--- a/db/btree/bt_verify.c
+++ b/db/btree/bt_verify.c
@@ -1,18 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2003
+ * Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
*
- * $Id: bt_verify.c,v 1.87 2003/10/06 14:09:23 bostic Exp $
+ * $Id: bt_verify.c,v 1.97 2004/10/11 18:47:46 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: bt_verify.c,v 1.87 2003/10/06 14:09:23 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -34,8 +30,6 @@ static int __bam_vrfy_treeorder __P((DB *, db_pgno_t, PAGE *, BINTERNAL *,
static int __ram_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
db_indx_t *, u_int32_t));
-#define OKFLAGS (DB_AGGRESSIVE | DB_NOORDERCHK | DB_SALVAGE)
-
/*
* __bam_vrfy_meta --
* Verify the btree-specific part of a metadata page.
@@ -185,6 +179,9 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags)
err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
ret = t_ret;
+ if (LF_ISSET(DB_SALVAGE) &&
+ (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
+ ret = t_ret;
return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
}
@@ -216,9 +213,6 @@ __ram_vrfy_leaf(dbp, vdp, h, pgno, flags)
if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
return (ret);
- if ((ret = __db_fchk(dbenv, "__ram_vrfy_leaf", flags, OKFLAGS)) != 0)
- goto err;
-
if (TYPE(h) != P_LRECNO) {
/* We should not have been called. */
TYPE_ERR_PRINT(dbenv, "__ram_vrfy_leaf", pgno, TYPE(h));
@@ -510,6 +504,8 @@ err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
}
+typedef enum { VRFY_ITEM_NOTSET=0, VRFY_ITEM_BEGIN, VRFY_ITEM_END } VRFY_ITEM;
+
/*
* __bam_vrfy_inp --
* Verify that all entries in inp[] array are reasonable;
@@ -528,11 +524,14 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
BOVERFLOW *bo;
DB_ENV *dbenv;
VRFY_CHILDINFO child;
+ VRFY_ITEM *pagelayout;
VRFY_PAGEINFO *pip;
- int isbad, initem, isdupitem, ret, t_ret;
- u_int32_t himark, offset; /* These would be db_indx_ts but for algnmt.*/
+ u_int32_t himark, offset; /*
+ * These would be db_indx_ts
+ * but for alignment.
+ */
u_int32_t i, endoff, nentries;
- u_int8_t *pagelayout;
+ int isbad, initem, isdupitem, ret, t_ret;
dbenv = dbp->dbenv;
isbad = isdupitem = 0;
@@ -573,9 +572,9 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
* it and the region immediately after it.
*/
himark = dbp->pgsize;
- if ((ret = __os_malloc(dbenv, dbp->pgsize, &pagelayout)) != 0)
+ if ((ret = __os_calloc(
+ dbenv, dbp->pgsize, sizeof(pagelayout[0]), &pagelayout)) != 0)
goto err;
- memset(pagelayout, 0, dbp->pgsize);
for (i = 0; i < NUM_ENT(h); i++) {
switch (ret = __db_vrfy_inpitem(dbp,
h, pgno, i, 1, flags, &himark, &offset)) {
@@ -600,11 +599,9 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
* items have no overlaps or gaps.
*/
bk = GET_BKEYDATA(dbp, h, i);
-#define ITEM_BEGIN 1
-#define ITEM_END 2
- if (pagelayout[offset] == 0)
- pagelayout[offset] = ITEM_BEGIN;
- else if (pagelayout[offset] == ITEM_BEGIN) {
+ if (pagelayout[offset] == VRFY_ITEM_NOTSET)
+ pagelayout[offset] = VRFY_ITEM_BEGIN;
+ else if (pagelayout[offset] == VRFY_ITEM_BEGIN) {
/*
* Having two inp entries that point at the same patch
* of page is legal if and only if the page is
@@ -676,12 +673,12 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
* If this is an onpage duplicate key we've seen before,
* the end had better coincide too.
*/
- if (isdupitem && pagelayout[endoff] != ITEM_END) {
+ if (isdupitem && pagelayout[endoff] != VRFY_ITEM_END) {
EPRINT((dbenv, "Page %lu: duplicated item %lu",
(u_long)pgno, (u_long)i));
isbad = 1;
- } else if (pagelayout[endoff] == 0)
- pagelayout[endoff] = ITEM_END;
+ } else if (pagelayout[endoff] == VRFY_ITEM_NOTSET)
+ pagelayout[endoff] = VRFY_ITEM_END;
isdupitem = 0;
/*
@@ -771,9 +768,9 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
for (i = himark; i < dbp->pgsize; i++)
if (initem == 0)
switch (pagelayout[i]) {
- case 0:
+ case VRFY_ITEM_NOTSET:
/* May be just for alignment. */
- if (i != ALIGN(i, sizeof(u_int32_t)))
+ if (i != DB_ALIGN(i, sizeof(u_int32_t)))
continue;
isbad = 1;
@@ -781,13 +778,13 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
"Page %lu: gap between items at offset %lu",
(u_long)pgno, (u_long)i));
/* Find the end of the gap */
- for ( ; pagelayout[i + 1] == 0 &&
+ for (; pagelayout[i + 1] == VRFY_ITEM_NOTSET &&
(size_t)(i + 1) < dbp->pgsize; i++)
;
break;
- case ITEM_BEGIN:
+ case VRFY_ITEM_BEGIN:
/* We've found an item. Check its alignment. */
- if (i != ALIGN(i, sizeof(u_int32_t))) {
+ if (i != DB_ALIGN(i, sizeof(u_int32_t))) {
isbad = 1;
EPRINT((dbenv,
"Page %lu: offset %lu unaligned",
@@ -796,7 +793,7 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
initem = 1;
nentries++;
break;
- case ITEM_END:
+ case VRFY_ITEM_END:
/*
* We've hit the end of an item even though
* we don't think we're in one; must
@@ -807,22 +804,17 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
"Page %lu: overlapping items at offset %lu",
(u_long)pgno, (u_long)i));
break;
- default:
- /* Should be impossible. */
- DB_ASSERT(0);
- ret = EINVAL;
- goto err;
}
else
switch (pagelayout[i]) {
- case 0:
+ case VRFY_ITEM_NOTSET:
/* In the middle of an item somewhere. Okay. */
break;
- case ITEM_END:
+ case VRFY_ITEM_END:
/* End of an item; switch to out-of-item mode.*/
initem = 0;
break;
- case ITEM_BEGIN:
+ case VRFY_ITEM_BEGIN:
/*
* Hit a second item beginning without an
* end. Overlap.
@@ -1401,11 +1393,11 @@ __bam_vrfy_subtree(dbp, vdp, pgno, l, r, flags, levelp, nrecsp, relenp)
* page's next_pgno, and our prev_pgno.
*/
if (pip->type != vdp->leaf_type) {
+ isbad = 1;
EPRINT((dbenv,
"Page %lu: unexpected page type %lu found in leaf chain (expected %lu)",
(u_long)pip->pgno, (u_long)pip->type,
(u_long)vdp->leaf_type));
- isbad = 1;
}
/*
@@ -1414,20 +1406,20 @@ __bam_vrfy_subtree(dbp, vdp, pgno, l, r, flags, levelp, nrecsp, relenp)
*/
if (!F_ISSET(vdp, VRFY_LEAFCHAIN_BROKEN)) {
if (pip->pgno != vdp->next_pgno) {
+ isbad = 1;
EPRINT((dbenv,
"Page %lu: incorrect next_pgno %lu found in leaf chain (should be %lu)",
(u_long)vdp->prev_pgno,
(u_long)vdp->next_pgno,
(u_long)pip->pgno));
- isbad = 1;
}
if (pip->prev_pgno != vdp->prev_pgno) {
-bad_prev: EPRINT((dbenv,
- "Page %lu: incorrect prev_pgno %lu found in leaf chain (should be %lu)",
+bad_prev: isbad = 1;
+ EPRINT((dbenv,
+ "Page %lu: incorrect prev_pgno %lu found in leaf chain (should be %lu)",
(u_long)pip->pgno,
(u_long)pip->prev_pgno,
(u_long)vdp->prev_pgno));
- isbad = 1;
}
}
}
@@ -1519,11 +1511,11 @@ bad_prev: EPRINT((dbenv,
dbp, vdp, child->pgno, NULL,
NULL, stflags | ST_TOPLEVEL,
NULL, NULL, NULL)) != 0) {
- if (ret !=
+ if (ret ==
DB_VERIFY_BAD)
- goto err;
- else
isbad = 1;
+ else
+ goto err;
}
}
}
@@ -1538,10 +1530,10 @@ bad_prev: EPRINT((dbenv,
*/
if (F_ISSET(pip, VRFY_DUPS_UNSORTED) &&
LF_ISSET(ST_DUPSORT)) {
+ isbad = 1;
EPRINT((dbenv,
"Page %lu: unsorted duplicate set in sorted-dup database",
(u_long)pgno));
- isbad = 1;
}
}
}
@@ -1602,10 +1594,10 @@ bad_prev: EPRINT((dbenv,
if ((ret = __bam_vrfy_subtree(dbp, vdp, child->pgno,
NULL, NULL, flags, &child_level, &child_nrecs,
&child_relen)) != 0) {
- if (ret != DB_VERIFY_BAD)
- goto done;
- else
+ if (ret == DB_VERIFY_BAD)
isbad = 1;
+ else
+ goto done;
}
if (LF_ISSET(ST_RELEN)) {
@@ -1662,10 +1654,10 @@ bad_prev: EPRINT((dbenv,
* shouldn't happen.
*/
if (child->refcnt > 2) {
+ isbad = 1;
EPRINT((dbenv,
"Page %lu: overflow page %lu referenced more than twice from internal page",
(u_long)pgno, (u_long)child->pgno));
- isbad = 1;
} else
for (j = 0; j < child->refcnt; j++)
if ((ret = __db_vrfy_ovfl_structure(dbp,
@@ -1701,7 +1693,7 @@ bad_prev: EPRINT((dbenv,
for (i = 0; i < pip->entries; i += O_INDX) {
li = GET_BINTERNAL(dbp, h, i);
ri = (i + O_INDX < pip->entries) ?
- GET_BINTERNAL(dbp, h, i + O_INDX) : NULL;
+ GET_BINTERNAL(dbp, h, i + O_INDX) : rp;
/*
* The leftmost key is forcibly sorted less than all entries,
@@ -1710,10 +1702,10 @@ bad_prev: EPRINT((dbenv,
if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
i == 0 ? NULL : li, ri, flags, &child_level,
&child_nrecs, NULL)) != 0) {
- if (ret != DB_VERIFY_BAD)
- goto done;
- else
+ if (ret == DB_VERIFY_BAD)
isbad = 1;
+ else
+ goto done;
}
if (LF_ISSET(ST_RECNUM)) {
@@ -1792,10 +1784,10 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) {
goto err;
if (NUM_ENT(h) == 0 && ISINTERNAL(h)) {
+ isbad = 1;
EPRINT((dbenv,
"Page %lu: internal page is empty and should not be",
(u_long)pgno));
- isbad = 1;
goto err;
}
}
@@ -1862,9 +1854,9 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) {
* PGNO_INVALID.
*/
if (vdp->next_pgno != PGNO_INVALID) {
+ isbad = 1;
EPRINT((dbenv, "Page %lu: unterminated leaf chain",
(u_long)vdp->prev_pgno));
- isbad = 1;
}
err: if (toplevel) {
@@ -1968,7 +1960,7 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags)
return (EINVAL);
}
- /* On error, fall through, free if neeeded, and return. */
+ /* On error, fall through, free if needed, and return. */
if ((ret = __bam_cmp(dbp, &dbt, h, 0, func, &cmp)) == 0) {
if (cmp > 0) {
EPRINT((dbenv,
@@ -2004,7 +1996,7 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags)
return (EINVAL);
}
- /* On error, fall through, free if neeeded, and return. */
+ /* On error, fall through, free if needed, and return. */
if ((ret = __bam_cmp(dbp, &dbt, h, last, func, &cmp)) == 0) {
if (cmp < 0) {
EPRINT((dbenv,
@@ -2049,9 +2041,9 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
DB_ENV *dbenv;
BKEYDATA *bk;
BOVERFLOW *bo;
+ VRFY_ITEM *pgmap;
db_indx_t i, beg, end, *inp;
u_int32_t himark;
- u_int8_t *pgmap;
void *ovflbuf;
int t_ret, ret, err_ret;
@@ -2078,12 +2070,9 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0)
return (ret);
- if (LF_ISSET(DB_AGGRESSIVE)) {
- if ((ret =
- __os_malloc(dbenv, dbp->pgsize, &pgmap)) != 0)
- goto err;
- memset(pgmap, 0, dbp->pgsize);
- }
+ if (LF_ISSET(DB_AGGRESSIVE) && (ret =
+ __os_calloc(dbenv, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0)
+ goto err;
/*
* Loop through the inp array, spitting out key/data pairs.
@@ -2135,7 +2124,7 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
*/
if (key != NULL &&
(i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY)))
- if ((ret = __db_prdbt(key,
+ if ((ret = __db_vrfy_prdbt(key,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
@@ -2166,7 +2155,8 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
if (!IS_VALID_PGNO(bo->pgno) ||
(i % P_INDX == 0)) {
/* Not much to do on failure. */
- if ((ret = __db_prdbt(&unkdbt, 0, " ",
+ if ((ret =
+ __db_vrfy_prdbt(&unkdbt, 0, " ",
handle, callback, 0, vdp)) != 0)
err_ret = ret;
break;
@@ -2179,11 +2169,11 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
break;
case B_KEYDATA:
- end =
- ALIGN(beg + bk->len, sizeof(u_int32_t)) - 1;
+ end = (db_indx_t)DB_ALIGN(
+ beg + bk->len, sizeof(u_int32_t)) - 1;
dbt.data = bk->data;
dbt.size = bk->len;
- if ((ret = __db_prdbt(&dbt,
+ if ((ret = __db_vrfy_prdbt(&dbt,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
break;
@@ -2194,11 +2184,11 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
bo->pgno, &dbt, &ovflbuf, flags)) != 0) {
err_ret = ret;
/* We care about err_ret more. */
- (void)__db_prdbt(&unkdbt, 0, " ",
+ (void)__db_vrfy_prdbt(&unkdbt, 0, " ",
handle, callback, 0, vdp);
break;
}
- if ((ret = __db_prdbt(&dbt,
+ if ((ret = __db_vrfy_prdbt(&dbt,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
break;
@@ -2219,8 +2209,8 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
* any bogus inp elements and thereby missed stuff.
*/
if (LF_ISSET(DB_AGGRESSIVE)) {
- pgmap[beg] = ITEM_BEGIN;
- pgmap[end] = ITEM_END;
+ pgmap[beg] = VRFY_ITEM_BEGIN;
+ pgmap[end] = VRFY_ITEM_END;
}
}
}
@@ -2230,7 +2220,7 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
* a datum; fix this imbalance by printing an "UNKNOWN".
*/
if (pgtype == P_LBTREE && (i % P_INDX == 1) && ((ret =
- __db_prdbt(&unkdbt, 0, " ", handle, callback, 0, vdp)) != 0))
+ __db_vrfy_prdbt(&unkdbt, 0, " ", handle, callback, 0, vdp)) != 0))
err_ret = ret;
err: if (pgmap != NULL)
diff --git a/db/btree/btree.src b/db/btree/btree.src
index 85faff67f..c4f761de0 100644
--- a/db/btree/btree.src
+++ b/db/btree/btree.src
@@ -1,17 +1,15 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*
- * $Id: btree.src,v 10.39 2003/11/14 05:32:34 ubell Exp $
+ * $Id: btree.src,v 10.42 2004/06/17 17:35:12 bostic Exp $
*/
PREFIX __bam
DBPRIVATE
-INCLUDE #include "db_config.h"
-INCLUDE
INCLUDE #ifndef NO_SYSTEM_INCLUDES
INCLUDE #include <sys/types.h>
INCLUDE
@@ -30,10 +28,6 @@ INCLUDE #include "dbinc/txn.h"
INCLUDE
/*
- * NOTE: pg_alloc and pg_free have been moved to db.src, where they belong.
- */
-
-/*
* BTREE-split: used to log a page split.
*
* left: the page number for the low-order contents.
@@ -208,3 +202,24 @@ ARG recno db_recno_t ld
/* Order number of the adjustment. */
ARG order u_int32_t ld
END
+
+/*
+ * BTREE-relink -- Handles relinking around a deleted leaf page.
+ *
+ */
+BEGIN relink 147
+/* Fileid of db affected. */
+DB fileid int32_t ld
+/* The page being changed. */
+ARG pgno db_pgno_t lu
+/* The page's original lsn. */
+POINTER lsn DB_LSN * lu
+/* The previous page. */
+ARG prev db_pgno_t lu
+/* The previous page's original lsn. */
+POINTER lsn_prev DB_LSN * lu
+/* The next page. */
+ARG next db_pgno_t lu
+/* The previous page's original lsn. */
+POINTER lsn_next DB_LSN * lu
+END
diff --git a/db/btree/btree_auto.c b/db/btree/btree_auto.c
index 16ebbcad9..9556e5fee 100644
--- a/db/btree/btree_auto.c
+++ b/db/btree/btree_auto.c
@@ -1,4 +1,5 @@
/* Do not edit: automatically built by gen_rec.awk. */
+
#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
@@ -43,33 +44,42 @@ __bam_split_log(dbp, txnid, ret_lsnp, flags, left, llsn, right, rlsn, indx,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_split;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -92,27 +102,23 @@ __bam_split_log(dbp, txnid, ret_lsnp, flags, left, llsn, right, rlsn, indx,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -192,141 +198,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_split_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_split_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_split_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_split_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_split_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_split_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_split_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_split%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tleft: %lu\n", (u_long)argp->left);
- (void)printf("\tllsn: [%lu][%lu]\n",
- (u_long)argp->llsn.file, (u_long)argp->llsn.offset);
- (void)printf("\tright: %lu\n", (u_long)argp->right);
- (void)printf("\trlsn: [%lu][%lu]\n",
- (u_long)argp->rlsn.file, (u_long)argp->rlsn.offset);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno);
- (void)printf("\tnlsn: [%lu][%lu]\n",
- (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset);
- (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
- (void)printf("\tpg: ");
- for (i = 0; i < argp->pg.size; i++) {
- ch = ((u_int8_t *)argp->pg.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\topflags: %lu\n", (u_long)argp->opflags);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_split_read __P((DB_ENV *, void *, __bam_split_args **));
*/
@@ -344,9 +256,9 @@ __bam_split_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_split_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -425,33 +337,42 @@ __bam_rsplit_log(dbp, txnid, ret_lsnp, flags, pgno, pgdbt, root_pgno, nrec, root
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_rsplit;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -470,27 +391,23 @@ __bam_rsplit_log(dbp, txnid, ret_lsnp, flags, pgno, pgdbt, root_pgno, nrec, root
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -557,140 +474,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_rsplit_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_rsplit_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_rsplit_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_rsplit_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_rsplit_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_rsplit_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_rsplit_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_rsplit%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tpgdbt: ");
- for (i = 0; i < argp->pgdbt.size; i++) {
- ch = ((u_int8_t *)argp->pgdbt.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
- (void)printf("\tnrec: %lu\n", (u_long)argp->nrec);
- (void)printf("\trootent: ");
- for (i = 0; i < argp->rootent.size; i++) {
- ch = ((u_int8_t *)argp->rootent.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\trootlsn: [%lu][%lu]\n",
- (u_long)argp->rootlsn.file, (u_long)argp->rootlsn.offset);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_rsplit_read __P((DB_ENV *, void *, __bam_rsplit_args **));
*/
@@ -708,9 +532,9 @@ __bam_rsplit_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_rsplit_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -775,33 +599,42 @@ __bam_adj_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, indx_copy, is_insert
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_adj;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -819,27 +652,23 @@ __bam_adj_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, indx_copy, is_insert
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -888,127 +717,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_adj_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_adj_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_adj_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_adj_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_adj_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_adj_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_adj_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_adj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\tindx_copy: %lu\n", (u_long)argp->indx_copy);
- (void)printf("\tis_insert: %lu\n", (u_long)argp->is_insert);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_adj_read __P((DB_ENV *, void *, __bam_adj_args **));
*/
@@ -1026,9 +775,9 @@ __bam_adj_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_adj_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1084,33 +833,42 @@ __bam_cadjust_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, adjust, opflags)
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_cadjust;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1128,27 +886,23 @@ __bam_cadjust_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, adjust, opflags)
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1197,127 +951,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_cadjust_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_cadjust_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_cadjust_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_cadjust_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_cadjust_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_cadjust_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_cadjust_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_cadjust%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\tadjust: %ld\n", (long)argp->adjust);
- (void)printf("\topflags: %lu\n", (u_long)argp->opflags);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_cadjust_read __P((DB_ENV *, void *,
* PUBLIC: __bam_cadjust_args **));
@@ -1336,9 +1010,9 @@ __bam_cadjust_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_cadjust_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1392,33 +1066,42 @@ __bam_cdel_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx)
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_cdel;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1434,27 +1117,23 @@ __bam_cdel_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx)
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1495,125 +1174,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_cdel_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_cdel_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_cdel_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_cdel_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_cdel_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_cdel_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_cdel_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_cdel%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_cdel_read __P((DB_ENV *, void *, __bam_cdel_args **));
*/
@@ -1631,9 +1232,9 @@ __bam_cdel_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_cdel_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1686,33 +1287,42 @@ __bam_repl_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, isdeleted, orig,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_repl;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1733,27 +1343,23 @@ __bam_repl_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, indx, isdeleted, orig,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1828,142 +1434,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_repl_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_repl_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_repl_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_repl_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_repl_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_repl_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_repl_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_repl%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\tisdeleted: %lu\n", (u_long)argp->isdeleted);
- (void)printf("\torig: ");
- for (i = 0; i < argp->orig.size; i++) {
- ch = ((u_int8_t *)argp->orig.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\trepl: ");
- for (i = 0; i < argp->repl.size; i++) {
- ch = ((u_int8_t *)argp->repl.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tprefix: %lu\n", (u_long)argp->prefix);
- (void)printf("\tsuffix: %lu\n", (u_long)argp->suffix);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_repl_read __P((DB_ENV *, void *, __bam_repl_args **));
*/
@@ -1981,9 +1492,9 @@ __bam_repl_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_repl_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2053,33 +1564,42 @@ __bam_root_log(dbp, txnid, ret_lsnp, flags, meta_pgno, root_pgno, meta_lsn)
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_root;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2095,27 +1615,23 @@ __bam_root_log(dbp, txnid, ret_lsnp, flags, meta_pgno, root_pgno, meta_lsn)
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2156,125 +1672,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_root_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_root_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_root_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_root_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_root_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_root_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_root_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_root%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno);
- (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
- (void)printf("\tmeta_lsn: [%lu][%lu]\n",
- (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_root_read __P((DB_ENV *, void *, __bam_root_args **));
*/
@@ -2292,9 +1730,9 @@ __bam_root_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_root_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2346,33 +1784,42 @@ __bam_curadj_log(dbp, txnid, ret_lsnp, flags, mode, from_pgno, to_pgno, left_pgn
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_curadj;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2392,27 +1839,23 @@ __bam_curadj_log(dbp, txnid, ret_lsnp, flags, mode, from_pgno, to_pgno, left_pgn
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2467,128 +1910,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_curadj_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_curadj_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_curadj_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_curadj_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_curadj_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_curadj_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_curadj_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_curadj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tmode: %ld\n", (long)argp->mode);
- (void)printf("\tfrom_pgno: %lu\n", (u_long)argp->from_pgno);
- (void)printf("\tto_pgno: %lu\n", (u_long)argp->to_pgno);
- (void)printf("\tleft_pgno: %lu\n", (u_long)argp->left_pgno);
- (void)printf("\tfirst_indx: %lu\n", (u_long)argp->first_indx);
- (void)printf("\tfrom_indx: %lu\n", (u_long)argp->from_indx);
- (void)printf("\tto_indx: %lu\n", (u_long)argp->to_indx);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_curadj_read __P((DB_ENV *, void *, __bam_curadj_args **));
*/
@@ -2606,9 +1968,9 @@ __bam_curadj_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_curadj_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2672,33 +2034,42 @@ __bam_rcuradj_log(dbp, txnid, ret_lsnp, flags, mode, root, recno, order)
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___bam_rcuradj;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2715,27 +2086,23 @@ __bam_rcuradj_log(dbp, txnid, ret_lsnp, flags, mode, root, recno, order)
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2778,125 +2145,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__bam_rcuradj_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __bam_rcuradj_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_rcuradj_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __bam_rcuradj_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__bam_rcuradj_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __bam_rcuradj_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __bam_rcuradj_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__bam_rcuradj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tmode: %ld\n", (long)argp->mode);
- (void)printf("\troot: %ld\n", (long)argp->root);
- (void)printf("\trecno: %ld\n", (long)argp->recno);
- (void)printf("\torder: %ld\n", (long)argp->order);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __bam_rcuradj_read __P((DB_ENV *, void *,
* PUBLIC: __bam_rcuradj_args **));
@@ -2915,9 +2204,9 @@ __bam_rcuradj_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__bam_rcuradj_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2952,90 +2241,252 @@ __bam_rcuradj_read(dbenv, recbuf, argpp)
}
/*
- * PUBLIC: int __bam_init_print __P((DB_ENV *, int (***)(DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
+ * PUBLIC: int __bam_relink_log __P((DB *, DB_TXN *, DB_LSN *,
+ * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t,
+ * PUBLIC: DB_LSN *));
*/
int
-__bam_init_print(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
+__bam_relink_log(dbp, txnid, ret_lsnp, flags, pgno, lsn, prev, lsn_prev, next,
+ lsn_next)
+ DB *dbp;
+ DB_TXN *txnid;
+ DB_LSN *ret_lsnp;
+ u_int32_t flags;
+ db_pgno_t pgno;
+ DB_LSN * lsn;
+ db_pgno_t prev;
+ DB_LSN * lsn_prev;
+ db_pgno_t next;
+ DB_LSN * lsn_next;
{
- int ret;
+ DBT logrec;
+ DB_ENV *dbenv;
+ DB_TXNLOGREC *lr;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
+ u_int32_t uinttmp, rectype, txn_num;
+ u_int npad;
+ u_int8_t *bp;
+ int is_durable, ret;
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_split_print, DB___bam_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_rsplit_print, DB___bam_rsplit)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_adj_print, DB___bam_adj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_cadjust_print, DB___bam_cadjust)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_cdel_print, DB___bam_cdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_repl_print, DB___bam_repl)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_root_print, DB___bam_root)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_curadj_print, DB___bam_curadj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_rcuradj_print, DB___bam_rcuradj)) != 0)
+ dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
+ rectype = DB___bam_relink;
+ npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
+
+ if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
+ F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
+ is_durable = 0;
+ } else
+ is_durable = 1;
+
+ if (txnid == NULL) {
+ txn_num = 0;
+ lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
+ } else {
+ if (TAILQ_FIRST(&txnid->kids) != NULL &&
+ (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
+ return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
+ txn_num = txnid->txnid;
+ lsnp = &txnid->last_lsn;
+ }
+
+ logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
+ + sizeof(u_int32_t)
+ + sizeof(u_int32_t)
+ + sizeof(*lsn)
+ + sizeof(u_int32_t)
+ + sizeof(*lsn_prev)
+ + sizeof(u_int32_t)
+ + sizeof(*lsn_next);
+ if (CRYPTO_ON(dbenv)) {
+ npad =
+ ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
+ logrec.size += npad;
+ }
+
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
+ if ((ret = __os_malloc(dbenv,
+ logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
+ return (ret);
+#ifdef DIAGNOSTIC
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
+ __os_free(dbenv, lr);
+ return (ret);
+ }
+#else
+ logrec.data = lr->data;
+#endif
+ }
+ if (npad > 0)
+ memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
+
+ 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);
+
+ DB_ASSERT(dbp->log_filename != NULL);
+ if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
+ (ret = __dbreg_lazy_id(dbp)) != 0)
return (ret);
- return (0);
+
+ uinttmp = (u_int32_t)dbp->log_filename->id;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
+ uinttmp = (u_int32_t)pgno;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
+ if (lsn != NULL)
+ memcpy(bp, lsn, sizeof(*lsn));
+ else
+ memset(bp, 0, sizeof(*lsn));
+ bp += sizeof(*lsn);
+
+ uinttmp = (u_int32_t)prev;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
+ if (lsn_prev != NULL)
+ memcpy(bp, lsn_prev, sizeof(*lsn_prev));
+ else
+ memset(bp, 0, sizeof(*lsn_prev));
+ bp += sizeof(*lsn_prev);
+
+ uinttmp = (u_int32_t)next;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
+ if (lsn_next != NULL)
+ memcpy(bp, lsn_next, sizeof(*lsn_next));
+ else
+ memset(bp, 0, sizeof(*lsn_next));
+ bp += sizeof(*lsn_next);
+
+ DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
+#ifdef DIAGNOSTIC
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
+ */
+ memcpy(lr->data, logrec.data, logrec.size);
+ rectype |= DB_debug_FLAG;
+ memcpy(logrec.data, &rectype, sizeof(rectype));
+
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
+ ret = 0;
+#endif
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
+ }
+
+#ifdef LOG_DIAGNOSTIC
+ if (ret != 0)
+ (void)__bam_relink_print(dbenv,
+ (DBT *)&logrec, ret_lsnp, NULL, NULL);
+#endif
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
+ if (is_durable || txnid == NULL)
+ __os_free(dbenv, logrec.data);
+#endif
+ return (ret);
}
-#ifdef HAVE_REPLICATION
/*
- * PUBLIC: int __bam_init_getpgnos __P((DB_ENV *, int (***)(DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
+ * PUBLIC: int __bam_relink_read __P((DB_ENV *, void *, __bam_relink_args **));
*/
int
-__bam_init_getpgnos(dbenv, dtabp, dtabsizep)
+__bam_relink_read(dbenv, recbuf, argpp)
DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
+ void *recbuf;
+ __bam_relink_args **argpp;
{
+ __bam_relink_args *argp;
+ u_int32_t uinttmp;
+ u_int8_t *bp;
int ret;
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_split_getpgnos, DB___bam_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_rsplit_getpgnos, DB___bam_rsplit)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_adj_getpgnos, DB___bam_adj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_cadjust_getpgnos, DB___bam_cadjust)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_cdel_getpgnos, DB___bam_cdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_repl_getpgnos, DB___bam_repl)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_root_getpgnos, DB___bam_root)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_curadj_getpgnos, DB___bam_curadj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __bam_rcuradj_getpgnos, DB___bam_rcuradj)) != 0)
+ if ((ret = __os_malloc(dbenv,
+ sizeof(__bam_relink_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
+ argp->txnid = (DB_TXN *)&argp[1];
+
+ 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(&uinttmp, bp, sizeof(uinttmp));
+ argp->fileid = (int32_t)uinttmp;
+ bp += sizeof(uinttmp);
+
+ memcpy(&uinttmp, bp, sizeof(uinttmp));
+ argp->pgno = (db_pgno_t)uinttmp;
+ bp += sizeof(uinttmp);
+
+ memcpy(&argp->lsn, bp, sizeof(argp->lsn));
+ bp += sizeof(argp->lsn);
+
+ memcpy(&uinttmp, bp, sizeof(uinttmp));
+ argp->prev = (db_pgno_t)uinttmp;
+ bp += sizeof(uinttmp);
+
+ memcpy(&argp->lsn_prev, bp, sizeof(argp->lsn_prev));
+ bp += sizeof(argp->lsn_prev);
+
+ memcpy(&uinttmp, bp, sizeof(uinttmp));
+ argp->next = (db_pgno_t)uinttmp;
+ bp += sizeof(uinttmp);
+
+ memcpy(&argp->lsn_next, bp, sizeof(argp->lsn_next));
+ bp += sizeof(argp->lsn_next);
+
+ *argpp = argp;
return (0);
}
-#endif /* HAVE_REPLICATION */
/*
* PUBLIC: int __bam_init_recover __P((DB_ENV *, int (***)(DB_ENV *,
@@ -3076,5 +2527,8 @@ __bam_init_recover(dbenv, dtabp, dtabsizep)
if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
__bam_rcuradj_recover, DB___bam_rcuradj)) != 0)
return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_relink_recover, DB___bam_relink)) != 0)
+ return (ret);
return (0);
}
diff --git a/db/btree/btree_autop.c b/db/btree/btree_autop.c
new file mode 100644
index 000000000..1db8c3be6
--- /dev/null
+++ b/db/btree/btree_autop.c
@@ -0,0 +1,514 @@
+/* Do not edit: automatically built by gen_rec.awk. */
+
+#include "db_config.h"
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_dispatch.h"
+#include "dbinc/db_am.h"
+#include "dbinc/btree.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+/*
+ * PUBLIC: int __bam_split_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_split_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_split_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_split_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_split%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tleft: %lu\n", (u_long)argp->left);
+ (void)printf("\tllsn: [%lu][%lu]\n",
+ (u_long)argp->llsn.file, (u_long)argp->llsn.offset);
+ (void)printf("\tright: %lu\n", (u_long)argp->right);
+ (void)printf("\trlsn: [%lu][%lu]\n",
+ (u_long)argp->rlsn.file, (u_long)argp->rlsn.offset);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno);
+ (void)printf("\tnlsn: [%lu][%lu]\n",
+ (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset);
+ (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
+ (void)printf("\tpg: ");
+ for (i = 0; i < argp->pg.size; i++) {
+ ch = ((u_int8_t *)argp->pg.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\topflags: %lu\n", (u_long)argp->opflags);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_rsplit_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_rsplit_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_rsplit_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_rsplit_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_rsplit%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tpgdbt: ");
+ for (i = 0; i < argp->pgdbt.size; i++) {
+ ch = ((u_int8_t *)argp->pgdbt.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
+ (void)printf("\tnrec: %lu\n", (u_long)argp->nrec);
+ (void)printf("\trootent: ");
+ for (i = 0; i < argp->rootent.size; i++) {
+ ch = ((u_int8_t *)argp->rootent.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\trootlsn: [%lu][%lu]\n",
+ (u_long)argp->rootlsn.file, (u_long)argp->rootlsn.offset);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_adj_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_adj_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_adj_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_adj_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_adj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tlsn: [%lu][%lu]\n",
+ (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\tindx_copy: %lu\n", (u_long)argp->indx_copy);
+ (void)printf("\tis_insert: %lu\n", (u_long)argp->is_insert);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_cadjust_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_cadjust_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_cadjust_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_cadjust_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_cadjust%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tlsn: [%lu][%lu]\n",
+ (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\tadjust: %ld\n", (long)argp->adjust);
+ (void)printf("\topflags: %lu\n", (u_long)argp->opflags);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_cdel_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_cdel_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_cdel_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_cdel_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_cdel%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tlsn: [%lu][%lu]\n",
+ (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_repl_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_repl_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_repl_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_repl_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_repl%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tlsn: [%lu][%lu]\n",
+ (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\tisdeleted: %lu\n", (u_long)argp->isdeleted);
+ (void)printf("\torig: ");
+ for (i = 0; i < argp->orig.size; i++) {
+ ch = ((u_int8_t *)argp->orig.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\trepl: ");
+ for (i = 0; i < argp->repl.size; i++) {
+ ch = ((u_int8_t *)argp->repl.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tprefix: %lu\n", (u_long)argp->prefix);
+ (void)printf("\tsuffix: %lu\n", (u_long)argp->suffix);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_root_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_root_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_root_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_root_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_root%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno);
+ (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno);
+ (void)printf("\tmeta_lsn: [%lu][%lu]\n",
+ (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_curadj_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_curadj_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_curadj_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_curadj_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_curadj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tmode: %ld\n", (long)argp->mode);
+ (void)printf("\tfrom_pgno: %lu\n", (u_long)argp->from_pgno);
+ (void)printf("\tto_pgno: %lu\n", (u_long)argp->to_pgno);
+ (void)printf("\tleft_pgno: %lu\n", (u_long)argp->left_pgno);
+ (void)printf("\tfirst_indx: %lu\n", (u_long)argp->first_indx);
+ (void)printf("\tfrom_indx: %lu\n", (u_long)argp->from_indx);
+ (void)printf("\tto_indx: %lu\n", (u_long)argp->to_indx);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_rcuradj_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_rcuradj_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_rcuradj_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_rcuradj_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_rcuradj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tmode: %ld\n", (long)argp->mode);
+ (void)printf("\troot: %ld\n", (long)argp->root);
+ (void)printf("\trecno: %ld\n", (long)argp->recno);
+ (void)printf("\torder: %ld\n", (long)argp->order);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_relink_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__bam_relink_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __bam_relink_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __bam_relink_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__bam_relink%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tlsn: [%lu][%lu]\n",
+ (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
+ (void)printf("\tprev: %lu\n", (u_long)argp->prev);
+ (void)printf("\tlsn_prev: [%lu][%lu]\n",
+ (u_long)argp->lsn_prev.file, (u_long)argp->lsn_prev.offset);
+ (void)printf("\tnext: %lu\n", (u_long)argp->next);
+ (void)printf("\tlsn_next: [%lu][%lu]\n",
+ (u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __bam_init_print __P((DB_ENV *, int (***)(DB_ENV *,
+ * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
+ */
+int
+__bam_init_print(dbenv, dtabp, dtabsizep)
+ DB_ENV *dbenv;
+ int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
+ size_t *dtabsizep;
+{
+ int ret;
+
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_split_print, DB___bam_split)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_rsplit_print, DB___bam_rsplit)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_adj_print, DB___bam_adj)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_cadjust_print, DB___bam_cadjust)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_cdel_print, DB___bam_cdel)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_repl_print, DB___bam_repl)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_root_print, DB___bam_root)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_curadj_print, DB___bam_curadj)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_rcuradj_print, DB___bam_rcuradj)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __bam_relink_print, DB___bam_relink)) != 0)
+ return (ret);
+ return (0);
+}