00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "db_config.h"
00046
00047 #ifndef NO_SYSTEM_INCLUDES
00048 #include <sys/types.h>
00049
00050 #include <string.h>
00051 #endif
00052
00053 #include "db_int.h"
00054 #include "dbinc/db_page.h"
00055 #include "dbinc/db_shash.h"
00056 #include "dbinc/btree.h"
00057 #include "dbinc/hash.h"
00058 #include "dbinc/log.h"
00059 #include "dbinc/mp.h"
00060
00061 static int __ham_alloc_pages __P((DB *, __ham_groupalloc_args *, DB_LSN *));
00062
00063
00064
00065
00066
00067
00068
00069 int
00070 __ham_insdel_recover(dbenv, dbtp, lsnp, op, info)
00071 DB_ENV *dbenv;
00072 DBT *dbtp;
00073 DB_LSN *lsnp;
00074 db_recops op;
00075 void *info;
00076 {
00077 __ham_insdel_args *argp;
00078 DB *file_dbp;
00079 DBC *dbc;
00080 DB_MPOOLFILE *mpf;
00081 PAGE *pagep;
00082 u_int32_t flags, opcode;
00083 int cmp_n, cmp_p, ret, type;
00084
00085 pagep = NULL;
00086 COMPQUIET(info, NULL);
00087
00088 REC_PRINT(__ham_insdel_print);
00089 REC_INTRO(__ham_insdel_read, 1, 0);
00090
00091 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00092 if (DB_UNDO(op)) {
00093 if (ret == DB_PAGE_NOTFOUND)
00094 goto done;
00095 else {
00096 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00097 goto out;
00098 }
00099 }
00100 #ifdef HAVE_FTRUNCATE
00101
00102 if (!IS_ZERO_LSN(argp->pagelsn))
00103 goto done;
00104 #endif
00105
00106
00107
00108
00109
00110 if ((ret = __memp_fget(mpf,
00111 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
00112 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00113 goto out;
00114 }
00115 }
00116
00117 cmp_n = log_compare(lsnp, &LSN(pagep));
00118 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00119 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 opcode = OPCODE_OF(argp->opcode);
00132 flags = 0;
00133 if ((opcode == DELPAIR && cmp_n == 0 && DB_UNDO(op)) ||
00134 (opcode == PUTPAIR && cmp_p == 0 && DB_REDO(op))) {
00135
00136
00137
00138
00139
00140
00141 if (opcode != DELPAIR ||
00142 argp->ndx == (u_int32_t)NUM_ENT(pagep)) {
00143 __ham_putitem(file_dbp, pagep, &argp->key,
00144 DB_UNDO(op) || PAIR_ISKEYBIG(argp->opcode) ?
00145 H_OFFPAGE : H_KEYDATA);
00146
00147 if (PAIR_ISDATADUP(argp->opcode))
00148 type = H_DUPLICATE;
00149 else if (DB_UNDO(op) || PAIR_ISDATABIG(argp->opcode))
00150 type = H_OFFPAGE;
00151 else
00152 type = H_KEYDATA;
00153 __ham_putitem(file_dbp, pagep, &argp->data, type);
00154 } else
00155 __ham_reputpair(file_dbp, pagep,
00156 argp->ndx, &argp->key, &argp->data);
00157
00158 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00159 flags = DB_MPOOL_DIRTY;
00160
00161 } else if ((opcode == DELPAIR && cmp_p == 0 && DB_REDO(op)) ||
00162 (opcode == PUTPAIR && cmp_n == 0 && DB_UNDO(op))) {
00163
00164 __ham_dpair(file_dbp, pagep, argp->ndx);
00165 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00166 flags = DB_MPOOL_DIRTY;
00167 }
00168
00169 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00170 goto out;
00171 pagep = NULL;
00172
00173
00174 done: *lsnp = argp->prev_lsn;
00175 ret = 0;
00176
00177 out: if (pagep != NULL)
00178 (void)__memp_fput(mpf, pagep, 0);
00179 REC_CLOSE;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 int
00191 __ham_newpage_recover(dbenv, dbtp, lsnp, op, info)
00192 DB_ENV *dbenv;
00193 DBT *dbtp;
00194 DB_LSN *lsnp;
00195 db_recops op;
00196 void *info;
00197 {
00198 __ham_newpage_args *argp;
00199 DB *file_dbp;
00200 DBC *dbc;
00201 DB_MPOOLFILE *mpf;
00202 PAGE *pagep;
00203 u_int32_t flags;
00204 int cmp_n, cmp_p, ret;
00205
00206 pagep = NULL;
00207 COMPQUIET(info, NULL);
00208
00209 REC_PRINT(__ham_newpage_print);
00210 REC_INTRO(__ham_newpage_read, 1, 0);
00211
00212 REC_FGET(mpf, argp->new_pgno, &pagep, ppage);
00213
00214
00215
00216
00217
00218
00219
00220 cmp_n = log_compare(lsnp, &LSN(pagep));
00221 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00222 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00223
00224 flags = 0;
00225 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00226 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00227
00228 P_INIT(pagep, file_dbp->pgsize, argp->new_pgno,
00229 argp->prev_pgno, argp->next_pgno, 0, P_HASH);
00230 flags = DB_MPOOL_DIRTY;
00231 } else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) ||
00232 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00233
00234
00235
00236
00237 flags = DB_MPOOL_DIRTY;
00238 }
00239
00240 if (flags)
00241 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00242
00243 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00244 goto out;
00245 pagep = NULL;
00246
00247
00248 ppage: if (argp->prev_pgno != PGNO_INVALID) {
00249 REC_FGET(mpf, argp->prev_pgno, &pagep, npage);
00250
00251 cmp_n = log_compare(lsnp, &LSN(pagep));
00252 cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
00253 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn);
00254 flags = 0;
00255
00256 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00257 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00258
00259 pagep->next_pgno = argp->new_pgno;
00260 flags = DB_MPOOL_DIRTY;
00261 } else if ((cmp_p == 0 &&
00262 DB_REDO(op) && argp->opcode == DELOVFL) ||
00263 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00264
00265 pagep->next_pgno = argp->next_pgno;
00266 flags = DB_MPOOL_DIRTY;
00267 }
00268
00269 if (flags)
00270 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn;
00271
00272 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00273 goto out;
00274 pagep = NULL;
00275 }
00276
00277
00278 npage: if (argp->next_pgno != PGNO_INVALID) {
00279 REC_FGET(mpf, argp->next_pgno, &pagep, done);
00280
00281 cmp_n = log_compare(lsnp, &LSN(pagep));
00282 cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
00283 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn);
00284 flags = 0;
00285
00286 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00287 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00288
00289 pagep->prev_pgno = argp->new_pgno;
00290 flags = DB_MPOOL_DIRTY;
00291 } else if ((cmp_p == 0 &&
00292 DB_REDO(op) && argp->opcode == DELOVFL) ||
00293 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00294
00295 pagep->prev_pgno = argp->prev_pgno;
00296 flags = DB_MPOOL_DIRTY;
00297 }
00298
00299 if (flags)
00300 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn;
00301
00302 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00303 goto out;
00304 pagep = NULL;
00305 }
00306 done: *lsnp = argp->prev_lsn;
00307 ret = 0;
00308
00309 out: if (pagep != NULL)
00310 (void)__memp_fput(mpf, pagep, 0);
00311 REC_CLOSE;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 int
00324 __ham_replace_recover(dbenv, dbtp, lsnp, op, info)
00325 DB_ENV *dbenv;
00326 DBT *dbtp;
00327 DB_LSN *lsnp;
00328 db_recops op;
00329 void *info;
00330 {
00331 __ham_replace_args *argp;
00332 DB *file_dbp;
00333 DBC *dbc;
00334 DB_MPOOLFILE *mpf;
00335 DBT dbt;
00336 PAGE *pagep;
00337 u_int32_t flags;
00338 u_int32_t change;
00339 int cmp_n, cmp_p, is_plus, ret;
00340 u_int8_t *hk;
00341
00342 pagep = NULL;
00343 COMPQUIET(info, NULL);
00344
00345 REC_PRINT(__ham_replace_print);
00346 REC_INTRO(__ham_replace_read, 1, 0);
00347
00348 REC_FGET(mpf, argp->pgno, &pagep, done);
00349
00350 cmp_n = log_compare(lsnp, &LSN(pagep));
00351 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00352 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00353
00354 memset(&dbt, 0, sizeof(dbt));
00355 flags = 0;
00356
00357
00358
00359
00360
00361
00362 if (argp->newitem.size > argp->olditem.size) {
00363 change = argp->newitem.size - argp->olditem.size;
00364 is_plus = 1;
00365 } else {
00366 change = argp->olditem.size - argp->newitem.size;
00367 is_plus = 0;
00368 }
00369 if (cmp_p == 0 && DB_REDO(op)) {
00370
00371 dbt.data = argp->newitem.data;
00372 dbt.size = argp->newitem.size;
00373 LSN(pagep) = *lsnp;
00374
00375
00376
00377
00378 flags = DB_MPOOL_DIRTY;
00379 } else if (cmp_n == 0 && DB_UNDO(op)) {
00380
00381 dbt.data = argp->olditem.data;
00382 dbt.size = argp->olditem.size;
00383
00384
00385
00386
00387 is_plus = !is_plus;
00388 LSN(pagep) = argp->pagelsn;
00389 flags = DB_MPOOL_DIRTY;
00390 }
00391
00392 if (flags) {
00393 __ham_onpage_replace(file_dbp, pagep,
00394 argp->ndx, argp->off, change, is_plus, &dbt);
00395 if (argp->makedup) {
00396 hk = P_ENTRY(file_dbp, pagep, argp->ndx);
00397 if (DB_REDO(op))
00398 HPAGE_PTYPE(hk) = H_DUPLICATE;
00399 else
00400 HPAGE_PTYPE(hk) = H_KEYDATA;
00401 }
00402 }
00403
00404 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00405 goto out;
00406 pagep = NULL;
00407
00408 done: *lsnp = argp->prev_lsn;
00409 ret = 0;
00410
00411 out: if (pagep != NULL)
00412 (void)__memp_fput(mpf, pagep, 0);
00413 REC_CLOSE;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422 int
00423 __ham_splitdata_recover(dbenv, dbtp, lsnp, op, info)
00424 DB_ENV *dbenv;
00425 DBT *dbtp;
00426 DB_LSN *lsnp;
00427 db_recops op;
00428 void *info;
00429 {
00430 __ham_splitdata_args *argp;
00431 DB *file_dbp;
00432 DBC *dbc;
00433 DB_MPOOLFILE *mpf;
00434 PAGE *pagep;
00435 u_int32_t flags;
00436 int cmp_n, cmp_p, ret;
00437
00438 pagep = NULL;
00439 COMPQUIET(info, NULL);
00440
00441 REC_PRINT(__ham_splitdata_print);
00442 REC_INTRO(__ham_splitdata_read, 1, 0);
00443
00444 if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00445 if (DB_UNDO(op)) {
00446 if (ret == DB_PAGE_NOTFOUND)
00447 goto done;
00448 else {
00449 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00450 goto out;
00451 }
00452 }
00453 #ifdef HAVE_FTRUNCATE
00454
00455 if (!IS_ZERO_LSN(argp->pagelsn))
00456 goto done;
00457 #endif
00458
00459
00460
00461
00462
00463 if ((ret = __memp_fget(mpf,
00464 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
00465 ret = __db_pgerr(file_dbp, argp->pgno, ret);
00466 goto out;
00467 }
00468 }
00469
00470 cmp_n = log_compare(lsnp, &LSN(pagep));
00471 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00472 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 flags = 0;
00485 if (cmp_p == 0 && DB_REDO(op)) {
00486 if (argp->opcode == SPLITNEW)
00487
00488 memcpy(pagep, argp->pageimage.data,
00489 argp->pageimage.size);
00490 LSN(pagep) = *lsnp;
00491 flags = DB_MPOOL_DIRTY;
00492 } else if (cmp_n == 0 && DB_UNDO(op)) {
00493 if (argp->opcode == SPLITOLD) {
00494
00495 memcpy(pagep, argp->pageimage.data,
00496 argp->pageimage.size);
00497 } else
00498 P_INIT(pagep, file_dbp->pgsize, argp->pgno,
00499 PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
00500 LSN(pagep) = argp->pagelsn;
00501 flags = DB_MPOOL_DIRTY;
00502 }
00503 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00504 goto out;
00505 pagep = NULL;
00506
00507 done: *lsnp = argp->prev_lsn;
00508 ret = 0;
00509
00510 out: if (pagep != NULL)
00511 (void)__memp_fput(mpf, pagep, 0);
00512 REC_CLOSE;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522 int
00523 __ham_copypage_recover(dbenv, dbtp, lsnp, op, info)
00524 DB_ENV *dbenv;
00525 DBT *dbtp;
00526 DB_LSN *lsnp;
00527 db_recops op;
00528 void *info;
00529 {
00530 __ham_copypage_args *argp;
00531 DB *file_dbp;
00532 DBC *dbc;
00533 DB_MPOOLFILE *mpf;
00534 PAGE *pagep;
00535 u_int32_t flags;
00536 int cmp_n, cmp_p, ret;
00537
00538 pagep = NULL;
00539 COMPQUIET(info, NULL);
00540
00541 REC_PRINT(__ham_copypage_print);
00542 REC_INTRO(__ham_copypage_read, 1, 0);
00543
00544 flags = 0;
00545
00546
00547 REC_FGET(mpf, argp->pgno, &pagep, donext);
00548
00549 cmp_n = log_compare(lsnp, &LSN(pagep));
00550 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00551 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00552
00553 if (cmp_p == 0 && DB_REDO(op)) {
00554
00555 memcpy(pagep, argp->page.data, argp->page.size);
00556 PGNO(pagep) = argp->pgno;
00557 PREV_PGNO(pagep) = PGNO_INVALID;
00558 LSN(pagep) = *lsnp;
00559 flags = DB_MPOOL_DIRTY;
00560 } else if (cmp_n == 0 && DB_UNDO(op)) {
00561
00562 P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
00563 argp->next_pgno, 0, P_HASH);
00564 LSN(pagep) = argp->pagelsn;
00565 flags = DB_MPOOL_DIRTY;
00566 }
00567 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00568 goto out;
00569 pagep = NULL;
00570
00571 donext:
00572 REC_FGET(mpf, argp->next_pgno, &pagep, do_nn);
00573
00574
00575 cmp_n = log_compare(lsnp, &LSN(pagep));
00576 cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
00577 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn);
00578 flags = 0;
00579 if (cmp_p == 0 && DB_REDO(op)) {
00580 LSN(pagep) = *lsnp;
00581 flags = DB_MPOOL_DIRTY;
00582 } else if (cmp_n == 0 && DB_UNDO(op)) {
00583
00584 memcpy(pagep, argp->page.data, argp->page.size);
00585 flags = DB_MPOOL_DIRTY;
00586 }
00587 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00588 goto out;
00589 pagep = NULL;
00590
00591
00592 do_nn: if (argp->nnext_pgno == PGNO_INVALID)
00593 goto done;
00594
00595 REC_FGET(mpf, argp->nnext_pgno, &pagep, done);
00596
00597 cmp_n = log_compare(lsnp, &LSN(pagep));
00598 cmp_p = log_compare(&LSN(pagep), &argp->nnextlsn);
00599 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nnextlsn);
00600
00601 flags = 0;
00602 if (cmp_p == 0 && DB_REDO(op)) {
00603
00604 PREV_PGNO(pagep) = argp->pgno;
00605 LSN(pagep) = *lsnp;
00606 flags = DB_MPOOL_DIRTY;
00607 } else if (cmp_n == 0 && DB_UNDO(op)) {
00608
00609 PREV_PGNO(pagep) = argp->next_pgno;
00610 LSN(pagep) = argp->nnextlsn;
00611 flags = DB_MPOOL_DIRTY;
00612 }
00613 if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
00614 goto out;
00615 pagep = NULL;
00616
00617 done: *lsnp = argp->prev_lsn;
00618 ret = 0;
00619
00620 out: if (pagep != NULL)
00621 (void)__memp_fput(mpf, pagep, 0);
00622 REC_CLOSE;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632 int
00633 __ham_metagroup_recover(dbenv, dbtp, lsnp, op, info)
00634 DB_ENV *dbenv;
00635 DBT *dbtp;
00636 DB_LSN *lsnp;
00637 db_recops op;
00638 void *info;
00639 {
00640 __ham_metagroup_args *argp;
00641 HASH_CURSOR *hcp;
00642 DB *file_dbp;
00643 DBMETA *mmeta;
00644 DBC *dbc;
00645 DB_MPOOLFILE *mpf;
00646 PAGE *pagep;
00647 db_pgno_t pgno;
00648 u_int32_t flags, mmeta_flags;
00649 int cmp_n, cmp_p, did_alloc, did_recover, groupgrow, ret;
00650
00651 COMPQUIET(info, NULL);
00652 mmeta_flags = 0;
00653 did_alloc = 0;
00654 mmeta = NULL;
00655 REC_PRINT(__ham_metagroup_print);
00656 REC_INTRO(__ham_metagroup_read, 1, 1);
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 groupgrow =
00676 (u_int32_t)(1 << __db_log2(argp->bucket + 1)) == argp->bucket + 1;
00677 pgno = argp->pgno;
00678 if (argp->newalloc)
00679 pgno += argp->bucket;
00680
00681 flags = 0;
00682 pagep = NULL;
00683 #ifndef HAVE_FTRUNCATE
00684 flags = DB_MPOOL_CREATE;
00685 #endif
00686 ret = __memp_fget(mpf, &pgno, flags, &pagep);
00687
00688 #ifdef HAVE_FTRUNCATE
00689
00690 if (ret != 0 && DB_REDO(op))
00691 ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep);
00692 else if (ret == DB_PAGE_NOTFOUND)
00693 goto do_meta;
00694 #endif
00695 if (ret != 0) {
00696 if (ret != ENOSPC)
00697 goto out;
00698 pgno = 0;
00699 goto do_meta;
00700 }
00701
00702
00703
00704
00705
00706
00707 did_alloc = groupgrow;
00708
00709 cmp_n = log_compare(lsnp, &LSN(pagep));
00710 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
00711 CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
00712
00713 flags = 0;
00714 if (cmp_p == 0 && DB_REDO(op)) {
00715 pagep->lsn = *lsnp;
00716 flags = DB_MPOOL_DIRTY;
00717 } else if (cmp_n == 0 && DB_UNDO(op)) {
00718 #ifdef HAVE_FTRUNCATE
00719
00720 if (argp->newalloc) {
00721 if (pagep != NULL && (ret =
00722 __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
00723 goto out;
00724 pagep = NULL;
00725 if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)
00726 goto out;
00727 } else
00728 #endif
00729 {
00730
00731
00732
00733
00734 pagep->lsn = argp->pagelsn;
00735 flags = DB_MPOOL_DIRTY;
00736 }
00737 }
00738 if (pagep != NULL && (ret = __memp_fput(mpf, pagep, flags)) != 0)
00739 goto out;
00740
00741 do_meta:
00742
00743 hcp = (HASH_CURSOR *)dbc->internal;
00744 if ((ret = __ham_get_meta(dbc)) != 0)
00745 goto out;
00746 cmp_n = log_compare(lsnp, &hcp->hdr->dbmeta.lsn);
00747 cmp_p = log_compare(&hcp->hdr->dbmeta.lsn, &argp->metalsn);
00748 CHECK_LSN(dbenv, op, cmp_p, &hcp->hdr->dbmeta.lsn, &argp->metalsn);
00749 did_recover = 0;
00750 if (cmp_p == 0 && DB_REDO(op)) {
00751
00752 ++hcp->hdr->max_bucket;
00753 if (groupgrow) {
00754 hcp->hdr->low_mask = hcp->hdr->high_mask;
00755 hcp->hdr->high_mask =
00756 (argp->bucket + 1) | hcp->hdr->low_mask;
00757 }
00758 hcp->hdr->dbmeta.lsn = *lsnp;
00759 did_recover = 1;
00760 } else if (cmp_n == 0 && DB_UNDO(op)) {
00761
00762 hcp->hdr->max_bucket = argp->bucket;
00763 if (groupgrow) {
00764 hcp->hdr->high_mask = argp->bucket;
00765 hcp->hdr->low_mask = hcp->hdr->high_mask >> 1;
00766 }
00767 hcp->hdr->dbmeta.lsn = argp->metalsn;
00768 did_recover = 1;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 if (did_alloc &&
00780 #ifdef HAVE_FTRUNCATE
00781 !DB_UNDO(op) &&
00782 #endif
00783 hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] == PGNO_INVALID) {
00784 hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] =
00785 (argp->pgno - argp->bucket) - 1;
00786 did_recover = 1;
00787 }
00788 #ifdef HAVE_FTRUNCATE
00789 if (cmp_n == 0 && groupgrow && DB_UNDO(op)) {
00790 hcp->hdr->spares[
00791 __db_log2(argp->bucket + 1) + 1] = PGNO_INVALID;
00792 did_recover = 1;
00793 }
00794 #endif
00795
00796
00797
00798
00799
00800
00801 if (argp->mmpgno != argp->mpgno) {
00802 if ((ret = __memp_fget(mpf, &argp->mmpgno, 0, &mmeta)) != 0)
00803 goto out;
00804 mmeta_flags = 0;
00805 cmp_n = log_compare(lsnp, &mmeta->lsn);
00806 cmp_p = log_compare(&mmeta->lsn, &argp->mmetalsn);
00807 if (cmp_p == 0 && DB_REDO(op))
00808 mmeta->lsn = *lsnp;
00809 else if (cmp_n == 0 && DB_UNDO(op))
00810 mmeta->lsn = argp->mmetalsn;
00811 } else
00812 mmeta = (DBMETA *)hcp->hdr;
00813
00814 #ifdef HAVE_FTRUNCATE
00815 if (cmp_n == 0 && DB_UNDO(op))
00816 mmeta->last_pgno = argp->last_pgno;
00817 else if (DB_REDO(op))
00818 #endif
00819 if (mmeta->last_pgno < pgno)
00820 mmeta->last_pgno = pgno;
00821 mmeta_flags = DB_MPOOL_DIRTY;
00822
00823 if (argp->mmpgno != argp->mpgno &&
00824 (ret = __memp_fput(mpf, mmeta, mmeta_flags)) != 0)
00825 goto out;
00826 mmeta = NULL;
00827
00828 if (did_recover)
00829 F_SET(hcp, H_DIRTY);
00830
00831 done: *lsnp = argp->prev_lsn;
00832 ret = 0;
00833
00834 out: if (mmeta != NULL)
00835 (void)__memp_fput(mpf, mmeta, 0);
00836 if (dbc != NULL)
00837 (void)__ham_release_meta(dbc);
00838 if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)
00839 ret = 0;
00840
00841 REC_CLOSE;
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851 int
00852 __ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
00853 DB_ENV *dbenv;
00854 DBT *dbtp;
00855 DB_LSN *lsnp;
00856 db_recops op;
00857 void *info;
00858 {
00859 __ham_groupalloc_args *argp;
00860 DBMETA *mmeta;
00861 DB_MPOOLFILE *mpf;
00862 DB *file_dbp;
00863 DBC *dbc;
00864 PAGE *pagep;
00865 db_pgno_t pgno;
00866 int cmp_n, cmp_p, modified, ret;
00867
00868 mmeta = NULL;
00869 modified = 0;
00870 REC_PRINT(__ham_groupalloc_print);
00871 REC_INTRO(__ham_groupalloc_read, 0, 0);
00872
00873 pgno = PGNO_BASE_MD;
00874 if ((ret = __memp_fget(mpf, &pgno, 0, &mmeta)) != 0) {
00875 if (DB_REDO(op)) {
00876 ret = __db_pgerr(file_dbp, pgno, ret);
00877 goto out;
00878 } else
00879 goto done;
00880 }
00881
00882 cmp_n = log_compare(lsnp, &LSN(mmeta));
00883 cmp_p = log_compare(&LSN(mmeta), &argp->meta_lsn);
00884 CHECK_LSN(dbenv, op, cmp_p, &LSN(mmeta), &argp->meta_lsn);
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 pgno = argp->start_pgno + argp->num - 1;
00896 if (DB_REDO(op)) {
00897 if ((ret = __ham_alloc_pages(file_dbp, argp, lsnp)) != 0)
00898 goto out;
00899 if (cmp_p == 0) {
00900 LSN(mmeta) = *lsnp;
00901 modified = 1;
00902 }
00903 } else if (DB_UNDO(op)) {
00904
00905
00906
00907
00908 pagep = NULL;
00909 if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) {
00910 if (log_compare(&pagep->lsn, lsnp) != 0) {
00911 if ((ret = __memp_fput(mpf,
00912 pagep, DB_MPOOL_DISCARD)) != 0)
00913 goto out;
00914 pagep = NULL;
00915 }
00916 } else if (ret != DB_PAGE_NOTFOUND)
00917 goto out;
00918 #ifdef HAVE_FTRUNCATE
00919 COMPQUIET(info, NULL);
00920
00921
00922
00923
00924 if (pagep != NULL) {
00925 if ((ret =
00926 __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
00927 goto out;
00928 if ((ret =
00929 __memp_ftruncate(mpf, argp->start_pgno, 0)) != 0)
00930 goto out;
00931 }
00932
00933
00934
00935
00936
00937 if (cmp_n == 0) {
00938 mmeta->last_pgno = argp->last_pgno;
00939 modified = 1;
00940 }
00941 pgno = 0;
00942 #else
00943
00944
00945
00946 if (pagep != NULL) {
00947 if (log_compare(&pagep->lsn, lsnp) == 0)
00948 ZERO_LSN(pagep->lsn);
00949
00950 if ((ret =
00951 __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
00952 goto out;
00953 }
00954
00955
00956
00957 if ((ret = __db_add_limbo(dbenv,
00958 info, argp->fileid, argp->start_pgno, argp->num)) != 0)
00959 goto out;
00960 #endif
00961 if (cmp_n == 0) {
00962 LSN(mmeta) = argp->meta_lsn;
00963 modified = 1;
00964 }
00965 }
00966
00967
00968
00969
00970
00971
00972 if (pgno > mmeta->last_pgno) {
00973 mmeta->last_pgno = pgno;
00974 modified = 1;
00975 }
00976
00977 done: if (ret == 0)
00978 *lsnp = argp->prev_lsn;
00979 ret = 0;
00980
00981 out: if (mmeta != NULL)
00982 (void)__memp_fput(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0);
00983
00984 if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)
00985 ret = 0;
00986 REC_CLOSE;
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999 static int
01000 __ham_alloc_pages(dbp, argp, lsnp)
01001 DB *dbp;
01002 __ham_groupalloc_args *argp;
01003 DB_LSN *lsnp;
01004 {
01005 DB_MPOOLFILE *mpf;
01006 PAGE *pagep;
01007 db_pgno_t pgno;
01008 int ret;
01009
01010 mpf = dbp->mpf;
01011
01012
01013 pgno = argp->start_pgno + argp->num - 1;
01014
01015
01016 if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) {
01017 if (NUM_ENT(pagep) == 0 && IS_ZERO_LSN(pagep->lsn))
01018 goto reinit_page;
01019 if ((ret = __memp_fput(mpf, pagep, 0)) != 0)
01020 return (ret);
01021 return (0);
01022 }
01023
01024
01025 if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0)
01026 return (__db_pgerr(dbp, pgno, ret));
01027
01028 reinit_page:
01029
01030 P_INIT(pagep, dbp->pgsize, pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
01031 pagep->lsn = *lsnp;
01032
01033 if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
01034 return (ret);
01035
01036 return (0);
01037 }
01038
01039
01040
01041
01042
01043
01044
01045
01046 int
01047 __ham_curadj_recover(dbenv, dbtp, lsnp, op, info)
01048 DB_ENV *dbenv;
01049 DBT *dbtp;
01050 DB_LSN *lsnp;
01051 db_recops op;
01052 void *info;
01053 {
01054 __ham_curadj_args *argp;
01055 DB_MPOOLFILE *mpf;
01056 DB *file_dbp;
01057 DBC *dbc;
01058 int ret;
01059 HASH_CURSOR *hcp;
01060
01061 COMPQUIET(info, NULL);
01062 REC_PRINT(__ham_curadj_print);
01063 REC_INTRO(__ham_curadj_read, 0, 1);
01064
01065 if (op != DB_TXN_ABORT)
01066 goto done;
01067
01068
01069
01070
01071
01072
01073 hcp = (HASH_CURSOR *)dbc->internal;
01074 hcp->pgno = argp->pgno;
01075 hcp->indx = argp->indx;
01076 hcp->dup_off = argp->dup_off;
01077 hcp->order = argp->order;
01078 if (!argp->add)
01079 F_SET(hcp, H_DELETED);
01080 (void)__ham_c_update(dbc, argp->len, !argp->add, argp->is_dup);
01081
01082 done: *lsnp = argp->prev_lsn;
01083 out: REC_CLOSE;
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093 int
01094 __ham_chgpg_recover(dbenv, dbtp, lsnp, op, info)
01095 DB_ENV *dbenv;
01096 DBT *dbtp;
01097 DB_LSN *lsnp;
01098 db_recops op;
01099 void *info;
01100 {
01101 __ham_chgpg_args *argp;
01102 BTREE_CURSOR *opdcp;
01103 DB_MPOOLFILE *mpf;
01104 DB *file_dbp, *ldbp;
01105 DBC *dbc;
01106 int ret;
01107 DBC *cp;
01108 HASH_CURSOR *lcp;
01109 u_int32_t order, indx;
01110
01111 COMPQUIET(info, NULL);
01112 REC_PRINT(__ham_chgpg_print);
01113 REC_INTRO(__ham_chgpg_read, 0, 0);
01114
01115 if (op != DB_TXN_ABORT)
01116 goto done;
01117
01118
01119 indx = argp->old_indx;
01120 order = argp->new_indx;
01121
01122 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
01123 for (ldbp = __dblist_get(dbenv, file_dbp->adj_fileid);
01124 ldbp != NULL && ldbp->adj_fileid == file_dbp->adj_fileid;
01125 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
01126 MUTEX_LOCK(dbenv, file_dbp->mutex);
01127
01128 for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;
01129 cp = TAILQ_NEXT(cp, links)) {
01130 lcp = (HASH_CURSOR *)cp->internal;
01131
01132 switch (argp->mode) {
01133 case DB_HAM_DELFIRSTPG:
01134 if (lcp->pgno != argp->new_pgno)
01135 break;
01136 if (lcp->indx != indx ||
01137 !F_ISSET(lcp, H_DELETED) ||
01138 lcp->order >= order) {
01139 lcp->pgno = argp->old_pgno;
01140 if (lcp->indx == indx)
01141 lcp->order -= order;
01142 }
01143 break;
01144 case DB_HAM_DELMIDPG:
01145 case DB_HAM_DELLASTPG:
01146 if (lcp->pgno == argp->new_pgno &&
01147 lcp->indx == indx &&
01148 F_ISSET(lcp, H_DELETED) &&
01149 lcp->order >= order) {
01150 lcp->pgno = argp->old_pgno;
01151 lcp->order -= order;
01152 lcp->indx = 0;
01153 }
01154 break;
01155 case DB_HAM_CHGPG:
01156
01157
01158
01159
01160
01161
01162
01163 if (F_ISSET(lcp, H_DELETED))
01164 break;
01165
01166 case DB_HAM_SPLIT:
01167 if (lcp->pgno == argp->new_pgno &&
01168 lcp->indx == argp->new_indx) {
01169 lcp->indx = argp->old_indx;
01170 lcp->pgno = argp->old_pgno;
01171 }
01172 break;
01173 case DB_HAM_DUP:
01174 if (lcp->opd == NULL)
01175 break;
01176 opdcp = (BTREE_CURSOR *)lcp->opd->internal;
01177 if (opdcp->pgno != argp->new_pgno ||
01178 opdcp->indx != argp->new_indx)
01179 break;
01180
01181 if (F_ISSET(opdcp, C_DELETED))
01182 F_SET(lcp, H_DELETED);
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 MUTEX_UNLOCK(dbenv, file_dbp->mutex);
01193 if ((ret = __db_c_close(lcp->opd)) != 0)
01194 goto out;
01195 MUTEX_LOCK(dbenv, file_dbp->mutex);
01196 lcp->opd = NULL;
01197 break;
01198 }
01199 }
01200 MUTEX_UNLOCK(dbenv, file_dbp->mutex);
01201 }
01202 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
01203
01204 done: *lsnp = argp->prev_lsn;
01205 out: REC_CLOSE;
01206 }