00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "config.h"
00011
00012 #ifndef lint
00013 static const char revid[] = "$Id: db__vrfyutil_8c-source.html,v 1.1 2008/06/08 10:18:32 sebdiaz Exp $";
00014 #endif
00015
00016 #ifndef NO_SYSTEM_INCLUDES
00017 #include <sys/types.h>
00018
00019 #include <string.h>
00020 #endif
00021
00022 #include "db_int.h"
00023 #include "db_page.h"
00024 #include "db_verify.h"
00025 #include "db_ext.h"
00026
00027 static int __db_vrfy_pgset_iinc __P((DB *, db_pgno_t, int));
00028
00029
00030
00031
00032
00033
00034
00035
00036 int
00037 CDB___db_vrfy_dbinfo_create (dbenv, pgsize, vdpp)
00038 DB_ENV *dbenv;
00039 u_int32_t pgsize;
00040 VRFY_DBINFO **vdpp;
00041 {
00042 DB *cdbp, *pgdbp, *pgset;
00043 VRFY_DBINFO *vdp;
00044 int ret;
00045
00046 vdp = NULL;
00047 cdbp = pgdbp = pgset = NULL;
00048
00049 if ((ret = CDB___os_calloc(NULL,
00050 1, sizeof(VRFY_DBINFO), (void **)&vdp)) != 0)
00051 goto err;
00052
00053 if ((ret = CDB_db_create(&cdbp, dbenv, 0)) != 0)
00054 goto err;
00055
00056 if ((ret = cdbp->set_flags(cdbp, DB_DUP | DB_DUPSORT)) != 0)
00057 goto err;
00058
00059 if ((ret = cdbp->set_pagesize(cdbp, pgsize)) != 0)
00060 goto err;
00061
00062 if ((ret =
00063 cdbp->open(cdbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0)
00064 goto err;
00065
00066 if ((ret = CDB_db_create(&pgdbp, dbenv, 0)) != 0)
00067 goto err;
00068
00069 if ((ret = pgdbp->set_pagesize(pgdbp, pgsize)) != 0)
00070 goto err;
00071
00072 if ((ret =
00073 pgdbp->open(pgdbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) != 0)
00074 goto err;
00075
00076 if ((ret = CDB___db_vrfy_pgset(dbenv, pgsize, &pgset)) != 0)
00077 goto err;
00078
00079 LIST_INIT(&vdp->subdbs);
00080 LIST_INIT(&vdp->activepips);
00081
00082 vdp->cdbp = cdbp;
00083 vdp->pgdbp = pgdbp;
00084 vdp->pgset = pgset;
00085 *vdpp = vdp;
00086 return (0);
00087
00088 err: if (cdbp != NULL)
00089 (void)cdbp->close(cdbp, 0);
00090 if (pgdbp != NULL)
00091 (void)pgdbp->close(pgdbp, 0);
00092 if (vdp != NULL)
00093 CDB___os_free(vdp, sizeof(VRFY_DBINFO));
00094 return (ret);
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104 int
00105 CDB___db_vrfy_dbinfo_destroy(vdp)
00106 VRFY_DBINFO *vdp;
00107 {
00108 VRFY_CHILDINFO *c, *d;
00109 int t_ret, ret;
00110
00111 ret = 0;
00112
00113 for (c = LIST_FIRST(&vdp->subdbs); c != NULL; c = d) {
00114 d = LIST_NEXT(c, links);
00115 CDB___os_free(c, 0);
00116 }
00117
00118 if ((t_ret = vdp->pgdbp->close(vdp->pgdbp, 0)) != 0)
00119 ret = t_ret;
00120
00121 if ((t_ret = vdp->cdbp->close(vdp->cdbp, 0)) != 0 && ret == 0)
00122 ret = t_ret;
00123
00124 if ((t_ret = vdp->pgset->close(vdp->pgset, 0)) != 0 && ret == 0)
00125 ret = t_ret;
00126
00127 DB_ASSERT(LIST_FIRST(&vdp->activepips) == NULL);
00128
00129 CDB___os_free(vdp, sizeof(VRFY_DBINFO));
00130 return (ret);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 int
00141 CDB___db_vrfy_getpageinfo(vdp, pgno, pipp)
00142 VRFY_DBINFO *vdp;
00143 db_pgno_t pgno;
00144 VRFY_PAGEINFO **pipp;
00145 {
00146 DBT key, data;
00147 DB *pgdbp;
00148 VRFY_PAGEINFO *pip;
00149 int ret;
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 for (pip = LIST_FIRST(&vdp->activepips); pip != NULL;
00171 pip = LIST_NEXT(pip, links))
00172 if (pip->pgno == pgno)
00173
00174 goto found;
00175
00176
00177 pgdbp = vdp->pgdbp;
00178 memset(&key, 0, sizeof(DBT));
00179 memset(&data, 0, sizeof(DBT));
00180 F_SET(&data, DB_DBT_MALLOC);
00181 key.data = &pgno;
00182 key.size = sizeof(db_pgno_t);
00183
00184 if ((ret = pgdbp->get(pgdbp, NULL, &key, &data, 0)) == 0) {
00185
00186 DB_ASSERT(data.size = sizeof(VRFY_PAGEINFO));
00187 pip = data.data;
00188 DB_ASSERT(pip->pi_refcount == 0);
00189 LIST_INSERT_HEAD(&vdp->activepips, pip, links);
00190 goto found;
00191 } else if (ret != DB_NOTFOUND)
00192 return (ret);
00193
00194
00195 if ((ret = CDB___db_vrfy_pageinfo_create(&pip)) != 0)
00196 return (ret);
00197
00198 LIST_INSERT_HEAD(&vdp->activepips, pip, links);
00199 found: pip->pi_refcount++;
00200
00201 *pipp = pip;
00202
00203 DB_ASSERT(pip->pi_refcount > 0);
00204 return (0);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 int
00214 CDB___db_vrfy_putpageinfo(vdp, pip)
00215 VRFY_DBINFO *vdp;
00216 VRFY_PAGEINFO *pip;
00217 {
00218 DBT key, data;
00219 DB *pgdbp;
00220 VRFY_PAGEINFO *p;
00221 int ret;
00222 #ifdef DIAGNOSTIC
00223 int found;
00224
00225 found = 0;
00226 #endif
00227
00228 if (--pip->pi_refcount > 0)
00229 return (0);
00230
00231 pgdbp = vdp->pgdbp;
00232 memset(&key, 0, sizeof(DBT));
00233 memset(&data, 0, sizeof(DBT));
00234
00235 key.data = &pip->pgno;
00236 key.size = sizeof(db_pgno_t);
00237 data.data = pip;
00238 data.size = sizeof(VRFY_PAGEINFO);
00239
00240 if ((ret = pgdbp->put(pgdbp, NULL, &key, &data, 0)) != 0)
00241 return (ret);
00242
00243 for (p = LIST_FIRST(&vdp->activepips); p != NULL;
00244 p = LIST_NEXT(p, links))
00245 if (p == pip) {
00246 #ifdef DIAGNOSTIC
00247 found++;
00248 #endif
00249 DB_ASSERT(p->pi_refcount == 0);
00250 LIST_REMOVE(p, links);
00251 break;
00252 }
00253 #ifdef DIAGNOSTIC
00254 DB_ASSERT(found == 1);
00255 #endif
00256
00257 DB_ASSERT(pip->pi_refcount == 0);
00258 CDB___os_free(pip, 0);
00259 return (0);
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 int
00271 CDB___db_vrfy_pgset(dbenv, pgsize, dbpp)
00272 DB_ENV *dbenv;
00273 u_int32_t pgsize;
00274 DB **dbpp;
00275 {
00276 DB *dbp;
00277 int ret;
00278
00279 if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0)
00280 return (ret);
00281 if ((ret = dbp->set_pagesize(dbp, pgsize)) != 0)
00282 goto err;
00283 if ((ret = dbp->open(dbp, NULL, NULL, DB_BTREE, DB_CREATE, 0600)) == 0)
00284 *dbpp = dbp;
00285 else
00286 err: (void)dbp->close(dbp, 0);
00287
00288 return (ret);
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 int
00299 CDB___db_vrfy_pgset_get(dbp, pgno, valp)
00300 DB *dbp;
00301 db_pgno_t pgno;
00302 int *valp;
00303 {
00304 DBT key, data;
00305 int ret, val;
00306
00307 memset(&key, 0, sizeof(DBT));
00308 memset(&data, 0, sizeof(DBT));
00309
00310 key.data = &pgno;
00311 key.size = sizeof(db_pgno_t);
00312 data.data = &val;
00313 data.ulen = sizeof(int);
00314 F_SET(&data, DB_DBT_USERMEM);
00315
00316 if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0) {
00317 DB_ASSERT(data.size = sizeof(int));
00318 memcpy(&val, data.data, sizeof(int));
00319 } else if (ret == DB_NOTFOUND)
00320 val = 0;
00321 else
00322 return (ret);
00323
00324 *valp = val;
00325 return (0);
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 int
00335 CDB___db_vrfy_pgset_inc(dbp, pgno)
00336 DB *dbp;
00337 db_pgno_t pgno;
00338 {
00339
00340 return (__db_vrfy_pgset_iinc(dbp, pgno, 1));
00341 }
00342
00343
00344
00345
00346
00347
00348
00349 int
00350 CDB___db_vrfy_pgset_dec(dbp, pgno)
00351 DB *dbp;
00352 db_pgno_t pgno;
00353 {
00354
00355 return (__db_vrfy_pgset_iinc(dbp, pgno, -1));
00356 }
00357
00358
00359
00360
00361
00362
00363 static int
00364 __db_vrfy_pgset_iinc(dbp, pgno, i)
00365 DB *dbp;
00366 db_pgno_t pgno;
00367 int i;
00368 {
00369 DBT key, data;
00370 int ret;
00371 int val;
00372
00373 memset(&key, 0, sizeof(DBT));
00374 memset(&data, 0, sizeof(DBT));
00375
00376 val = 0;
00377
00378 key.data = &pgno;
00379 key.size = sizeof(db_pgno_t);
00380 data.data = &val;
00381 data.ulen = sizeof(int);
00382 F_SET(&data, DB_DBT_USERMEM);
00383
00384 if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0) {
00385 DB_ASSERT(data.size = sizeof(int));
00386 memcpy(&val, data.data, sizeof(int));
00387 } else if (ret != DB_NOTFOUND)
00388 return (ret);
00389
00390 data.size = sizeof(int);
00391 val += i;
00392
00393 return (dbp->put(dbp, NULL, &key, &data, 0));
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403 int
00404 CDB___db_vrfy_pgset_next(dbc, pgnop)
00405 DBC *dbc;
00406 db_pgno_t *pgnop;
00407 {
00408 DBT key, data;
00409 db_pgno_t pgno;
00410 int ret;
00411
00412 memset(&key, 0, sizeof(DBT));
00413 memset(&data, 0, sizeof(DBT));
00414
00415 F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
00416 F_SET(&key, DB_DBT_USERMEM);
00417 key.data = &pgno;
00418 key.ulen = sizeof(db_pgno_t);
00419
00420 if ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) != 0)
00421 return (ret);
00422
00423 DB_ASSERT(key.size == sizeof(db_pgno_t));
00424 *pgnop = pgno;
00425
00426 return (0);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436 int
00437 CDB___db_vrfy_childcursor(vdp, dbcp)
00438 VRFY_DBINFO *vdp;
00439 DBC **dbcp;
00440 {
00441 DB *cdbp;
00442 DBC *dbc;
00443 int ret;
00444
00445 cdbp = vdp->cdbp;
00446
00447 if ((ret = cdbp->cursor(cdbp, NULL, &dbc, 0)) == 0)
00448 *dbcp = dbc;
00449
00450 return (ret);
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 int
00461 CDB___db_vrfy_childput(vdp, pgno, cip)
00462 VRFY_DBINFO *vdp;
00463 db_pgno_t pgno;
00464 VRFY_CHILDINFO *cip;
00465 {
00466 DBT key, data;
00467 DB *cdbp;
00468 int ret;
00469
00470 cdbp = vdp->cdbp;
00471 memset(&key, 0, sizeof(DBT));
00472 memset(&data, 0, sizeof(DBT));
00473
00474 key.data = &pgno;
00475 key.size = sizeof(db_pgno_t);
00476
00477 data.data = cip;
00478 data.size = sizeof(VRFY_CHILDINFO);
00479
00480
00481
00482
00483
00484
00485
00486 ret = cdbp->put(cdbp, NULL, &key, &data, DB_NODUPDATA);
00487 return (ret == DB_KEYEXIST ? 0 : ret);
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497 int
00498 CDB___db_vrfy_ccset(dbc, pgno, cipp)
00499 DBC *dbc;
00500 db_pgno_t pgno;
00501 VRFY_CHILDINFO **cipp;
00502 {
00503 DBT key, data;
00504 int ret;
00505
00506 memset(&key, 0, sizeof(DBT));
00507 memset(&data, 0, sizeof(DBT));
00508
00509 key.data = &pgno;
00510 key.size = sizeof(db_pgno_t);
00511
00512 if ((ret = dbc->c_get(dbc, &key, &data, DB_SET)) != 0)
00513 return (ret);
00514
00515 DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));
00516 *cipp = (VRFY_CHILDINFO *)data.data;
00517
00518 return (0);
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 int
00530 CDB___db_vrfy_ccnext(dbc, cipp)
00531 DBC *dbc;
00532 VRFY_CHILDINFO **cipp;
00533 {
00534 DBT key, data;
00535 int ret;
00536
00537 memset(&key, 0, sizeof(DBT));
00538 memset(&data, 0, sizeof(DBT));
00539
00540 if ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
00541 return (ret);
00542
00543 DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));
00544 *cipp = (VRFY_CHILDINFO *)data.data;
00545
00546 return (0);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 int
00561 CDB___db_vrfy_ccclose(dbc)
00562 DBC *dbc;
00563 {
00564
00565 return (dbc->c_close(dbc));
00566 }
00567
00568
00569
00570
00571
00572
00573
00574 int
00575 CDB___db_vrfy_pageinfo_create(pgipp)
00576 VRFY_PAGEINFO **pgipp;
00577 {
00578 VRFY_PAGEINFO *pgip;
00579 int ret;
00580
00581 if ((ret = CDB___os_calloc(NULL,
00582 1, sizeof(VRFY_PAGEINFO), (void **)&pgip)) != 0)
00583 return (ret);
00584
00585 DB_ASSERT(pgip->pi_refcount == 0);
00586
00587 *pgipp = pgip;
00588 return (0);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 int
00598 CDB___db_salvage_init(vdp)
00599 VRFY_DBINFO *vdp;
00600 {
00601 DB *dbp;
00602 int ret;
00603
00604 if ((ret = CDB_db_create(&dbp, NULL, 0)) != 0)
00605 return (ret);
00606
00607 if ((ret = dbp->set_pagesize(dbp, 1024)) != 0)
00608 goto err;
00609
00610 if ((ret = dbp->open(dbp, NULL, NULL, DB_BTREE, DB_CREATE, 0)) != 0)
00611 goto err;
00612
00613 vdp->salvage_pages = dbp;
00614 return (0);
00615
00616 err: (void)dbp->close(dbp, 0);
00617 return (ret);
00618 }
00619
00620
00621
00622
00623
00624
00625 void
00626 CDB___db_salvage_destroy(vdp)
00627 VRFY_DBINFO *vdp;
00628 {
00629 (void)vdp->salvage_pages->close(vdp->salvage_pages, 0);
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 int
00642 CDB___db_salvage_getnext(vdp, pgnop, pgtypep)
00643 VRFY_DBINFO *vdp;
00644 db_pgno_t *pgnop;
00645 u_int32_t *pgtypep;
00646 {
00647 DB *dbp;
00648 DBC *dbc;
00649 DBT key, data;
00650 int ret;
00651 u_int32_t pgtype;
00652
00653 dbp = vdp->salvage_pages;
00654
00655 memset(&key, 0, sizeof(DBT));
00656 memset(&data, 0, sizeof(DBT));
00657
00658 if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
00659 return (ret);
00660
00661 while ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0) {
00662 DB_ASSERT(data.size == sizeof(u_int32_t));
00663 memcpy(&pgtype, data.data, sizeof(pgtype));
00664
00665 if ((ret = dbc->c_del(dbc, 0)) != 0)
00666 goto err;
00667 if (pgtype != SALVAGE_IGNORE)
00668 goto found;
00669 }
00670
00671
00672
00673 if (0) {
00674 found: DB_ASSERT(key.size == sizeof(db_pgno_t));
00675 DB_ASSERT(data.size == sizeof(u_int32_t));
00676
00677 *pgnop = *(db_pgno_t *)key.data;
00678 *pgtypep = *(u_int32_t *)data.data;
00679 }
00680
00681 err: (void)dbc->c_close(dbc);
00682 return (ret);
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 int
00696 CDB___db_salvage_isdone(vdp, pgno)
00697 VRFY_DBINFO *vdp;
00698 db_pgno_t pgno;
00699 {
00700 DBT key, data;
00701 DB *dbp;
00702 int ret;
00703 u_int32_t currtype;
00704
00705 dbp = vdp->salvage_pages;
00706
00707 memset(&key, 0, sizeof(DBT));
00708 memset(&data, 0, sizeof(DBT));
00709
00710 currtype = SALVAGE_INVALID;
00711 data.data = &currtype;
00712 data.ulen = sizeof(u_int32_t);
00713 data.flags = DB_DBT_USERMEM;
00714
00715 key.data = &pgno;
00716 key.size = sizeof(db_pgno_t);
00717
00718
00719
00720
00721
00722
00723
00724 ret = dbp->get(dbp, NULL, &key, &data, 0);
00725 if (ret == 0) {
00726
00727
00728
00729
00730
00731 if (currtype == SALVAGE_IGNORE)
00732 return (DB_KEYEXIST);
00733 else
00734 return (0);
00735 } else if (ret != DB_NOTFOUND)
00736 return (ret);
00737
00738
00739 return (0);
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 int
00749 CDB___db_salvage_markdone(vdp, pgno)
00750 VRFY_DBINFO *vdp;
00751 db_pgno_t pgno;
00752 {
00753 DBT key, data;
00754 DB *dbp;
00755 int pgtype, ret;
00756 u_int32_t currtype;
00757
00758 pgtype = SALVAGE_IGNORE;
00759 dbp = vdp->salvage_pages;
00760
00761 memset(&key, 0, sizeof(DBT));
00762 memset(&data, 0, sizeof(DBT));
00763
00764 currtype = SALVAGE_INVALID;
00765 data.data = &currtype;
00766 data.ulen = sizeof(u_int32_t);
00767 data.flags = DB_DBT_USERMEM;
00768
00769 key.data = &pgno;
00770 key.size = sizeof(db_pgno_t);
00771
00772
00773
00774
00775
00776
00777
00778
00779 if ((ret = CDB___db_salvage_isdone(vdp, pgno)) != 0)
00780 return (ret);
00781
00782 data.size = sizeof(u_int32_t);
00783 data.data = &pgtype;
00784
00785 return (dbp->put(dbp, NULL, &key, &data, 0));
00786 }
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 int
00797 CDB___db_salvage_markneeded(vdp, pgno, pgtype)
00798 VRFY_DBINFO *vdp;
00799 db_pgno_t pgno;
00800 u_int32_t pgtype;
00801 {
00802 DB *dbp;
00803 DBT key, data;
00804 int ret;
00805
00806 dbp = vdp->salvage_pages;
00807
00808 memset(&key, 0, sizeof(DBT));
00809 memset(&data, 0, sizeof(DBT));
00810
00811 key.data = &pgno;
00812 key.size = sizeof(db_pgno_t);
00813
00814 data.data = &pgtype;
00815 data.size = sizeof(u_int32_t);
00816
00817
00818
00819
00820
00821
00822 ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
00823 return (ret == DB_KEYEXIST ? 0 : ret);
00824 }