diff options
Diffstat (limited to 'bdb/btree/bt_verify.c')
-rw-r--r-- | bdb/btree/bt_verify.c | 526 |
1 files changed, 338 insertions, 188 deletions
diff --git a/bdb/btree/bt_verify.c b/bdb/btree/bt_verify.c index 9f8647e7e2a..0cf8a47e476 100644 --- a/bdb/btree/bt_verify.c +++ b/bdb/btree/bt_verify.c @@ -1,16 +1,16 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2000 + * Copyright (c) 1999-2002 * Sleepycat Software. All rights reserved. * - * $Id: bt_verify.c,v 1.44 2000/12/06 19:55:44 ubell Exp $ + * $Id: bt_verify.c,v 1.76 2002/07/03 19:03:51 bostic Exp $ */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: bt_verify.c,v 1.44 2000/12/06 19:55:44 ubell Exp $"; +static const char revid[] = "$Id: bt_verify.c,v 1.76 2002/07/03 19:03:51 bostic Exp $"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -20,9 +20,9 @@ static const char revid[] = "$Id: bt_verify.c,v 1.44 2000/12/06 19:55:44 ubell E #endif #include "db_int.h" -#include "db_page.h" -#include "db_verify.h" -#include "btree.h" +#include "dbinc/db_page.h" +#include "dbinc/db_verify.h" +#include "dbinc/btree.h" static int __bam_safe_getdata __P((DB *, PAGE *, u_int32_t, int, DBT *, int *)); static int __bam_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, @@ -79,15 +79,15 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) /* avoid division by zero */ ovflsize = meta->minkey > 0 ? - B_MINKEY_TO_OVFLSIZE(meta->minkey, dbp->pgsize) : 0; + B_MINKEY_TO_OVFLSIZE(dbp, meta->minkey, dbp->pgsize) : 0; if (meta->minkey < 2 || - ovflsize > B_MINKEY_TO_OVFLSIZE(DEFMINKEYPAGE, dbp->pgsize)) { + ovflsize > B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) { pip->bt_minkey = 0; isbad = 1; EPRINT((dbp->dbenv, - "Nonsensical bt_minkey value %lu on metadata page %lu", - (u_long)meta->minkey, (u_long)pgno)); + "Page %lu: nonsensical bt_minkey value %lu on metadata page", + (u_long)pgno, (u_long)meta->minkey)); } else pip->bt_minkey = meta->minkey; @@ -103,13 +103,13 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) * of the file, then the root page had better be page 1. */ pip->root = 0; - if (meta->root == PGNO_INVALID - || meta->root == pgno || !IS_VALID_PGNO(meta->root) || + if (meta->root == PGNO_INVALID || + meta->root == pgno || !IS_VALID_PGNO(meta->root) || (pgno == PGNO_BASE_MD && meta->root != 1)) { isbad = 1; EPRINT((dbp->dbenv, - "Nonsensical root page %lu on metadata page %lu", - (u_long)meta->root, (u_long)vdp->last_pgno)); + "Page %lu: nonsensical root page %lu on metadata page", + (u_long)pgno, (u_long)meta->root)); } else pip->root = meta->root; @@ -125,7 +125,7 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) if (F_ISSET(&meta->dbmeta, BTM_DUP) && pgno == PGNO_BASE_MD) { isbad = 1; EPRINT((dbp->dbenv, - "Btree metadata page %lu has both duplicates and multiple databases", +"Page %lu: Btree metadata page has both duplicates and multiple databases", (u_long)pgno)); } F_SET(pip, VRFY_HAS_SUBDBS); @@ -139,7 +139,7 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) F_SET(pip, VRFY_HAS_RECNUMS); if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_DUPS)) { EPRINT((dbp->dbenv, - "Btree metadata page %lu illegally has both recnums and dups", + "Page %lu: Btree metadata page illegally has both recnums and dups", (u_long)pgno)); isbad = 1; } @@ -150,13 +150,13 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) } else if (F_ISSET(pip, VRFY_IS_RRECNO)) { isbad = 1; EPRINT((dbp->dbenv, - "Metadata page %lu has renumber flag set but is not recno", + "Page %lu: metadata page has renumber flag set but is not recno", (u_long)pgno)); } if (F_ISSET(pip, VRFY_IS_RECNO) && F_ISSET(pip, VRFY_HAS_DUPS)) { EPRINT((dbp->dbenv, - "Recno metadata page %lu specifies duplicates", + "Page %lu: recno metadata page specifies duplicates", (u_long)pgno)); isbad = 1; } @@ -170,8 +170,8 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) */ isbad = 1; EPRINT((dbp->dbenv, - "re_len of %lu in non-fixed-length database", - (u_long)pip->re_len)); + "Page %lu: re_len of %lu in non-fixed-length database", + (u_long)pgno, (u_long)pip->re_len)); } /* @@ -179,7 +179,8 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) * not be and may still be correct. */ -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } @@ -242,7 +243,7 @@ __ram_vrfy_leaf(dbp, vdp, h, pgno, flags) if (F_ISSET(pip, VRFY_HAS_DUPS)) { EPRINT((dbp->dbenv, - "Recno database has dups on page %lu", (u_long)pgno)); + "Page %lu: Recno database has dups", (u_long)pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -255,7 +256,7 @@ __ram_vrfy_leaf(dbp, vdp, h, pgno, flags) */ re_len_guess = 0; for (i = 0; i < NUM_ENT(h); i++) { - bk = GET_BKEYDATA(h, i); + bk = GET_BKEYDATA(dbp, h, i); /* KEYEMPTY. Go on. */ if (B_DISSET(bk->type)) continue; @@ -266,8 +267,8 @@ __ram_vrfy_leaf(dbp, vdp, h, pgno, flags) else { isbad = 1; EPRINT((dbp->dbenv, - "Nonsensical type for item %lu, page %lu", - (u_long)i, (u_long)pgno)); + "Page %lu: nonsensical type for item %lu", + (u_long)pgno, (u_long)i)); continue; } if (re_len_guess == 0) @@ -288,9 +289,10 @@ __ram_vrfy_leaf(dbp, vdp, h, pgno, flags) /* Save off record count. */ pip->rec_cnt = NUM_ENT(h); -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : 0); + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } /* @@ -362,7 +364,7 @@ __bam_vrfy(dbp, vdp, h, pgno, flags) else goto err; EPRINT((dbp->dbenv, - "item order check on page %lu unsafe: skipping", + "Page %lu: item order check unsafe: skipping", (u_long)pgno)); } else if (!LF_ISSET(DB_NOORDERCHK) && (ret = __bam_vrfy_itemorder(dbp, vdp, h, pgno, 0, 0, 0, flags)) != 0) { @@ -377,9 +379,10 @@ __bam_vrfy(dbp, vdp, h, pgno, flags) goto err; } -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : 0); + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } /* @@ -403,6 +406,7 @@ __ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) VRFY_PAGEINFO *pip; int ret, t_ret, isbad; u_int32_t himark, i, offset, nentries; + db_indx_t *inp; u_int8_t *pagelayout, *p; isbad = 0; @@ -422,30 +426,31 @@ __ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) himark = dbp->pgsize; if ((ret = - __os_malloc(dbp->dbenv, dbp->pgsize, NULL, &pagelayout)) != 0) + __os_malloc(dbp->dbenv, dbp->pgsize, &pagelayout)) != 0) goto err; memset(pagelayout, 0, dbp->pgsize); + inp = P_INP(dbp, h); for (i = 0; i < NUM_ENT(h); i++) { - if ((u_int8_t *)h->inp + i >= (u_int8_t *)h + himark) { + if ((u_int8_t *)inp + i >= (u_int8_t *)h + himark) { EPRINT((dbp->dbenv, - "Page %lu entries listing %lu overlaps data", + "Page %lu: entries listing %lu overlaps data", (u_long)pgno, (u_long)i)); ret = DB_VERIFY_BAD; goto err; } - offset = h->inp[i]; + offset = inp[i]; /* * Check that the item offset is reasonable: it points * somewhere after the inp array and before the end of the * page. */ - if (offset <= (u_int32_t)((u_int8_t *)h->inp + i - + if (offset <= (u_int32_t)((u_int8_t *)inp + i - (u_int8_t *)h) || offset > (u_int32_t)(dbp->pgsize - RINTERNAL_SIZE)) { isbad = 1; EPRINT((dbp->dbenv, - "Bad offset %lu at page %lu index %lu", - (u_long)offset, (u_long)pgno, (u_long)i)); + "Page %lu: bad offset %lu at index %lu", + (u_long)pgno, (u_long)offset, (u_long)i)); continue; } @@ -456,7 +461,7 @@ __ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) nentries++; /* Make sure this RINTERNAL is not multiply referenced. */ - ri = GET_RINTERNAL(h, i); + ri = GET_RINTERNAL(dbp, h, i); if (pagelayout[offset] == 0) { pagelayout[offset] = 1; child.pgno = ri->pgno; @@ -466,8 +471,8 @@ __ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) goto err; } else { EPRINT((dbp->dbenv, - "RINTERNAL structure at offset %lu, page %lu referenced twice", - (u_long)offset, (u_long)pgno)); + "Page %lu: RINTERNAL structure at offset %lu referenced twice", + (u_long)pgno, (u_long)offset)); isbad = 1; } } @@ -477,23 +482,25 @@ __ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) p += RINTERNAL_SIZE) if (*p != 1) { EPRINT((dbp->dbenv, - "Gap between items at offset %lu, page %lu", - (u_long)(p - pagelayout), (u_long)pgno)); + "Page %lu: gap between items at offset %lu", + (u_long)pgno, (u_long)(p - pagelayout))); isbad = 1; } if ((db_indx_t)himark != HOFFSET(h)) { - EPRINT((dbp->dbenv, "Bad HOFFSET %lu, appears to be %lu", - (u_long)(HOFFSET(h)), (u_long)himark)); + EPRINT((dbp->dbenv, + "Page %lu: bad HOFFSET %lu, appears to be %lu", + (u_long)pgno, (u_long)(HOFFSET(h)), (u_long)himark)); isbad = 1; } *nentriesp = nentries; -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; if (pagelayout != NULL) - __os_free(pagelayout, dbp->pgsize); + __os_free(dbp->dbenv, pagelayout); return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } @@ -558,22 +565,24 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) * it and the region immediately after it. */ himark = dbp->pgsize; - if ((ret = __os_malloc(dbp->dbenv, - dbp->pgsize, NULL, &pagelayout)) != 0) + if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &pagelayout)) != 0) goto err; memset(pagelayout, 0, dbp->pgsize); for (i = 0; i < NUM_ENT(h); i++) { - - ret = __db_vrfy_inpitem(dbp, - h, pgno, i, 1, flags, &himark, &offset); - if (ret == DB_VERIFY_BAD) { + switch (ret = __db_vrfy_inpitem(dbp, + h, pgno, i, 1, flags, &himark, &offset)) { + case 0: + break; + case DB_VERIFY_BAD: isbad = 1; continue; - } else if (ret == DB_VERIFY_FATAL) { + case DB_VERIFY_FATAL: isbad = 1; goto err; - } else if (ret != 0) - DB_ASSERT(0); + default: + DB_ASSERT(ret != 0); + break; + } /* * We now have a plausible beginning for the item, and we know @@ -582,7 +591,7 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) * Mark the beginning and end in pagelayout so we can make sure * items have no overlaps or gaps. */ - bk = GET_BKEYDATA(h, i); + bk = GET_BKEYDATA(dbp, h, i); #define ITEM_BEGIN 1 #define ITEM_END 2 if (pagelayout[offset] == 0) @@ -609,8 +618,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) } else { isbad = 1; EPRINT((dbp->dbenv, - "Duplicated item %lu on page %lu", - (u_long)i, (u_long)pgno)); + "Page %lu: duplicated item %lu", + (u_long)pgno, (u_long)i)); } } @@ -662,8 +671,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) */ if (isdupitem && pagelayout[endoff] != ITEM_END) { EPRINT((dbp->dbenv, - "Duplicated item %lu on page %lu", - (u_long)i, (u_long)pgno)); + "Page %lu: duplicated item %lu", + (u_long)pgno, (u_long)i)); isbad = 1; } else if (pagelayout[endoff] == 0) pagelayout[endoff] = ITEM_END; @@ -676,8 +685,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) if (B_DISSET(bk->type) && TYPE(h) != P_LRECNO) { isbad = 1; EPRINT((dbp->dbenv, - "Item %lu on page %lu marked deleted", - (u_long)i, (u_long)pgno)); + "Page %lu: item %lu marked deleted", + (u_long)pgno, (u_long)i)); } /* @@ -696,13 +705,13 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) if (TYPE(h) == P_IBTREE) { isbad = 1; EPRINT((dbp->dbenv, - "Duplicate page referenced by internal btree page %lu at item %lu", + "Page %lu: duplicate page referenced by internal btree page at item %lu", (u_long)pgno, (u_long)i)); break; } else if (TYPE(h) == P_LRECNO) { isbad = 1; EPRINT((dbp->dbenv, - "Duplicate page referenced by recno page %lu at item %lu", + "Page %lu: duplicate page referenced by recno page at item %lu", (u_long)pgno, (u_long)i)); break; } @@ -717,9 +726,9 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) if (bo->tlen > dbp->pgsize * vdp->last_pgno) { isbad = 1; EPRINT((dbp->dbenv, - "Impossible tlen %lu, item %lu, page %lu", - (u_long)bo->tlen, (u_long)i, - (u_long)pgno)); + "Page %lu: impossible tlen %lu, item %lu", + (u_long)pgno, + (u_long)bo->tlen, (u_long)i)); /* Don't save as a child. */ break; } @@ -728,8 +737,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) bo->pgno == PGNO_INVALID) { isbad = 1; EPRINT((dbp->dbenv, - "Offpage item %lu, page %lu has bad pgno", - (u_long)i, (u_long)pgno)); + "Page %lu: offpage item %lu has bad pgno %lu", + (u_long)pgno, (u_long)i, (u_long)bo->pgno)); /* Don't save as a child. */ break; } @@ -744,8 +753,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) default: isbad = 1; EPRINT((dbp->dbenv, - "Item %lu on page %lu of invalid type %lu", - (u_long)i, (u_long)pgno)); + "Page %lu: item %lu of invalid type %lu", + (u_long)pgno, (u_long)i)); break; } } @@ -765,7 +774,7 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) isbad = 1; EPRINT((dbp->dbenv, - "Gap between items, page %lu offset %lu", + "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 && @@ -777,8 +786,8 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) if (i != ALIGN(i, sizeof(u_int32_t))) { isbad = 1; EPRINT((dbp->dbenv, - "Offset %lu page %lu unaligned", - (u_long)i, (u_long)pgno)); + "Page %lu: offset %lu unaligned", + (u_long)pgno, (u_long)i)); } initem = 1; nentries++; @@ -791,7 +800,7 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) */ isbad = 1; EPRINT((dbp->dbenv, - "Overlapping items, page %lu offset %lu", + "Page %lu: overlapping items at offset %lu", (u_long)pgno, (u_long)i)); break; default: @@ -816,24 +825,26 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) */ isbad = 1; EPRINT((dbp->dbenv, - "Overlapping items, page %lu offset %lu", + "Page %lu: overlapping items at offset %lu", (u_long)pgno, (u_long)i)); break; } - (void)__os_free(pagelayout, dbp->pgsize); + (void)__os_free(dbp->dbenv, pagelayout); /* Verify HOFFSET. */ if ((db_indx_t)himark != HOFFSET(h)) { - EPRINT((dbp->dbenv, "Bad HOFFSET %lu, appears to be %lu", - (u_long)HOFFSET(h), (u_long)himark)); + EPRINT((dbp->dbenv, + "Page %lu: bad HOFFSET %lu, appears to be %lu", + (u_long)pgno, (u_long)HOFFSET(h), (u_long)himark)); isbad = 1; } err: if (nentriesp != NULL) *nentriesp = nentries; - if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) + if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); @@ -865,14 +876,14 @@ __bam_vrfy_itemorder(dbp, vdp, h, pgno, nentries, ovflok, hasdups, flags) int ovflok, hasdups; u_int32_t flags; { - DBT dbta, dbtb, dup1, dup2, *p1, *p2, *tmp; + DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp; BTREE *bt; BINTERNAL *bi; BKEYDATA *bk; BOVERFLOW *bo; VRFY_PAGEINFO *pip; db_indx_t i; - int cmp, freedup1, freedup2, isbad, ret, t_ret; + int cmp, freedup_1, freedup_2, isbad, ret, t_ret; int (*dupfunc) __P((DB *, const DBT *, const DBT *)); int (*func) __P((DB *, const DBT *, const DBT *)); void *buf1, *buf2, *tmpbuf; @@ -949,7 +960,7 @@ __bam_vrfy_itemorder(dbp, vdp, h, pgno, nentries, ovflok, hasdups, flags) */ switch (TYPE(h)) { case P_IBTREE: - bi = GET_BINTERNAL(h, i); + bi = GET_BINTERNAL(dbp, h, i); if (B_TYPE(bi->type) == B_OVERFLOW) { bo = (BOVERFLOW *)(bi->data); goto overflow; @@ -972,14 +983,14 @@ __bam_vrfy_itemorder(dbp, vdp, h, pgno, nentries, ovflok, hasdups, flags) if (i == 0 && bi->len != 0) { isbad = 1; EPRINT((dbp->dbenv, - "Lowest key on internal page %lu of nonzero length", + "Page %lu: lowest key on internal page of nonzero length", (u_long)pgno)); } #endif break; case P_LBTREE: case P_LDUP: - bk = GET_BKEYDATA(h, i); + bk = GET_BKEYDATA(dbp, h, i); if (B_TYPE(bk->type) == B_OVERFLOW) { bo = (BOVERFLOW *)bk; goto overflow; @@ -1030,8 +1041,8 @@ overflow: if (!ovflok) { p2, bo->tlen, bo->pgno, NULL, NULL)) != 0) { isbad = 1; EPRINT((dbp->dbenv, - "Error %lu in fetching overflow item %lu, page %lu", - (u_long)ret, (u_long)i, (u_long)pgno)); + "Page %lu: error %lu in fetching overflow item %lu", + (u_long)pgno, (u_long)ret, (u_long)i)); } /* In case it got realloc'ed and thus changed. */ buf2 = p2->data; @@ -1045,7 +1056,7 @@ overflow: if (!ovflok) { if (cmp > 0) { isbad = 1; EPRINT((dbp->dbenv, - "Out-of-order key, page %lu item %lu", + "Page %lu: out-of-order key at entry %lu", (u_long)pgno, (u_long)i)); /* proceed */ } else if (cmp == 0) { @@ -1060,7 +1071,7 @@ overflow: if (!ovflok) { else if (hasdups == 0) { isbad = 1; EPRINT((dbp->dbenv, - "Database with no duplicates has duplicated keys on page %lu", + "Page %lu: database with no duplicates has duplicated keys", (u_long)pgno)); } @@ -1092,11 +1103,11 @@ overflow: if (!ovflok) { * dups are probably (?) rare. */ if (((ret = __bam_safe_getdata(dbp, - h, i - 1, ovflok, &dup1, - &freedup1)) != 0) || + h, i - 1, ovflok, &dup_1, + &freedup_1)) != 0) || ((ret = __bam_safe_getdata(dbp, - h, i + 1, ovflok, &dup2, - &freedup2)) != 0)) + h, i + 1, ovflok, &dup_2, + &freedup_2)) != 0)) goto err; /* @@ -1105,8 +1116,8 @@ overflow: if (!ovflok) { * it's not safe to chase them now. * Mark an incomplete and return. */ - if (dup1.data == NULL || - dup2.data == NULL) { + if (dup_1.data == NULL || + dup_2.data == NULL) { DB_ASSERT(!ovflok); F_SET(pip, VRFY_INCOMPLETE); goto err; @@ -1118,26 +1129,28 @@ overflow: if (!ovflok) { * until we do the structure check * and see whether DUPSORT is set. */ - if (dupfunc(dbp, &dup1, &dup2) > 0) + if (dupfunc(dbp, &dup_1, &dup_2) > 0) F_SET(pip, VRFY_DUPS_UNSORTED); - if (freedup1) - __os_free(dup1.data, 0); - if (freedup2) - __os_free(dup2.data, 0); + if (freedup_1) + __os_ufree(dbp->dbenv, + dup_1.data); + if (freedup_2) + __os_ufree(dbp->dbenv, + dup_2.data); } } } } -err: if (pip != NULL && - ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0) && ret == 0) +err: if (pip != NULL && ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) && ret == 0) ret = t_ret; if (buf1 != NULL) - __os_free(buf1, 0); + __os_ufree(dbp->dbenv, buf1); if (buf2 != NULL) - __os_free(buf2, 0); + __os_ufree(dbp->dbenv, buf2); return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } @@ -1173,7 +1186,7 @@ __bam_vrfy_structure(dbp, vdp, meta_pgno, flags) goto err; if (p != 0) { EPRINT((dbp->dbenv, - "Btree metadata page number %lu observed twice", + "Page %lu: btree metadata page observed twice", (u_long)meta_pgno)); ret = DB_VERIFY_BAD; goto err; @@ -1185,7 +1198,8 @@ __bam_vrfy_structure(dbp, vdp, meta_pgno, flags) if (root == 0) { EPRINT((dbp->dbenv, - "Btree metadata page %lu has no root", (u_long)meta_pgno)); + "Page %lu: btree metadata page has no root", + (u_long)meta_pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -1222,7 +1236,7 @@ __bam_vrfy_structure(dbp, vdp, meta_pgno, flags) */ if (mip->re_len > 0 && relen > 0 && mip->re_len != relen) { EPRINT((dbp->dbenv, - "Recno database with meta page %lu has bad re_len %lu", + "Page %lu: recno database has bad re_len %lu", (u_long)meta_pgno, (u_long)relen)); ret = DB_VERIFY_BAD; goto err; @@ -1231,24 +1245,24 @@ __bam_vrfy_structure(dbp, vdp, meta_pgno, flags) break; case P_LDUP: EPRINT((dbp->dbenv, - "Duplicate tree referenced from metadata page %lu", + "Page %lu: duplicate tree referenced from metadata page", (u_long)meta_pgno)); ret = DB_VERIFY_BAD; break; default: EPRINT((dbp->dbenv, - "Btree root of incorrect type %lu on meta page %lu", - (u_long)rip->type, (u_long)meta_pgno)); + "Page %lu: btree root of incorrect type %lu on metadata page", + (u_long)meta_pgno, (u_long)rip->type)); ret = DB_VERIFY_BAD; break; } -err: if (mip != NULL && - ((t_ret = __db_vrfy_putpageinfo(vdp, mip)) != 0) && ret == 0) - t_ret = ret; - if (rip != NULL && - ((t_ret = __db_vrfy_putpageinfo(vdp, rip)) != 0) && ret == 0) - t_ret = ret; +err: if (mip != NULL && ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, mip)) != 0) && ret == 0) + ret = t_ret; + if (rip != NULL && ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, rip)) != 0) && ret == 0) + ret = t_ret; return (ret); } @@ -1273,20 +1287,26 @@ __bam_vrfy_subtree(dbp, { BINTERNAL *li, *ri, *lp, *rp; DB *pgset; + DB_MPOOLFILE *mpf; DBC *cc; PAGE *h; VRFY_CHILDINFO *child; VRFY_PAGEINFO *pip; - db_recno_t nrecs, child_nrecs; db_indx_t i; - int ret, t_ret, isbad, toplevel, p; + db_pgno_t next_pgno, prev_pgno; + db_recno_t child_nrecs, nrecs; + u_int32_t child_level, child_relen, level, relen, stflags; + u_int8_t leaf_type; int (*func) __P((DB *, const DBT *, const DBT *)); - u_int32_t level, child_level, stflags, child_relen, relen; + int isbad, p, ret, t_ret, toplevel; + mpf = dbp->mpf; ret = isbad = 0; nrecs = 0; h = NULL; relen = 0; + leaf_type = P_INVALID; + next_pgno = prev_pgno = PGNO_INVALID; rp = (BINTERNAL *)r; lp = (BINTERNAL *)l; @@ -1300,10 +1320,33 @@ __bam_vrfy_subtree(dbp, cc = NULL; level = pip->bt_level; - toplevel = LF_ISSET(ST_TOPLEVEL); + toplevel = LF_ISSET(ST_TOPLEVEL) ? 1 : 0; LF_CLR(ST_TOPLEVEL); /* + * If this is the root, initialize the vdp's prev- and next-pgno + * accounting. + * + * For each leaf page we hit, we'll want to make sure that + * vdp->prev_pgno is the same as pip->prev_pgno and vdp->next_pgno is + * our page number. Then, we'll set vdp->next_pgno to pip->next_pgno + * and vdp->prev_pgno to our page number, and the next leaf page in + * line should be able to do the same verification. + */ + if (toplevel) { + /* + * Cache the values stored in the vdp so that if we're an + * auxiliary tree such as an off-page duplicate set, our + * caller's leaf page chain doesn't get lost. + */ + prev_pgno = vdp->prev_pgno; + next_pgno = vdp->next_pgno; + leaf_type = vdp->leaf_type; + vdp->next_pgno = vdp->prev_pgno = PGNO_INVALID; + vdp->leaf_type = P_INVALID; + } + + /* * We are recursively descending a btree, starting from the root * and working our way out to the leaves. * @@ -1333,8 +1376,53 @@ __bam_vrfy_subtree(dbp, case P_LDUP: case P_LBTREE: /* - * Cases 1, 2 and 3 (overflow pages are common to all three); - * traverse child list, looking for overflows. + * Cases 1, 2 and 3. + * + * We're some sort of leaf page; verify + * that our linked list of leaves is consistent. + */ + if (vdp->leaf_type == P_INVALID) { + /* + * First leaf page. Set the type that all its + * successors should be, and verify that our prev_pgno + * is PGNO_INVALID. + */ + vdp->leaf_type = pip->type; + if (pip->prev_pgno != PGNO_INVALID) + goto bad_prev; + } else { + /* + * Successor leaf page. Check our type, the previous + * page's next_pgno, and our prev_pgno. + */ + if (pip->type != vdp->leaf_type) { + EPRINT((dbp->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; + } + if (pip->pgno != vdp->next_pgno) { + EPRINT((dbp->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((dbp->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; + } + } + vdp->prev_pgno = pip->pgno; + vdp->next_pgno = pip->next_pgno; + + /* + * Overflow pages are common to all three leaf types; + * traverse the child list, looking for overflows. */ if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) goto err; @@ -1360,7 +1448,7 @@ __bam_vrfy_subtree(dbp, !(LF_ISSET(ST_DUPOK) && !LF_ISSET(ST_DUPSORT))) { isbad = 1; EPRINT((dbp->dbenv, - "Recno leaf page %lu in non-recno tree", + "Page %lu: recno leaf page non-recno tree", (u_long)pgno)); goto done; } @@ -1372,7 +1460,7 @@ __bam_vrfy_subtree(dbp, */ isbad = 1; EPRINT((dbp->dbenv, - "Non-recno leaf page %lu in recno tree", + "Page %lu: non-recno leaf page in recno tree", (u_long)pgno)); goto done; } @@ -1389,7 +1477,7 @@ __bam_vrfy_subtree(dbp, if (!LF_ISSET(ST_DUPOK)) { isbad = 1; EPRINT((dbp->dbenv, - "Duplicates on page %lu in non-dup btree", + "Page %lu: duplicates in non-dup btree", (u_long)pgno)); } else { /* @@ -1414,8 +1502,8 @@ __bam_vrfy_subtree(dbp, } if ((ret = __bam_vrfy_subtree( dbp, vdp, child->pgno, NULL, - NULL, stflags, NULL, NULL, - NULL)) != 0) { + NULL, stflags | ST_TOPLEVEL, + NULL, NULL, NULL)) != 0) { if (ret != DB_VERIFY_BAD) goto err; @@ -1436,14 +1524,13 @@ __bam_vrfy_subtree(dbp, if (F_ISSET(pip, VRFY_DUPS_UNSORTED) && LF_ISSET(ST_DUPSORT)) { EPRINT((dbp->dbenv, - "Unsorted duplicate set at page %lu in sorted-dup database", + "Page %lu: unsorted duplicate set in sorted-dup database", (u_long)pgno)); isbad = 1; } } } goto leaf; - break; case P_IBTREE: case P_IRECNO: /* We handle these below. */ @@ -1455,10 +1542,18 @@ __bam_vrfy_subtree(dbp, * Note that the code at the "done" label assumes that the * current page is a btree/recno one of some sort; this * is not the case here, so we goto err. + * + * If the page is entirely zeroed, its pip->type will be a lie + * (we assumed it was a hash page, as they're allowed to be + * zeroed); handle this case specially. */ - EPRINT((dbp->dbenv, - "Page %lu is of inappropriate type %lu", - (u_long)pgno, (u_long)pip->type)); + if (F_ISSET(pip, VRFY_IS_ALLZEROES)) + ZEROPG_ERR_PRINT(dbp->dbenv, + pgno, "btree or recno page"); + else + EPRINT((dbp->dbenv, + "Page %lu: btree or recno page is of inappropriate type %lu", + (u_long)pgno, (u_long)pip->type)); ret = DB_VERIFY_BAD; goto err; } @@ -1500,8 +1595,9 @@ __bam_vrfy_subtree(dbp, relen != child_relen) { isbad = 1; EPRINT((dbp->dbenv, - "Recno page %lu returned bad re_len", - (u_long)child->pgno)); + "Page %lu: recno page returned bad re_len %lu", + (u_long)child->pgno, + (u_long)child_relen)); } if (relenp) *relenp = relen; @@ -1510,10 +1606,8 @@ __bam_vrfy_subtree(dbp, nrecs += child_nrecs; if (level != child_level + 1) { isbad = 1; - EPRINT((dbp->dbenv, "%s%lu%s%lu%s%lu", - "Recno level incorrect on page ", - (u_long)child->pgno, ": got ", - (u_long)child_level, ", expected ", + EPRINT((dbp->dbenv, "Page %lu: recno level incorrect: got %lu, expected %lu", + (u_long)child->pgno, (u_long)child_level, (u_long)(level - 1))); } } else if (child->type == V_OVERFLOW && @@ -1543,12 +1637,12 @@ __bam_vrfy_subtree(dbp, * itself, which must sort lower than all entries on its child; * ri will be the key to its right, which must sort greater. */ - if (h == NULL && (ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) + if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0) goto err; for (i = 0; i < pip->entries; i += O_INDX) { - li = GET_BINTERNAL(h, i); + li = GET_BINTERNAL(dbp, h, i); ri = (i + O_INDX < pip->entries) ? - GET_BINTERNAL(h, i + O_INDX) : NULL; + GET_BINTERNAL(dbp, h, i + O_INDX) : NULL; /* * The leftmost key is forcibly sorted less than all entries, @@ -1578,18 +1672,18 @@ __bam_vrfy_subtree(dbp, if (li->nrecs != child_nrecs) { isbad = 1; EPRINT((dbp->dbenv, - "Item %lu page %lu has incorrect record count of %lu, should be %lu", - (u_long)i, (u_long)pgno, (u_long)li->nrecs, + "Page %lu: item %lu has incorrect record count of %lu, should be %lu", + (u_long)pgno, (u_long)i, (u_long)li->nrecs, (u_long)child_nrecs)); } } if (level != child_level + 1) { isbad = 1; - EPRINT((dbp->dbenv, "%s%lu%s%lu%s%lu", - "Btree level incorrect on page ", (u_long)li->pgno, - ": got ", (u_long)child_level, ", expected ", - (u_long)(level - 1))); + EPRINT((dbp->dbenv, + "Page %lu: Btree level incorrect: got %lu, expected %lu", + (u_long)li->pgno, + (u_long)child_level, (u_long)(level - 1))); } } @@ -1616,7 +1710,7 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { * isbad == 0, though, it's now safe to do so, as we've * traversed any child overflow pages. Do it. */ - if (h == NULL && (ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) + if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0) goto err; if ((ret = __bam_vrfy_itemorder(dbp, vdp, h, pgno, 0, 1, 0, flags)) != 0) @@ -1625,12 +1719,35 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { } /* + * It's possible to get to this point with a page that has no + * items, but without having detected any sort of failure yet. + * Having zero items is legal if it's a leaf--it may be the + * root page in an empty tree, or the tree may have been + * modified with the DB_REVSPLITOFF flag set (there's no way + * to tell from what's on disk). For an internal page, + * though, having no items is a problem (all internal pages + * must have children). + */ + if (isbad == 0 && ret == 0) { + if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0) + goto err; + + if (NUM_ENT(h) == 0 && ISINTERNAL(h)) { + EPRINT((dbp->dbenv, + "Page %lu: internal page is empty and should not be", + (u_long)pgno)); + isbad = 1; + goto err; + } + } + + /* * Our parent has sent us BINTERNAL pointers to parent records * so that we can verify our place with respect to them. If it's * appropriate--we have a default sort function--verify this. */ if (isbad == 0 && ret == 0 && !LF_ISSET(DB_NOORDERCHK) && lp != NULL) { - if (h == NULL && (ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) + if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0) goto err; /* @@ -1662,7 +1779,7 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { if (LF_ISSET(ST_RECNUM) && nrecs != pip->rec_cnt && toplevel) { isbad = 1; EPRINT((dbp->dbenv, - "Bad record count on page %lu: got %lu, expected %lu", + "Page %lu: bad record count: has %lu records, claims %lu", (u_long)pgno, (u_long)nrecs, (u_long)pip->rec_cnt)); } @@ -1676,13 +1793,32 @@ done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { goto err; if (p != 0) { isbad = 1; - EPRINT((dbp->dbenv, "Page %lu linked twice", (u_long)pgno)); + EPRINT((dbp->dbenv, "Page %lu: linked twice", (u_long)pgno)); } else if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0) goto err; -err: if (h != NULL && (t_ret = memp_fput(dbp->mpf, h, 0)) != 0 && ret == 0) + if (toplevel) + /* + * The last page's next_pgno in the leaf chain should have been + * PGNO_INVALID. + */ + if (vdp->next_pgno != PGNO_INVALID) { + EPRINT((dbp->dbenv, "Page %lu: unterminated leaf chain", + (u_long)vdp->prev_pgno)); + isbad = 1; + } + +err: if (toplevel) { + /* Restore our caller's settings. */ + vdp->next_pgno = next_pgno; + vdp->prev_pgno = prev_pgno; + vdp->leaf_type = leaf_type; + } + + if (h != NULL && (t_ret = mpf->put(mpf, h, 0)) != 0 && ret == 0) ret = t_ret; - if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) + if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0) ret = t_ret; @@ -1720,6 +1856,14 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) F_SET(&dbt, DB_DBT_MALLOC); ret = 0; + /* + * Empty pages are sorted correctly by definition. We check + * to see whether they ought to be empty elsewhere; leaf + * pages legally may be. + */ + if (NUM_ENT(h) == 0) + return (0); + switch (TYPE(h)) { case P_IBTREE: case P_LDUP: @@ -1760,7 +1904,8 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) } else { DB_ASSERT(0); EPRINT((dbp->dbenv, - "Unknown type for internal record")); + "Page %lu: unknown type for internal record", + (u_long)PGNO(h))); return (EINVAL); } @@ -1768,17 +1913,17 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) if ((ret = __bam_cmp(dbp, &dbt, h, 0, func, &cmp)) == 0) { if (cmp > 0) { EPRINT((dbp->dbenv, - "First item on page %lu sorted greater than parent entry", + "Page %lu: first item on page sorted greater than parent entry", (u_long)PGNO(h))); ret = DB_VERIFY_BAD; } } else EPRINT((dbp->dbenv, - "First item on page %lu had comparison error", + "Page %lu: first item on page had comparison error", (u_long)PGNO(h))); if (dbt.data != lp->data) - __os_free(dbt.data, 0); + __os_ufree(dbp->dbenv, dbt.data); if (ret != 0) return (ret); } @@ -1795,7 +1940,8 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) } else { DB_ASSERT(0); EPRINT((dbp->dbenv, - "Unknown type for internal record")); + "Page %lu: unknown type for internal record", + (u_long)PGNO(h))); return (EINVAL); } @@ -1803,17 +1949,17 @@ __bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) if ((ret = __bam_cmp(dbp, &dbt, h, last, func, &cmp)) == 0) { if (cmp < 0) { EPRINT((dbp->dbenv, - "Last item on page %lu sorted greater than parent entry", + "Page %lu: last item on page sorted greater than parent entry", (u_long)PGNO(h))); ret = DB_VERIFY_BAD; } } else EPRINT((dbp->dbenv, - "Last item on page %lu had comparison error", + "Page %lu: last item on page had comparison error", (u_long)PGNO(h))); if (dbt.data != rp->data) - __os_free(dbt.data, 0); + __os_ufree(dbp->dbenv, dbt.data); } return (ret); @@ -1843,7 +1989,7 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) DBT dbt, unkdbt; BKEYDATA *bk; BOVERFLOW *bo; - db_indx_t i, beg, end; + db_indx_t i, beg, end, *inp; u_int32_t himark; u_int8_t *pgmap; void *ovflbuf; @@ -1854,24 +2000,25 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) ovflbuf = pgmap = NULL; err_ret = ret = 0; + inp = P_INP(dbp, h); memset(&dbt, 0, sizeof(DBT)); dbt.flags = DB_DBT_REALLOC; memset(&unkdbt, 0, sizeof(DBT)); - unkdbt.size = strlen("UNKNOWN") + 1; + unkdbt.size = (u_int32_t)(strlen("UNKNOWN") + 1); unkdbt.data = "UNKNOWN"; /* * Allocate a buffer for overflow items. Start at one page; * __db_safe_goff will realloc as needed. */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, NULL, &ovflbuf)) != 0) + if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &ovflbuf)) != 0) return (ret); if (LF_ISSET(DB_AGGRESSIVE)) { if ((ret = - __os_malloc(dbp->dbenv, dbp->pgsize, NULL, &pgmap)) != 0) + __os_malloc(dbp->dbenv, dbp->pgsize, &pgmap)) != 0) goto err; memset(pgmap, 0, dbp->pgsize); } @@ -1914,7 +2061,7 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) * We only want to print deleted items if * DB_AGGRESSIVE is set. */ - bk = GET_BKEYDATA(h, i); + bk = GET_BKEYDATA(dbp, h, i); if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type)) continue; @@ -1927,10 +2074,10 @@ __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, - 0, " ", handle, callback, 0, NULL)) != 0) + 0, " ", handle, callback, 0, vdp)) != 0) err_ret = ret; - beg = h->inp[i]; + beg = inp[i]; switch (B_TYPE(bk->type)) { case B_DUPLICATE: end = beg + BOVERFLOW_SIZE - 1; @@ -1958,23 +2105,24 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) (i % P_INDX == 0)) { /* Not much to do on failure. */ if ((ret = __db_prdbt(&unkdbt, 0, " ", - handle, callback, 0, NULL)) != 0) + handle, callback, 0, vdp)) != 0) err_ret = ret; break; } if ((ret = __db_salvage_duptree(dbp, vdp, bo->pgno, &dbt, handle, callback, - flags | SA_SKIPFIRSTKEY)) != 0) + flags | SA_SKIPFIRSTKEY)) != 0) err_ret = ret; break; case B_KEYDATA: - end = ALIGN(beg + bk->len, sizeof(u_int32_t)) - 1; + end = + ALIGN(beg + bk->len, sizeof(u_int32_t)) - 1; dbt.data = bk->data; dbt.size = bk->len; if ((ret = __db_prdbt(&dbt, - 0, " ", handle, callback, 0, NULL)) != 0) + 0, " ", handle, callback, 0, vdp)) != 0) err_ret = ret; break; case B_OVERFLOW: @@ -1985,11 +2133,11 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) err_ret = ret; /* We care about err_ret more. */ (void)__db_prdbt(&unkdbt, 0, " ", - handle, callback, 0, NULL); + handle, callback, 0, vdp); break; } if ((ret = __db_prdbt(&dbt, - 0, " ", handle, callback, 0, NULL)) != 0) + 0, " ", handle, callback, 0, vdp)) != 0) err_ret = ret; break; default: @@ -2020,12 +2168,12 @@ __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, NULL)) != 0)) + __db_prdbt(&unkdbt, 0, " ", handle, callback, 0, vdp)) != 0)) err_ret = ret; err: if (pgmap != NULL) - __os_free(pgmap, 0); - __os_free(ovflbuf, 0); + __os_free(dbp->dbenv, pgmap); + __os_free(dbp->dbenv, ovflbuf); /* Mark this page as done. */ if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0) @@ -2061,12 +2209,13 @@ __bam_salvage_walkdupint(dbp, vdp, h, key, handle, callback, flags) for (i = 0; i < NUM_ENT(h); i++) { switch (TYPE(h)) { case P_IBTREE: - bi = GET_BINTERNAL(h, i); + bi = GET_BINTERNAL(dbp, h, i); if ((t_ret = __db_salvage_duptree(dbp, vdp, bi->pgno, key, handle, callback, flags)) != 0) ret = t_ret; + break; case P_IRECNO: - ri = GET_RINTERNAL(h, i); + ri = GET_RINTERNAL(dbp, h, i); if ((t_ret = __db_salvage_duptree(dbp, vdp, ri->pgno, key, handle, callback, flags)) != 0) ret = t_ret; @@ -2110,11 +2259,13 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) DB *pgset; { BINTERNAL *bi; + DB_MPOOLFILE *mpf; PAGE *h; RINTERNAL *ri; db_pgno_t current, p; int err_ret, ret; + mpf = dbp->mpf; h = NULL; ret = err_ret = 0; DB_ASSERT(pgset != NULL); @@ -2123,7 +2274,7 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) err_ret = DB_VERIFY_BAD; goto err; } - if ((ret = memp_fget(dbp->mpf, ¤t, 0, &h)) != 0) { + if ((ret = mpf->get(mpf, ¤t, 0, &h)) != 0) { err_ret = ret; goto err; } @@ -2137,10 +2288,10 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) goto err; } if (TYPE(h) == P_IBTREE) { - bi = GET_BINTERNAL(h, 0); + bi = GET_BINTERNAL(dbp, h, 0); current = bi->pgno; } else { /* P_IRECNO */ - ri = GET_RINTERNAL(h, 0); + ri = GET_RINTERNAL(dbp, h, 0); current = ri->pgno; } break; @@ -2152,7 +2303,7 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) goto err; } - if ((ret = memp_fput(dbp->mpf, h, 0)) != 0) + if ((ret = mpf->put(mpf, h, 0)) != 0) err_ret = ret; h = NULL; } @@ -2163,8 +2314,7 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) */ traverse: while (IS_VALID_PGNO(current) && current != PGNO_INVALID) { - if (h == NULL && - (ret = memp_fget(dbp->mpf, ¤t, 0, &h) != 0)) { + if (h == NULL && (ret = mpf->get(mpf, ¤t, 0, &h)) != 0) { err_ret = ret; break; } @@ -2184,13 +2334,13 @@ traverse: goto err; current = NEXT_PGNO(h); - if ((ret = memp_fput(dbp->mpf, h, 0)) != 0) + if ((ret = mpf->put(mpf, h, 0)) != 0) err_ret = ret; h = NULL; } err: if (h != NULL) - (void)memp_fput(dbp->mpf, h, 0); + (void)mpf->put(mpf, h, 0); return (ret == 0 ? err_ret : ret); } @@ -2218,7 +2368,7 @@ __bam_safe_getdata(dbp, h, i, ovflok, dbt, freedbtp) memset(dbt, 0, sizeof(DBT)); *freedbtp = 0; - bk = GET_BKEYDATA(h, i); + bk = GET_BKEYDATA(dbp, h, i); if (B_TYPE(bk->type) == B_OVERFLOW) { if (!ovflok) return (0); |