00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #include <string.h>
00016 #endif
00017
00018 #include "db_int.h"
00019 #include "dbinc/db_page.h"
00020 #include "dbinc/db_shash.h"
00021 #include "dbinc/btree.h"
00022 #include "dbinc/lock.h"
00023 #include "dbinc/log.h"
00024 #include "dbinc/mp.h"
00025
00026 #define IS_BTREE_PAGE(pagep) \
00027 (TYPE(pagep) == P_IBTREE || \
00028 TYPE(pagep) == P_LBTREE || TYPE(pagep) == P_LDUP)
00029
00030
00031
00032
00033
00034
00035
00036
00037 int
00038 __bam_split_recover(dbenv, dbtp, lsnp, op, info)
00039 DB_ENV *dbenv;
00040 DBT *dbtp;
00041 DB_LSN *lsnp;
00042 db_recops op;
00043 void *info;
00044 {
00045 __bam_split_args *argp;
00046 DB *file_dbp;
00047 DBC *dbc;
00048 DB_MPOOLFILE *mpf;
00049 PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp;
00050 db_pgno_t pgno, root_pgno;
00051 u_int32_t ptype;
00052 int cmp, l_update, p_update, r_update, rc, ret, rootsplit, t_ret;
00053
00054 COMPQUIET(info, NULL);
00055 REC_PRINT(__bam_split_print);
00056
00057 mpf = NULL;
00058 _lp = lp = np = pp = _rp = rp = NULL;
00059 sp = NULL;
00060
00061 REC_INTRO(__bam_split_read, 1, 0);
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 if ((ret = __os_malloc(dbenv, argp->pg.size, &sp)) != 0)
00078 goto out;
00079 memcpy(sp, argp->pg.data, argp->pg.size);
00080
00081 pgno = PGNO(sp);
00082 root_pgno = argp->root_pgno;
00083 rootsplit = root_pgno != PGNO_INVALID;
00084 REC_FGET(mpf, argp->left, &lp, right);
00085 right: REC_FGET(mpf, argp->right, &rp, redo);
00086
00087 redo: if (DB_REDO(op)) {
00088 l_update = r_update = p_update = 0;
00089
00090
00091
00092
00093
00094
00095 if (rootsplit) {
00096 REC_FGET(mpf, root_pgno, &pp, do_left);
00097 cmp =
00098 log_compare(&LSN(pp), &LSN(argp->pg.data));
00099 CHECK_LSN(dbenv, op,
00100 cmp, &LSN(pp), &LSN(argp->pg.data));
00101 p_update = cmp == 0;
00102 }
00103
00104 do_left: if (lp != NULL) {
00105 cmp = log_compare(&LSN(lp), &argp->llsn);
00106 CHECK_LSN(dbenv, op, cmp, &LSN(lp), &argp->llsn);
00107 if (cmp == 0)
00108 l_update = 1;
00109 }
00110
00111 if (rp != NULL) {
00112 cmp = log_compare(&LSN(rp), &argp->rlsn);
00113 CHECK_LSN(dbenv, op, cmp, &LSN(rp), &argp->rlsn);
00114 if (cmp == 0)
00115 r_update = 1;
00116 }
00117
00118 if (!p_update && !l_update && !r_update)
00119 goto check_next;
00120
00121
00122 if ((ret = __os_malloc(dbenv, file_dbp->pgsize, &_lp)) != 0 ||
00123 (ret = __os_malloc(dbenv, file_dbp->pgsize, &_rp)) != 0)
00124 goto out;
00125 if (rootsplit) {
00126 P_INIT(_lp, file_dbp->pgsize, argp->left,
00127 PGNO_INVALID,
00128 ISINTERNAL(sp) ? PGNO_INVALID : argp->right,
00129 LEVEL(sp), TYPE(sp));
00130 P_INIT(_rp, file_dbp->pgsize, argp->right,
00131 ISINTERNAL(sp) ? PGNO_INVALID : argp->left,
00132 PGNO_INVALID, LEVEL(sp), TYPE(sp));
00133 } else {
00134 P_INIT(_lp, file_dbp->pgsize, PGNO(sp),
00135 ISINTERNAL(sp) ? PGNO_INVALID : PREV_PGNO(sp),
00136 ISINTERNAL(sp) ? PGNO_INVALID : argp->right,
00137 LEVEL(sp), TYPE(sp));
00138 P_INIT(_rp, file_dbp->pgsize, argp->right,
00139 ISINTERNAL(sp) ? PGNO_INVALID : sp->pgno,
00140 ISINTERNAL(sp) ? PGNO_INVALID : NEXT_PGNO(sp),
00141 LEVEL(sp), TYPE(sp));
00142 }
00143
00144
00145 if ((ret = __bam_copy(file_dbp, sp, _lp, 0, argp->indx)) != 0 ||
00146 (ret = __bam_copy(file_dbp, sp, _rp, argp->indx,
00147 NUM_ENT(sp))) != 0)
00148 goto out;
00149
00150 if (l_update) {
00151 memcpy(lp, _lp, file_dbp->pgsize);
00152 lp->lsn = *lsnp;
00153 if ((ret = __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0)
00154 goto out;
00155 lp = NULL;
00156 }
00157
00158 if (r_update) {
00159 memcpy(rp, _rp, file_dbp->pgsize);
00160 rp->lsn = *lsnp;
00161 if ((ret = __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0)
00162 goto out;
00163 rp = NULL;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172 if (rootsplit && p_update) {
00173 if (IS_BTREE_PAGE(sp)) {
00174 ptype = P_IBTREE;
00175 rc = argp->opflags & SPL_NRECS ? 1 : 0;
00176 } else {
00177 ptype = P_IRECNO;
00178 rc = 1;
00179 }
00180
00181 P_INIT(pp, file_dbp->pgsize, root_pgno,
00182 PGNO_INVALID, PGNO_INVALID, _lp->level + 1, ptype);
00183 RE_NREC_SET(pp, rc ? __bam_total(file_dbp, _lp) +
00184 __bam_total(file_dbp, _rp) : 0);
00185
00186 pp->lsn = *lsnp;
00187 if ((ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0)
00188 goto out;
00189 pp = NULL;
00190 }
00191
00192 check_next:
00193
00194
00195
00196
00197
00198
00199 if (!rootsplit && argp->npgno != PGNO_INVALID) {
00200 if ((ret =
00201 __memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
00202 if (ret != DB_PAGE_NOTFOUND
00203 #ifndef HAVE_FTRUNCATE
00204 || DB_REDO(op)
00205 #endif
00206 ) {
00207 ret = __db_pgerr(
00208 file_dbp, argp->npgno, ret);
00209 goto out;
00210 } else
00211 goto done;
00212 }
00213 cmp = log_compare(&LSN(np), &argp->nlsn);
00214 CHECK_LSN(dbenv, op, cmp, &LSN(np), &argp->nlsn);
00215 if (cmp == 0) {
00216 PREV_PGNO(np) = argp->right;
00217 np->lsn = *lsnp;
00218 if ((ret =
00219 __memp_fput(mpf, np, DB_MPOOL_DIRTY)) != 0)
00220 goto out;
00221 np = NULL;
00222 }
00223 }
00224 } else {
00225
00226
00227
00228
00229
00230
00231
00232 if ((ret = __memp_fget(mpf, &pgno, 0, &pp)) != 0) {
00233 pp = NULL;
00234 goto lrundo;
00235 }
00236 if (log_compare(lsnp, &LSN(pp)) == 0) {
00237 memcpy(pp, argp->pg.data, argp->pg.size);
00238 if ((ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0)
00239 goto out;
00240 pp = NULL;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 lrundo: if ((rootsplit && lp != NULL) || rp != NULL) {
00252 if (rootsplit && lp != NULL &&
00253 log_compare(lsnp, &LSN(lp)) == 0) {
00254 lp->lsn = argp->llsn;
00255 if ((ret =
00256 __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0)
00257 goto out;
00258 lp = NULL;
00259 }
00260 if (rp != NULL &&
00261 log_compare(lsnp, &LSN(rp)) == 0) {
00262 rp->lsn = argp->rlsn;
00263 if ((ret =
00264 __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0)
00265 goto out;
00266 rp = NULL;
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 if (!rootsplit && argp->npgno != PGNO_INVALID) {
00279 if ((ret =
00280 __memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
00281 np = NULL;
00282 goto done;
00283 }
00284 if (log_compare(lsnp, &LSN(np)) == 0) {
00285 PREV_PGNO(np) = argp->left;
00286 np->lsn = argp->nlsn;
00287 if (__memp_fput(mpf, np, DB_MPOOL_DIRTY))
00288 goto out;
00289 np = NULL;
00290 }
00291 }
00292 }
00293
00294 done: *lsnp = argp->prev_lsn;
00295 ret = 0;
00296
00297 out:
00298 if (pp != NULL && (t_ret = __memp_fput(mpf, pp, 0)) != 0 && ret == 0)
00299 ret = t_ret;
00300 if (lp != NULL && (t_ret = __memp_fput(mpf, lp, 0)) != 0 && ret == 0)
00301 ret = t_ret;
00302 if (np != NULL && (t_ret = __memp_fput(mpf, np, 0)) != 0 && ret == 0)
00303 ret = t_ret;
00304 if (rp != NULL && (t_ret = __memp_fput(mpf, rp, 0)) != 0 && ret == 0)
00305 ret = t_ret;
00306
00307
00308 if (_lp != NULL)
00309 __os_free(dbenv, _lp);
00310 if (_rp != NULL)
00311 __os_free(dbenv, _rp);
00312 if (sp != NULL)
00313 __os_free(dbenv, sp);
00314
00315 REC_CLOSE;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 int
00326 __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
00327 DB_ENV *dbenv;
00328 DBT *dbtp;
00329 DB_LSN *lsnp;
00330 db_recops op;
00331 void *info;
00332 {
00333 __bam_rsplit_args *argp;
00334 DB *file_dbp;
00335 DBC *dbc;
00336 DB_LSN copy_lsn;
00337 DB_MPOOLFILE *mpf;
00338 PAGE *pagep;
00339 db_pgno_t pgno, root_pgno;
00340 db_recno_t rcnt;
00341 int cmp_n, cmp_p, modified, ret;
00342
00343 pagep = NULL;
00344 COMPQUIET(info, NULL);
00345 REC_PRINT(__bam_rsplit_print);
00346 REC_INTRO(__bam_rsplit_read, 1, 1);
00347
00348
00349 pgno = root_pgno = argp->root_pgno;
00350 if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) {
00351 if (ret != DB_PAGE_NOTFOUND
00352 #ifndef HAVE_FTRUNCATE
00353 || DB_REDO(op)
00354 #endif
00355 ) {
00356 ret = __db_pgerr(file_dbp, pgno, ret);
00357 goto out;
00358 } else
00359 goto do_page;
00360 }
00361
00362 modified = 0;
00363 cmp_n = log_compare(lsnp, &LSN(pagep));
00364 cmp_p = log_compare(&LSN(pagep), &argp->rootlsn);
00365 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->rootlsn);
00366 if (cmp_p == 0 && DB_REDO(op)) {
00367
00368
00369
00370
00371
00372
00373
00374 rcnt = RE_NREC(pagep);
00375 memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
00376 if (LEVEL(pagep) > LEAFLEVEL)
00377 RE_NREC_SET(pagep, rcnt);
00378 pagep->pgno = root_pgno;
00379 pagep->lsn = *lsnp;
00380 modified = 1;
00381 } else if (cmp_n == 0 && DB_UNDO(op)) {
00382
00383 P_INIT(pagep, file_dbp->pgsize, root_pgno,
00384 argp->nrec, PGNO_INVALID, pagep->level + 1,
00385 IS_BTREE_PAGE(pagep) ? P_IBTREE : P_IRECNO);
00386 if ((ret = __db_pitem(dbc, pagep, 0,
00387 argp->rootent.size, &argp->rootent, NULL)) != 0)
00388 goto out;
00389 pagep->lsn = argp->rootlsn;
00390 modified = 1;
00391 }
00392 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00393 goto out;
00394
00395 do_page:
00396
00397
00398
00399
00400
00401 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00402 if (ret != DB_PAGE_NOTFOUND
00403 #ifndef HAVE_FTRUNCATE
00404 || DB_REDO(op)
00405 #endif
00406 ) {
00407 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00408 goto out;
00409 } else
00410 goto done;
00411 }
00412 modified = 0;
00413 (void)__ua_memcpy(©_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN));
00414 cmp_n = log_compare(lsnp, &LSN(pagep));
00415 cmp_p = log_compare(&LSN(pagep), ©_lsn);
00416 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn);
00417 if (cmp_p == 0 && DB_REDO(op)) {
00418
00419 pagep->lsn = *lsnp;
00420 modified = 1;
00421 } else if (cmp_n == 0 && DB_UNDO(op)) {
00422
00423 memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
00424 modified = 1;
00425 }
00426 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00427 goto out;
00428 pagep = NULL;
00429
00430 done: *lsnp = argp->prev_lsn;
00431 ret = 0;
00432
00433 out: if (pagep != NULL)
00434 (void)__memp_fput(mpf, pagep, 0);
00435 REC_CLOSE;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445 int
00446 __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
00447 DB_ENV *dbenv;
00448 DBT *dbtp;
00449 DB_LSN *lsnp;
00450 db_recops op;
00451 void *info;
00452 {
00453 __bam_adj_args *argp;
00454 DB *file_dbp;
00455 DBC *dbc;
00456 DB_MPOOLFILE *mpf;
00457 PAGE *pagep;
00458 int cmp_n, cmp_p, modified, ret;
00459
00460 pagep = NULL;
00461 COMPQUIET(info, NULL);
00462 REC_PRINT(__bam_adj_print);
00463 REC_INTRO(__bam_adj_read, 1, 1);
00464
00465
00466 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00467 if (ret != DB_PAGE_NOTFOUND
00468 #ifndef HAVE_FTRUNCATE
00469 || DB_REDO(op)
00470 #endif
00471 ) {
00472 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00473 goto out;
00474 } else
00475 goto done;
00476 }
00477
00478 modified = 0;
00479 cmp_n = log_compare(lsnp, &LSN(pagep));
00480 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
00481 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
00482 if (cmp_p == 0 && DB_REDO(op)) {
00483
00484 if ((ret = __bam_adjindx(dbc,
00485 pagep, argp->indx, argp->indx_copy, argp->is_insert)) != 0)
00486 goto out;
00487
00488 LSN(pagep) = *lsnp;
00489 modified = 1;
00490 } else if (cmp_n == 0 && DB_UNDO(op)) {
00491
00492 if ((ret = __bam_adjindx(dbc,
00493 pagep, argp->indx, argp->indx_copy, !argp->is_insert)) != 0)
00494 goto out;
00495
00496 LSN(pagep) = argp->lsn;
00497 modified = 1;
00498 }
00499 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00500 goto out;
00501 pagep = NULL;
00502
00503 done: *lsnp = argp->prev_lsn;
00504 ret = 0;
00505
00506 out: if (pagep != NULL)
00507 (void)__memp_fput(mpf, pagep, 0);
00508 REC_CLOSE;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 int
00520 __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
00521 DB_ENV *dbenv;
00522 DBT *dbtp;
00523 DB_LSN *lsnp;
00524 db_recops op;
00525 void *info;
00526 {
00527 __bam_cadjust_args *argp;
00528 DB *file_dbp;
00529 DBC *dbc;
00530 DB_MPOOLFILE *mpf;
00531 PAGE *pagep;
00532 int cmp_n, cmp_p, modified, ret;
00533
00534 pagep = NULL;
00535 COMPQUIET(info, NULL);
00536 REC_PRINT(__bam_cadjust_print);
00537 REC_INTRO(__bam_cadjust_read, 1, 0);
00538
00539
00540 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00541 if (ret != DB_PAGE_NOTFOUND
00542 #ifndef HAVE_FTRUNCATE
00543 || DB_REDO(op)
00544 #endif
00545 ) {
00546 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00547 goto out;
00548 } else
00549 goto done;
00550 }
00551
00552 modified = 0;
00553 cmp_n = log_compare(lsnp, &LSN(pagep));
00554 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
00555 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
00556 if (cmp_p == 0 && DB_REDO(op)) {
00557
00558 if (IS_BTREE_PAGE(pagep)) {
00559 GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs +=
00560 argp->adjust;
00561 if (argp->opflags & CAD_UPDATEROOT)
00562 RE_NREC_ADJ(pagep, argp->adjust);
00563 } else {
00564 GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs +=
00565 argp->adjust;
00566 if (argp->opflags & CAD_UPDATEROOT)
00567 RE_NREC_ADJ(pagep, argp->adjust);
00568 }
00569
00570 LSN(pagep) = *lsnp;
00571 modified = 1;
00572 } else if (cmp_n == 0 && DB_UNDO(op)) {
00573
00574 if (IS_BTREE_PAGE(pagep)) {
00575 GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs -=
00576 argp->adjust;
00577 if (argp->opflags & CAD_UPDATEROOT)
00578 RE_NREC_ADJ(pagep, -(argp->adjust));
00579 } else {
00580 GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs -=
00581 argp->adjust;
00582 if (argp->opflags & CAD_UPDATEROOT)
00583 RE_NREC_ADJ(pagep, -(argp->adjust));
00584 }
00585 LSN(pagep) = argp->lsn;
00586 modified = 1;
00587 }
00588 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00589 goto out;
00590 pagep = NULL;
00591
00592 done: *lsnp = argp->prev_lsn;
00593 ret = 0;
00594
00595 out: if (pagep != NULL)
00596 (void)__memp_fput(mpf, pagep, 0);
00597 REC_CLOSE;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607 int
00608 __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
00609 DB_ENV *dbenv;
00610 DBT *dbtp;
00611 DB_LSN *lsnp;
00612 db_recops op;
00613 void *info;
00614 {
00615 __bam_cdel_args *argp;
00616 DB *file_dbp;
00617 DBC *dbc;
00618 DB_MPOOLFILE *mpf;
00619 PAGE *pagep;
00620 u_int32_t indx;
00621 int cmp_n, cmp_p, modified, ret;
00622
00623 pagep = NULL;
00624 COMPQUIET(info, NULL);
00625 REC_PRINT(__bam_cdel_print);
00626 REC_INTRO(__bam_cdel_read, 1, 0);
00627
00628
00629 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00630 if (ret != DB_PAGE_NOTFOUND
00631 #ifndef HAVE_FTRUNCATE
00632 || DB_REDO(op)
00633 #endif
00634 ) {
00635 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00636 goto out;
00637 } else
00638 goto done;
00639 }
00640
00641 modified = 0;
00642 cmp_n = log_compare(lsnp, &LSN(pagep));
00643 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
00644 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
00645 if (cmp_p == 0 && DB_REDO(op)) {
00646
00647 indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
00648 B_DSET(GET_BKEYDATA(file_dbp, pagep, indx)->type);
00649
00650 LSN(pagep) = *lsnp;
00651 modified = 1;
00652 } else if (cmp_n == 0 && DB_UNDO(op)) {
00653
00654 indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
00655 B_DCLR(GET_BKEYDATA(file_dbp, pagep, indx)->type);
00656
00657 if ((ret = __bam_ca_delete(
00658 file_dbp, argp->pgno, argp->indx, 0, NULL)) != 0)
00659 goto out;
00660
00661 LSN(pagep) = argp->lsn;
00662 modified = 1;
00663 }
00664 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00665 goto out;
00666 pagep = NULL;
00667
00668 done: *lsnp = argp->prev_lsn;
00669 ret = 0;
00670
00671 out: if (pagep != NULL)
00672 (void)__memp_fput(mpf, pagep, 0);
00673 REC_CLOSE;
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683 int
00684 __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
00685 DB_ENV *dbenv;
00686 DBT *dbtp;
00687 DB_LSN *lsnp;
00688 db_recops op;
00689 void *info;
00690 {
00691 __bam_repl_args *argp;
00692 BKEYDATA *bk;
00693 DB *file_dbp;
00694 DBC *dbc;
00695 DBT dbt;
00696 DB_MPOOLFILE *mpf;
00697 PAGE *pagep;
00698 int cmp_n, cmp_p, modified, ret;
00699 u_int8_t *p;
00700
00701 pagep = NULL;
00702 COMPQUIET(info, NULL);
00703 REC_PRINT(__bam_repl_print);
00704 REC_INTRO(__bam_repl_read, 1, 1);
00705
00706
00707 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00708 if (ret != DB_PAGE_NOTFOUND
00709 #ifndef HAVE_FTRUNCATE
00710 || DB_REDO(op)
00711 #endif
00712 ) {
00713 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00714 goto out;
00715 } else
00716 goto done;
00717 }
00718 bk = GET_BKEYDATA(file_dbp, pagep, argp->indx);
00719
00720 modified = 0;
00721 cmp_n = log_compare(lsnp, &LSN(pagep));
00722 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
00723 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
00724 if (cmp_p == 0 && DB_REDO(op)) {
00725
00726
00727
00728
00729
00730 memset(&dbt, 0, sizeof(dbt));
00731 dbt.size = argp->prefix + argp->suffix + argp->repl.size;
00732 if ((ret = __os_malloc(dbenv, dbt.size, &dbt.data)) != 0)
00733 goto out;
00734 p = dbt.data;
00735 memcpy(p, bk->data, argp->prefix);
00736 p += argp->prefix;
00737 memcpy(p, argp->repl.data, argp->repl.size);
00738 p += argp->repl.size;
00739 memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix);
00740
00741 ret = __bam_ritem(dbc, pagep, argp->indx, &dbt);
00742 __os_free(dbenv, dbt.data);
00743 if (ret != 0)
00744 goto out;
00745
00746 LSN(pagep) = *lsnp;
00747 modified = 1;
00748 } else if (cmp_n == 0 && DB_UNDO(op)) {
00749
00750
00751
00752
00753
00754 memset(&dbt, 0, sizeof(dbt));
00755 dbt.size = argp->prefix + argp->suffix + argp->orig.size;
00756 if ((ret = __os_malloc(dbenv, dbt.size, &dbt.data)) != 0)
00757 goto out;
00758 p = dbt.data;
00759 memcpy(p, bk->data, argp->prefix);
00760 p += argp->prefix;
00761 memcpy(p, argp->orig.data, argp->orig.size);
00762 p += argp->orig.size;
00763 memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix);
00764
00765 ret = __bam_ritem(dbc, pagep, argp->indx, &dbt);
00766 __os_free(dbenv, dbt.data);
00767 if (ret != 0)
00768 goto out;
00769
00770
00771 if (argp->isdeleted)
00772 B_DSET(GET_BKEYDATA(file_dbp, pagep, argp->indx)->type);
00773
00774 LSN(pagep) = argp->lsn;
00775 modified = 1;
00776 }
00777 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00778 goto out;
00779 pagep = NULL;
00780
00781 done: *lsnp = argp->prev_lsn;
00782 ret = 0;
00783
00784 out: if (pagep != NULL)
00785 (void)__memp_fput(mpf, pagep, 0);
00786 REC_CLOSE;
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796 int
00797 __bam_root_recover(dbenv, dbtp, lsnp, op, info)
00798 DB_ENV *dbenv;
00799 DBT *dbtp;
00800 DB_LSN *lsnp;
00801 db_recops op;
00802 void *info;
00803 {
00804 __bam_root_args *argp;
00805 BTMETA *meta;
00806 DB *file_dbp;
00807 DBC *dbc;
00808 DB_MPOOLFILE *mpf;
00809 int cmp_n, cmp_p, modified, ret;
00810
00811 meta = NULL;
00812 COMPQUIET(info, NULL);
00813 REC_PRINT(__bam_root_print);
00814 REC_INTRO(__bam_root_read, 0, 0);
00815
00816 if ((ret = __memp_fget(mpf, &argp->meta_pgno, 0, &meta)) != 0) {
00817 if (ret != DB_PAGE_NOTFOUND
00818 #ifndef HAVE_FTRUNCATE
00819 || DB_REDO(op)
00820 #endif
00821 ) {
00822 ret = __db_pgerr(file_dbp, argp->meta_pgno, ret);
00823 goto out;
00824 } else
00825 goto done;
00826 }
00827
00828 modified = 0;
00829 cmp_n = log_compare(lsnp, &LSN(meta));
00830 cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
00831 CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn);
00832 if (cmp_p == 0 && DB_REDO(op)) {
00833
00834 meta->root = argp->root_pgno;
00835 meta->dbmeta.lsn = *lsnp;
00836 ((BTREE *)file_dbp->bt_internal)->bt_root = meta->root;
00837 modified = 1;
00838 } else if (cmp_n == 0 && DB_UNDO(op)) {
00839
00840 meta->dbmeta.lsn = argp->meta_lsn;
00841 modified = 1;
00842 }
00843 if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00844 goto out;
00845 meta = NULL;
00846
00847 done: *lsnp = argp->prev_lsn;
00848 ret = 0;
00849
00850 out: if (meta != NULL)
00851 (void)__memp_fput(mpf, meta, 0);
00852 REC_CLOSE;
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 int
00864 __bam_curadj_recover(dbenv, dbtp, lsnp, op, info)
00865 DB_ENV *dbenv;
00866 DBT *dbtp;
00867 DB_LSN *lsnp;
00868 db_recops op;
00869 void *info;
00870 {
00871 __bam_curadj_args *argp;
00872 DB *file_dbp;
00873 DBC *dbc;
00874 DB_MPOOLFILE *mpf;
00875 int ret;
00876
00877 COMPQUIET(info, NULL);
00878 COMPQUIET(mpf, NULL);
00879
00880 REC_PRINT(__bam_curadj_print);
00881 REC_INTRO(__bam_curadj_read, 0, 1);
00882
00883 ret = 0;
00884 if (op != DB_TXN_ABORT)
00885 goto done;
00886
00887 switch (argp->mode) {
00888 case DB_CA_DI:
00889 if ((ret = __bam_ca_di(dbc, argp->from_pgno,
00890 argp->from_indx, -(int)argp->first_indx)) != 0)
00891 goto out;
00892 break;
00893 case DB_CA_DUP:
00894 if ((ret = __bam_ca_undodup(file_dbp, argp->first_indx,
00895 argp->from_pgno, argp->from_indx, argp->to_indx)) != 0)
00896 goto out;
00897 break;
00898
00899 case DB_CA_RSPLIT:
00900 if ((ret =
00901 __bam_ca_rsplit(dbc, argp->to_pgno, argp->from_pgno)) != 0)
00902 goto out;
00903 break;
00904
00905 case DB_CA_SPLIT:
00906 if ((ret = __bam_ca_undosplit(file_dbp, argp->from_pgno,
00907 argp->to_pgno, argp->left_pgno, argp->from_indx)) != 0)
00908 goto out;
00909 break;
00910 }
00911
00912 done: *lsnp = argp->prev_lsn;
00913 out: REC_CLOSE;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 int
00925 __bam_rcuradj_recover(dbenv, dbtp, lsnp, op, info)
00926 DB_ENV *dbenv;
00927 DBT *dbtp;
00928 DB_LSN *lsnp;
00929 db_recops op;
00930 void *info;
00931 {
00932 __bam_rcuradj_args *argp;
00933 BTREE_CURSOR *cp;
00934 DB *file_dbp;
00935 DBC *dbc, *rdbc;
00936 DB_MPOOLFILE *mpf;
00937 int ret, t_ret;
00938
00939 COMPQUIET(info, NULL);
00940 COMPQUIET(mpf, NULL);
00941 rdbc = NULL;
00942
00943 REC_PRINT(__bam_rcuradj_print);
00944 REC_INTRO(__bam_rcuradj_read, 0, 1);
00945
00946 ret = t_ret = 0;
00947
00948 if (op != DB_TXN_ABORT)
00949 goto done;
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 if ((ret = __db_cursor_int(file_dbp,
00962 NULL, DB_RECNO, argp->root, 0, DB_LOCK_INVALIDID, &rdbc)) != 0)
00963 goto out;
00964
00965 cp = (BTREE_CURSOR *)rdbc->internal;
00966 F_SET(cp, C_RENUMBER);
00967 cp->recno = argp->recno;
00968
00969 switch (argp->mode) {
00970 case CA_DELETE:
00971
00972
00973
00974
00975 F_SET(cp, C_DELETED);
00976 F_SET(cp, C_RENUMBER);
00977 cp->order = argp->order;
00978 (void)__ram_ca(rdbc, CA_ICURRENT);
00979 break;
00980 case CA_IAFTER:
00981 case CA_IBEFORE:
00982 case CA_ICURRENT:
00983
00984
00985
00986
00987 F_CLR(cp, C_DELETED);
00988 cp->order = INVALID_ORDER;
00989 (void)__ram_ca(rdbc, CA_DELETE);
00990 break;
00991 }
00992
00993 done: *lsnp = argp->prev_lsn;
00994 out: if (rdbc != NULL && (t_ret = __db_c_close(rdbc)) != 0 && ret == 0)
00995 ret = t_ret;
00996 REC_CLOSE;
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006 int
01007 __bam_relink_recover(dbenv, dbtp, lsnp, op, info)
01008 DB_ENV *dbenv;
01009 DBT *dbtp;
01010 DB_LSN *lsnp;
01011 db_recops op;
01012 void *info;
01013 {
01014 __bam_relink_args *argp;
01015 DB *file_dbp;
01016 DBC *dbc;
01017 DB_MPOOLFILE *mpf;
01018 PAGE *pagep;
01019 int cmp_n, cmp_p, modified, ret;
01020
01021 pagep = NULL;
01022 COMPQUIET(info, NULL);
01023 REC_PRINT(__bam_relink_print);
01024 REC_INTRO(__bam_relink_read, 1, 0);
01025
01026
01027
01028
01029
01030
01031
01032 if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
01033 if (ret != DB_PAGE_NOTFOUND
01034 #ifndef HAVE_FTRUNCATE
01035 || DB_REDO(op)
01036 #endif
01037 ) {
01038 ret = __db_pgerr(file_dbp, argp->next, ret);
01039 goto out;
01040 } else
01041 goto prev;
01042 }
01043
01044 modified = 0;
01045 cmp_n = log_compare(lsnp, &LSN(pagep));
01046 cmp_p = log_compare(&LSN(pagep), &argp->lsn_next);
01047 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_next);
01048 if (cmp_p == 0 && DB_REDO(op)) {
01049
01050 if (argp->new_pgno == PGNO_INVALID)
01051 pagep->prev_pgno = argp->prev;
01052 else
01053 pagep->prev_pgno = argp->new_pgno;
01054
01055 pagep->lsn = *lsnp;
01056 modified = 1;
01057 } else if (cmp_n == 0 && DB_UNDO(op)) {
01058
01059 pagep->prev_pgno = argp->pgno;
01060
01061 pagep->lsn = argp->lsn_next;
01062 modified = 1;
01063 }
01064
01065 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
01066 goto out;
01067 pagep = NULL;
01068
01069 prev: if ((ret = __memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
01070 if (ret != DB_PAGE_NOTFOUND
01071 #ifndef HAVE_FTRUNCATE
01072 || DB_REDO(op)
01073 #endif
01074 ) {
01075 ret = __db_pgerr(file_dbp, argp->prev, ret);
01076 goto out;
01077 } else
01078 goto done;
01079 }
01080
01081 modified = 0;
01082 cmp_p = log_compare(&LSN(pagep), &argp->lsn_prev);
01083 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_prev);
01084 if (cmp_p == 0 && DB_REDO(op)) {
01085
01086 if (argp->new_pgno == PGNO_INVALID)
01087 pagep->next_pgno = argp->next;
01088 else
01089 pagep->next_pgno = argp->new_pgno;
01090
01091 pagep->lsn = *lsnp;
01092 modified = 1;
01093 } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
01094
01095 pagep->next_pgno = argp->pgno;
01096 pagep->lsn = argp->lsn_prev;
01097
01098 modified = 1;
01099 }
01100
01101 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
01102 goto out;
01103 pagep = NULL;
01104
01105 done: *lsnp = argp->prev_lsn;
01106 ret = 0;
01107
01108 out: if (pagep != NULL)
01109 (void)__memp_fput(mpf, pagep, 0);
01110 REC_CLOSE;
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120 int
01121 __bam_merge_recover(dbenv, dbtp, lsnp, op, info)
01122 DB_ENV *dbenv;
01123 DBT *dbtp;
01124 DB_LSN *lsnp;
01125 db_recops op;
01126 void *info;
01127 {
01128 __bam_merge_args *argp;
01129 BKEYDATA *bk;
01130 DB *file_dbp;
01131 DBC *dbc;
01132 DB_MPOOLFILE *mpf;
01133 PAGE *pagep;
01134 db_indx_t indx, *ninp, *pinp;
01135 u_int32_t size;
01136 u_int8_t *bp;
01137 int cmp_n, cmp_p, i, modified, ret;
01138
01139 COMPQUIET(info, NULL);
01140
01141 REC_PRINT(__bam_merge_print);
01142 REC_INTRO(__bam_merge_read, 1, 1);
01143
01144 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
01145 if (ret != DB_PAGE_NOTFOUND
01146 #ifndef HAVE_FTRUNCATE
01147 || DB_REDO(op)
01148 #endif
01149 ) {
01150 ret = __db_pgerr(file_dbp, argp->pgno, ret);
01151 goto out;
01152 } else
01153 goto next;
01154 }
01155
01156 modified = 0;
01157 cmp_n = log_compare(lsnp, &LSN(pagep));
01158 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
01159 CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
01160
01161 if (cmp_p == 0 && DB_REDO(op)) {
01162
01163
01164
01165
01166 DB_ASSERT(argp->hdr.size == 0 || NUM_ENT(pagep) == 0);
01167 if (argp->hdr.size != 0) {
01168 P_INIT(pagep, file_dbp->pgsize, pagep->pgno,
01169 PREV_PGNO(argp->hdr.data),
01170 NEXT_PGNO(argp->hdr.data),
01171 LEVEL(argp->hdr.data), TYPE(argp->hdr.data));
01172 }
01173 if (TYPE(pagep) == P_OVERFLOW) {
01174 OV_REF(pagep) = OV_REF(argp->hdr.data);
01175 OV_LEN(pagep) = OV_LEN(argp->hdr.data);
01176 bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp);
01177 memcpy(bp, argp->data.data, argp->data.size);
01178 } else {
01179
01180 bp = (u_int8_t *)pagep +
01181 (db_indx_t)(HOFFSET(pagep) - argp->data.size);
01182 memcpy(bp, argp->data.data, argp->data.size);
01183
01184
01185 pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep);
01186 ninp = argp->ind.data;
01187 for (i = 0;
01188 i < (int)(argp->ind.size / sizeof(*ninp)); i++)
01189 *pinp++ = *ninp++
01190 - (file_dbp->pgsize - HOFFSET(pagep));
01191 HOFFSET(pagep) -= argp->data.size;
01192 NUM_ENT(pagep) += i;
01193 }
01194 pagep->lsn = *lsnp;
01195 modified = 1;
01196 } else if (cmp_n == 0 && !DB_REDO(op)) {
01197
01198
01199
01200
01201
01202
01203 for (i = 0; i < (int)(argp->ind.size / sizeof(*ninp)); i++) {
01204 indx = NUM_ENT(pagep) - 1;
01205 if (P_INP(file_dbp, pagep)[indx] ==
01206 P_INP(file_dbp, pagep)[indx - P_INDX]) {
01207 NUM_ENT(pagep)--;
01208 continue;
01209 }
01210 switch (TYPE(pagep)) {
01211 case P_LBTREE:
01212 case P_LRECNO:
01213 case P_LDUP:
01214 bk = GET_BKEYDATA(file_dbp, pagep, indx);
01215 size = BITEM_SIZE(bk);
01216 break;
01217
01218 case P_IBTREE:
01219 size = BINTERNAL_SIZE(
01220 GET_BINTERNAL(file_dbp, pagep, indx)->len);
01221 break;
01222 case P_IRECNO:
01223 size = RINTERNAL_SIZE;
01224 break;
01225
01226 default:
01227 ret = __db_pgfmt(dbenv, PGNO(pagep));
01228 goto out;
01229 }
01230 if ((ret =
01231 __db_ditem(dbc, pagep, indx, size)) != 0)
01232 goto out;
01233 }
01234 if (argp->ind.size == 0)
01235 HOFFSET(pagep) = file_dbp->pgsize;
01236 pagep->lsn = argp->lsn;
01237 modified = 1;
01238 }
01239
01240 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
01241 goto out;
01242
01243 next: if ((ret = __memp_fget(mpf, &argp->npgno, 0, &pagep)) != 0) {
01244 if (ret != DB_PAGE_NOTFOUND
01245 #ifndef HAVE_FTRUNCATE
01246 || DB_REDO(op)
01247 #endif
01248 ) {
01249 ret = __db_pgerr(file_dbp, argp->pgno, ret);
01250 goto out;
01251 } else
01252 goto done;
01253 }
01254
01255 modified = 0;
01256 cmp_n = log_compare(lsnp, &LSN(pagep));
01257 cmp_p = log_compare(&LSN(pagep), &argp->nlsn);
01258 CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->nlsn);
01259
01260 if (cmp_p == 0 && DB_REDO(op)) {
01261
01262 HOFFSET(pagep) = file_dbp->pgsize;
01263 NUM_ENT(pagep) = 0;
01264 pagep->lsn = *lsnp;
01265 modified = 1;
01266 } else if (cmp_n == 0 && !DB_REDO(op)) {
01267
01268 if (TYPE(pagep) == P_OVERFLOW) {
01269 OV_REF(pagep) = OV_REF(argp->hdr.data);
01270 OV_LEN(pagep) = OV_LEN(argp->hdr.data);
01271 bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp);
01272 memcpy(bp, argp->data.data, argp->data.size);
01273 } else {
01274 bp = (u_int8_t *)pagep +
01275 (db_indx_t)(HOFFSET(pagep) - argp->data.size);
01276 memcpy(bp, argp->data.data, argp->data.size);
01277
01278
01279 pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep);
01280 ninp = argp->ind.data;
01281 for (i = 0;
01282 i < (int)(argp->ind.size / sizeof(*ninp)); i++)
01283 *pinp++ = *ninp++;
01284 HOFFSET(pagep) -= argp->data.size;
01285 NUM_ENT(pagep) = i;
01286 }
01287 pagep->lsn = argp->nlsn;
01288 modified = 1;
01289 }
01290
01291 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
01292 goto out;
01293 done:
01294 *lsnp = argp->prev_lsn;
01295 ret = 0;
01296
01297 out: REC_CLOSE;
01298 }
01299
01300
01301
01302
01303
01304
01305
01306
01307 int
01308 __bam_pgno_recover(dbenv, dbtp, lsnp, op, info)
01309 DB_ENV *dbenv;
01310 DBT *dbtp;
01311 DB_LSN *lsnp;
01312 db_recops op;
01313 void *info;
01314 {
01315 BINTERNAL *bi;
01316 __bam_pgno_args *argp;
01317 DB *file_dbp;
01318 DBC *dbc;
01319 DB_MPOOLFILE *mpf;
01320 PAGE *pagep, *npagep;
01321 db_pgno_t *pgnop;
01322 int cmp_n, cmp_p, modified, ret;
01323
01324 COMPQUIET(info, NULL);
01325
01326 REC_PRINT(__bam_pgno_print);
01327 REC_INTRO(__bam_pgno_read, 1, 0);
01328
01329 REC_FGET(mpf, argp->pgno, &pagep, done);
01330
01331 modified = 0;
01332 cmp_n = log_compare(lsnp, &LSN(pagep));
01333 cmp_p = log_compare(&LSN(pagep), &argp->lsn);
01334 CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
01335
01336 if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && !DB_REDO(op))) {
01337 switch (TYPE(pagep)) {
01338 case P_IBTREE:
01339
01340
01341
01342
01343
01344 bi = GET_BINTERNAL(file_dbp, pagep, argp->indx);
01345 if (B_TYPE(bi->type) == B_OVERFLOW) {
01346 REC_FGET(mpf, argp->npgno, &npagep, out);
01347
01348 if (TYPE(npagep) == P_OVERFLOW)
01349 pgnop =
01350 &((BOVERFLOW *)(bi->data))->pgno;
01351 else
01352 pgnop = &bi->pgno;
01353 if ((ret = __memp_fput(mpf, npagep, 0)) != 0)
01354 goto out;
01355 break;
01356 }
01357 pgnop = &bi->pgno;
01358 break;
01359 case P_IRECNO:
01360 pgnop =
01361 &GET_RINTERNAL(file_dbp, pagep, argp->indx)->pgno;
01362 break;
01363 default:
01364 pgnop =
01365 &GET_BOVERFLOW(file_dbp, pagep, argp->indx)->pgno;
01366 break;
01367 }
01368
01369 if (DB_REDO(op)) {
01370
01371 *pgnop = argp->npgno;
01372 pagep->lsn = *lsnp;
01373 modified = 1;
01374 } else {
01375 *pgnop = argp->opgno;
01376 pagep->lsn = argp->lsn;
01377 modified = 1;
01378 }
01379 }
01380
01381 if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
01382 goto out;
01383
01384 done:
01385 *lsnp = argp->prev_lsn;
01386 ret = 0;
01387
01388 out: REC_CLOSE;
01389 }