diff options
Diffstat (limited to 'bdb/db/db_vrfyutil.c')
-rw-r--r-- | bdb/db/db_vrfyutil.c | 118 |
1 files changed, 80 insertions, 38 deletions
diff --git a/bdb/db/db_vrfyutil.c b/bdb/db/db_vrfyutil.c index 89dccdcc760..44344ceed11 100644 --- a/bdb/db/db_vrfyutil.c +++ b/bdb/db/db_vrfyutil.c @@ -1,16 +1,16 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000 + * Copyright (c) 2000-2002 * Sleepycat Software. All rights reserved. * - * $Id: db_vrfyutil.c,v 11.11 2000/11/28 21:36:04 bostic Exp $ + * $Id: db_vrfyutil.c,v 11.29 2002/08/08 03:57:50 bostic Exp $ */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: db_vrfyutil.c,v 11.11 2000/11/28 21:36:04 bostic Exp $"; +static const char revid[] = "$Id: db_vrfyutil.c,v 11.29 2002/08/08 03:57:50 bostic Exp $"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -20,10 +20,11 @@ static const char revid[] = "$Id: db_vrfyutil.c,v 11.11 2000/11/28 21:36:04 bost #endif #include "db_int.h" -#include "db_page.h" -#include "db_verify.h" -#include "db_ext.h" +#include "dbinc/db_page.h" +#include "dbinc/db_verify.h" +#include "dbinc/db_am.h" +static int __db_vrfy_pageinfo_create __P((DB_ENV *, VRFY_PAGEINFO **)); static int __db_vrfy_pgset_iinc __P((DB *, db_pgno_t, int)); /* @@ -34,7 +35,7 @@ static int __db_vrfy_pgset_iinc __P((DB *, db_pgno_t, int)); * PUBLIC: __P((DB_ENV *, u_int32_t, VRFY_DBINFO **)); */ int -__db_vrfy_dbinfo_create (dbenv, pgsize, vdpp) +__db_vrfy_dbinfo_create(dbenv, pgsize, vdpp) DB_ENV *dbenv; u_int32_t pgsize; VRFY_DBINFO **vdpp; @@ -53,14 +54,14 @@ __db_vrfy_dbinfo_create (dbenv, pgsize, vdpp) if ((ret = db_create(&cdbp, dbenv, 0)) != 0) goto err; - if ((ret = cdbp->set_flags(cdbp, DB_DUP | DB_DUPSORT)) != 0) + if ((ret = cdbp->set_flags(cdbp, DB_DUP)) != 0) goto err; if ((ret = cdbp->set_pagesize(cdbp, pgsize)) != 0) goto err; if ((ret = - cdbp->open(cdbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) + cdbp->open(cdbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) goto err; if ((ret = db_create(&pgdbp, dbenv, 0)) != 0) @@ -69,8 +70,8 @@ __db_vrfy_dbinfo_create (dbenv, pgsize, vdpp) if ((ret = pgdbp->set_pagesize(pgdbp, pgsize)) != 0) goto err; - if ((ret = - pgdbp->open(pgdbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) + if ((ret = pgdbp->open(pgdbp, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) goto err; if ((ret = __db_vrfy_pgset(dbenv, pgsize, &pgset)) != 0) @@ -90,7 +91,7 @@ err: if (cdbp != NULL) if (pgdbp != NULL) (void)pgdbp->close(pgdbp, 0); if (vdp != NULL) - __os_free(vdp, sizeof(VRFY_DBINFO)); + __os_free(dbenv, vdp); return (ret); } @@ -99,10 +100,11 @@ err: if (cdbp != NULL) * Destructor for VRFY_DBINFO. Destroys VRFY_PAGEINFOs and deallocates * structure. * - * PUBLIC: int __db_vrfy_dbinfo_destroy __P((VRFY_DBINFO *)); + * PUBLIC: int __db_vrfy_dbinfo_destroy __P((DB_ENV *, VRFY_DBINFO *)); */ int -__db_vrfy_dbinfo_destroy(vdp) +__db_vrfy_dbinfo_destroy(dbenv, vdp) + DB_ENV *dbenv; VRFY_DBINFO *vdp; { VRFY_CHILDINFO *c, *d; @@ -112,7 +114,7 @@ __db_vrfy_dbinfo_destroy(vdp) for (c = LIST_FIRST(&vdp->subdbs); c != NULL; c = d) { d = LIST_NEXT(c, links); - __os_free(c, 0); + __os_free(NULL, c); } if ((t_ret = vdp->pgdbp->close(vdp->pgdbp, 0)) != 0) @@ -126,7 +128,7 @@ __db_vrfy_dbinfo_destroy(vdp) DB_ASSERT(LIST_FIRST(&vdp->activepips) == NULL); - __os_free(vdp, sizeof(VRFY_DBINFO)); + __os_free(dbenv, vdp); return (ret); } @@ -192,7 +194,7 @@ __db_vrfy_getpageinfo(vdp, pgno, pipp) return (ret); /* Case 3 */ - if ((ret = __db_vrfy_pageinfo_create(&pip)) != 0) + if ((ret = __db_vrfy_pageinfo_create(pgdbp->dbenv, &pip)) != 0) return (ret); LIST_INSERT_HEAD(&vdp->activepips, pip, links); @@ -208,10 +210,12 @@ found: pip->pi_refcount++; * __db_vrfy_putpageinfo -- * Put back a VRFY_PAGEINFO that we're done with. * - * PUBLIC: int __db_vrfy_putpageinfo __P((VRFY_DBINFO *, VRFY_PAGEINFO *)); + * PUBLIC: int __db_vrfy_putpageinfo __P((DB_ENV *, + * PUBLIC: VRFY_DBINFO *, VRFY_PAGEINFO *)); */ int -__db_vrfy_putpageinfo(vdp, pip) +__db_vrfy_putpageinfo(dbenv, vdp, pip) + DB_ENV *dbenv; VRFY_DBINFO *vdp; VRFY_PAGEINFO *pip; { @@ -255,7 +259,7 @@ __db_vrfy_putpageinfo(vdp, pip) #endif DB_ASSERT(pip->pi_refcount == 0); - __os_free(pip, 0); + __os_ufree(dbenv, pip); return (0); } @@ -280,7 +284,8 @@ __db_vrfy_pgset(dbenv, pgsize, dbpp) return (ret); if ((ret = dbp->set_pagesize(dbp, pgsize)) != 0) goto err; - if ((ret = dbp->open(dbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) == 0) + if ((ret = dbp->open(dbp, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) == 0) *dbpp = dbp; else err: (void)dbp->close(dbp, 0); @@ -382,7 +387,7 @@ __db_vrfy_pgset_iinc(dbp, pgno, i) F_SET(&data, DB_DBT_USERMEM); if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0) { - DB_ASSERT(data.size = sizeof(int)); + DB_ASSERT(data.size == sizeof(int)); memcpy(&val, data.data, sizeof(int)); } else if (ret != DB_NOTFOUND) return (ret); @@ -463,8 +468,10 @@ __db_vrfy_childput(vdp, pgno, cip) db_pgno_t pgno; VRFY_CHILDINFO *cip; { - DBT key, data; DB *cdbp; + DBC *cc; + DBT key, data; + VRFY_CHILDINFO *oldcip; int ret; cdbp = vdp->cdbp; @@ -474,17 +481,44 @@ __db_vrfy_childput(vdp, pgno, cip) key.data = &pgno; key.size = sizeof(db_pgno_t); + /* + * We want to avoid adding multiple entries for a single child page; + * we only need to verify each child once, even if a child (such + * as an overflow key) is multiply referenced. + * + * However, we also need to make sure that when walking the list + * of children, we encounter them in the order they're referenced + * on a page. (This permits us, for example, to verify the + * prev_pgno/next_pgno chain of Btree leaf pages.) + * + * Check the child database to make sure that this page isn't + * already a child of the specified page number. If it's not, + * put it at the end of the duplicate set. + */ + if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) + return (ret); + for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0; + ret = __db_vrfy_ccnext(cc, &oldcip)) + if (oldcip->pgno == cip->pgno) { + /* + * Found a matching child. Return without + * putting it again. + */ + if ((ret = __db_vrfy_ccclose(cc)) != 0) + return (ret); + return (0); + } + if (ret != DB_NOTFOUND) { + (void)__db_vrfy_ccclose(cc); + return (ret); + } + if ((ret = __db_vrfy_ccclose(cc)) != 0) + return (ret); + data.data = cip; data.size = sizeof(VRFY_CHILDINFO); - /* - * Don't add duplicate (data) entries for a given child, and accept - * DB_KEYEXIST as a successful return; we only need to verify - * each child once, even if a child (such as an overflow key) is - * multiply referenced. - */ - ret = cdbp->put(cdbp, NULL, &key, &data, DB_NODUPDATA); - return (ret == DB_KEYEXIST ? 0 : ret); + return (cdbp->put(cdbp, NULL, &key, &data, 0)); } /* @@ -568,19 +602,26 @@ __db_vrfy_ccclose(dbc) /* * __db_vrfy_pageinfo_create -- * Constructor for VRFY_PAGEINFO; allocates and initializes. - * - * PUBLIC: int __db_vrfy_pageinfo_create __P((VRFY_PAGEINFO **)); */ -int -__db_vrfy_pageinfo_create(pgipp) +static int +__db_vrfy_pageinfo_create(dbenv, pgipp) + DB_ENV *dbenv; VRFY_PAGEINFO **pgipp; { VRFY_PAGEINFO *pgip; int ret; - if ((ret = __os_calloc(NULL, - 1, sizeof(VRFY_PAGEINFO), (void **)&pgip)) != 0) + /* + * pageinfo structs are sometimes allocated here and sometimes + * allocated by fetching them from a database with DB_DBT_MALLOC. + * There's no easy way for the destructor to tell which was + * used, and so we always allocate with __os_umalloc so we can free + * with __os_ufree. + */ + if ((ret = __os_umalloc(dbenv, + sizeof(VRFY_PAGEINFO), (void **)&pgip)) != 0) return (ret); + memset(pgip, 0, sizeof(VRFY_PAGEINFO)); DB_ASSERT(pgip->pi_refcount == 0); @@ -607,7 +648,8 @@ __db_salvage_init(vdp) if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) goto err; - if ((ret = dbp->open(dbp, NULL, NULL, DB_BTREE, DB_CREATE, 0)) != 0) + if ((ret = dbp->open(dbp, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0)) != 0) goto err; vdp->salvage_pages = dbp; |