diff options
author | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
commit | d03f220fde879509cab2ac1c73b71b7efb52b737 (patch) | |
tree | 1e34bfadac0a6618d0e9a7933bad90063a785acf /db/btree | |
parent | 2dc699bfe049b9319ea3719f604d25940ff52004 (diff) | |
download | librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.gz librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.bz2 librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.zip |
... and in with the New ...
CVS patchset: 7471
CVS date: 2004/10/16 01:31:54
Diffstat (limited to 'db/btree')
-rw-r--r-- | db/btree/bt_compare.c | 18 | ||||
-rw-r--r-- | db/btree/bt_conv.c | 8 | ||||
-rw-r--r-- | db/btree/bt_curadj.c | 36 | ||||
-rw-r--r-- | db/btree/bt_cursor.c | 292 | ||||
-rw-r--r-- | db/btree/bt_delete.c | 142 | ||||
-rw-r--r-- | db/btree/bt_method.c | 60 | ||||
-rw-r--r-- | db/btree/bt_open.c | 121 | ||||
-rw-r--r-- | db/btree/bt_put.c | 8 | ||||
-rw-r--r-- | db/btree/bt_rec.c | 302 | ||||
-rw-r--r-- | db/btree/bt_reclaim.c | 8 | ||||
-rw-r--r-- | db/btree/bt_recno.c | 68 | ||||
-rw-r--r-- | db/btree/bt_rsearch.c | 58 | ||||
-rw-r--r-- | db/btree/bt_search.c | 101 | ||||
-rw-r--r-- | db/btree/bt_split.c | 75 | ||||
-rw-r--r-- | db/btree/bt_stat.c | 398 | ||||
-rw-r--r-- | db/btree/bt_upgrade.c | 8 | ||||
-rw-r--r-- | db/btree/bt_verify.c | 142 | ||||
-rw-r--r-- | db/btree/btree.src | 31 | ||||
-rw-r--r-- | db/btree/btree_auto.c | 1876 | ||||
-rw-r--r-- | db/btree/btree_autop.c | 514 |
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(©_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); +} |