/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2000
+ * Copyright (c) 1999-2001
* Sleepycat Software. All rights reserved.
*
- * $Id: hash_verify.c,v 1.31 2000/11/30 00:58:37 ubell Exp $
+ * Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp
*/
#include "db_config.h"
#ifndef lint
-static const char revid[] = "$Id: hash_verify.c,v 1.31 2000/11/30 00:58:37 ubell Exp $";
+static const char revid[] = "Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp ";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
VRFY_DBINFO *, db_pgno_t, PAGE *, u_int32_t, u_int32_t));
/*
+ * XXX Doing a db->del followed by a db->put for the same record
+ * causes the nelem/page count to go awry, causing db->verify failure.
+ * Turn off the message for now.
+ */
+int db_hash_nelem_debug = 0;
+
+/*
* __ham_vrfy_meta --
* Verify the hash-specific part of a metadata page.
*
if (m->max_bucket > vdp->last_pgno) {
EPRINT((dbp->dbenv,
"Impossible max_bucket %lu on meta page %lu",
- m->max_bucket, pgno));
+ (u_long)m->max_bucket, (u_long)pgno));
/*
* Most other fields depend somehow on max_bucket, so
* we just return--there will be lots of extraneous
if (m->high_mask != pwr - 1) {
EPRINT((dbp->dbenv,
"Incorrect high_mask %lu on page %lu, should be %lu",
- m->high_mask, pgno, pwr - 1));
+ (u_long)m->high_mask, (u_long)pgno, (u_long)pwr - 1));
isbad = 1;
}
pwr >>= 1;
if (m->low_mask != pwr - 1) {
EPRINT((dbp->dbenv,
"Incorrect low_mask %lu on page %lu, should be %lu",
- m->low_mask, pgno, pwr - 1));
+ (u_long)m->low_mask, (u_long)pgno, (u_long)pwr - 1));
isbad = 1;
}
* which could make nelem go "negative".
*/
if (m->nelem > 0x80000000) {
+ if (db_hash_nelem_debug) {
EPRINT((dbp->dbenv,
"Suspiciously high nelem of %lu on page %lu",
- m->nelem, pgno));
+ (u_long)m->nelem, (u_long)pgno));
isbad = 1;
+ }
pip->h_nelem = 0;
} else
pip->h_nelem = m->nelem;
mbucket = (1 << i) - 1;
if (BS_TO_PAGE(mbucket, m->spares) > vdp->last_pgno) {
EPRINT((dbp->dbenv,
- "Spares array entry %lu, page %lu is invalid",
- i, pgno));
+ "Spares array entry %d, page %lu is invalid",
+ i, (u_long)pgno));
isbad = 1;
}
}
-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);
}
if (h->inp[ent] >= himark) {
EPRINT((dbp->dbenv,
"Item %lu on page %lu out of order or nonsensical",
- ent, pgno));
+ (u_long)ent, (u_long)pgno));
isbad = 1;
goto err;
} else if (inpend >= himark) {
EPRINT((dbp->dbenv,
"inp array collided with data on page %lu",
- pgno));
+ (u_long)pgno));
isbad = 1;
goto err;
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 : ret);
}
if (i % 2 == 0) {
EPRINT((dbp->dbenv,
"Hash key stored as duplicate at page %lu item %lu",
- pip->pgno, i));
+ (u_long)pip->pgno, (u_long)i));
}
/*
* Dups are encoded as a series within a single HKEYDATA,
if (offset + DUP_SIZE(dlen) > len) {
EPRINT((dbp->dbenv,
"Duplicate item %lu, page %lu has bad length",
- i, pip->pgno));
+ (u_long)i, (u_long)pip->pgno));
ret = DB_VERIFY_BAD;
goto err;
}
if (elen != dlen) {
EPRINT((dbp->dbenv,
"Duplicate item %lu, page %lu has two different lengths",
- i, pip->pgno));
+ (u_long)i, (u_long)pip->pgno));
ret = DB_VERIFY_BAD;
goto err;
}
if (!IS_VALID_PGNO(hop.pgno) || hop.pgno == pip->pgno ||
hop.pgno == PGNO_INVALID) {
EPRINT((dbp->dbenv,
- "Offpage item %lu, page %lu has bad page number",
- i, pip->pgno));
+ "Offpage item %lu, page %lu has bad pgno %lu",
+ (u_long)i, (u_long)pip->pgno, (u_long)hop.pgno));
ret = DB_VERIFY_BAD;
goto err;
}
hod.pgno == PGNO_INVALID) {
EPRINT((dbp->dbenv,
"Offpage item %lu, page %lu has bad page number",
- i, pip->pgno));
+ (u_long)i, (u_long)pip->pgno));
ret = DB_VERIFY_BAD;
goto err;
}
break;
default:
EPRINT((dbp->dbenv,
- "Item %i, page %lu has bad type", i, pip->pgno));
+ "Item %i, page %lu has bad type",
+ (u_long)i, (u_long)pip->pgno));
ret = DB_VERIFY_BAD;
break;
}
-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);
}
VRFY_PAGEINFO *pip;
int isbad, p, ret, t_ret;
db_pgno_t pgno;
- u_int32_t bucket;
+ u_int32_t bucket, spares_entry;
ret = isbad = 0;
h = NULL;
return (ret);
if (p != 0) {
EPRINT((dbp->dbenv,
- "Hash meta page %lu referenced twice", meta_pgno));
+ "Hash meta page %lu referenced twice", (u_long)meta_pgno));
return (DB_VERIFY_BAD);
}
if ((ret = __db_vrfy_pgset_inc(pgset, meta_pgno)) != 0)
* Note that this should be safe, since we've already verified
* that the spares array is sane.
*/
- for (bucket = m->max_bucket + 1;
- m->spares[__db_log2(bucket + 1)] != 0; bucket++) {
+ for (bucket = m->max_bucket + 1; spares_entry = __db_log2(bucket + 1),
+ spares_entry < NCACHED && m->spares[spares_entry] != 0; bucket++) {
pgno = BS_TO_PAGE(bucket, m->spares);
if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
goto err;
if (pip->type != P_HASH) {
EPRINT((dbp->dbenv,
"Hash bucket %lu maps to non-hash page %lu",
- bucket, pgno));
+ (u_long)bucket, (u_long)pgno));
isbad = 1;
} else if (pip->entries != 0) {
EPRINT((dbp->dbenv,
"Non-empty page %lu in unused hash bucket %lu",
- pgno, bucket));
+ (u_long)pgno, (u_long)bucket));
isbad = 1;
} else {
if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0)
if (p != 0) {
EPRINT((dbp->dbenv,
"Hash page %lu above max_bucket referenced",
- pgno));
+ (u_long)pgno));
isbad = 1;
} else {
if ((ret =
__db_vrfy_pgset_inc(pgset, pgno)) != 0)
goto err;
- if ((ret =
- __db_vrfy_putpageinfo(vdp, pip)) != 0)
+ if ((ret = __db_vrfy_putpageinfo(dbp->dbenv,
+ vdp, pip)) != 0)
goto err;
continue;
}
}
/* If we got here, it's an error. */
- (void)__db_vrfy_putpageinfo(vdp, pip);
+ (void)__db_vrfy_putpageinfo(dbp->dbenv, vdp, pip);
goto err;
}
/* Make sure we got a plausible page number. */
if (pgno > vdp->last_pgno || pip->type != P_HASH) {
EPRINT((dbp->dbenv, "Bucket %lu has impossible first page %lu",
- bucket, pgno));
+ (u_long)bucket, (u_long)pgno));
/* Unsafe to continue. */
isbad = 1;
goto err;
if (pip->prev_pgno != PGNO_INVALID) {
EPRINT((dbp->dbenv,
- "First hash page %lu in bucket %lu has a prev_pgno", pgno));
+ "First hash page %lu in bucket %lu has a prev_pgno",
+ (u_long)pgno));
isbad = 1;
}
goto err;
if (p != 0) {
EPRINT((dbp->dbenv,
- "Hash page %lu referenced twice", pgno));
+ "Hash page %lu referenced twice", (u_long)pgno));
isbad = 1;
/* Unsafe to continue. */
goto err;
&& !F_ISSET(mip, VRFY_HAS_DUPS)) {
EPRINT((dbp->dbenv,
"Duplicates present in non-duplicate database, page %lu",
- pgno));
+ (u_long)pgno));
isbad = 1;
}
F_ISSET(pip, VRFY_DUPS_UNSORTED)) {
EPRINT((dbp->dbenv,
"Unsorted dups in sorted-dup database, page %lu",
- pgno));
+ (u_long)pgno));
isbad = 1;
}
}
next_pgno = pip->next_pgno;
- ret = __db_vrfy_putpageinfo(vdp, pip);
+ ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip);
pip = NULL;
if (ret != 0)
if (!IS_VALID_PGNO(next_pgno)) {
DB_ASSERT(0);
EPRINT((dbp->dbenv,
- "Hash page %lu has bad next_pgno", pgno));
+ "Hash page %lu has bad next_pgno", (u_long)pgno));
isbad = 1;
goto err;
}
if (pip->prev_pgno != pgno) {
EPRINT((dbp->dbenv, "Hash page %lu has bad prev_pgno",
- next_pgno));
+ (u_long)next_pgno));
isbad = 1;
}
pgno = next_pgno;
err: if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0)
ret = t_ret;
- if (mip != NULL && ((t_ret = __db_vrfy_putpageinfo(vdp, mip)) != 0) &&
- ret == 0)
+ if (mip != NULL && ((t_ret =
+ __db_vrfy_putpageinfo(dbp->dbenv, vdp, mip)) != 0) && ret == 0)
ret = t_ret;
- if (pip != NULL && ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0) &&
- ret == 0)
+ if (pip != NULL && ((t_ret =
+ __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) && ret == 0)
ret = t_ret;
return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
}
if (bucket != thisbucket) {
EPRINT((dbp->dbenv,
"Item %lu on page %lu hashes incorrectly",
- i, pgno));
+ (u_long)i, (u_long)pgno));
isbad = 1;
}
}
err: if (dbt.data != NULL)
- __os_free(dbt.data, 0);
+ __os_free(dbp->dbenv, dbt.data, 0);
if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
return (t_ret);
* 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, &buf)) != 0)
+ if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &buf)) != 0)
return (ret);
himark = dbp->pgsize;
}
}
- __os_free(buf, 0);
+ __os_free(dbp->dbenv, buf, 0);
if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0)
return (t_ret);
return ((ret == 0 && err_ret != 0) ? err_ret : ret);
return (DB_VERIFY_BAD);
}
if ((ret =
- __db_vrfy_pgset_inc(pgset, pgno)) != 0)
+ __db_vrfy_pgset_inc(pgset, pgno)) != 0) {
+ (void)memp_fput(dbp->mpf, h, 0);
return (ret);
+ }
pgno = NEXT_PGNO(h);
} else
/* If the new pgno is wonky, go onto the next bucket. */
if (!IS_VALID_PGNO(pgno) ||
pgno == PGNO_INVALID)
- goto nextbucket;
+ break;
/*
* If we've touched this page before, we have a cycle;
if ((ret = __db_vrfy_pgset_get(pgset, pgno, &val)) != 0)
return (ret);
if (val != 0)
- goto nextbucket;
+ break;
}
-nextbucket: ;
}
return (0);
}