00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__rec_8c-source.html,v 1.1 2008/06/08 10:18:14 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "db_page.h"
00022 #include "log.h"
00023 #include "hash.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032 int
00033 CDB___db_addrem_recover(dbenv, dbtp, lsnp, op, info)
00034 DB_ENV *dbenv;
00035 DBT *dbtp;
00036 DB_LSN *lsnp;
00037 db_recops op;
00038 void *info;
00039 {
00040 __db_addrem_args *argp;
00041 DB *file_dbp;
00042 DBC *dbc;
00043 DB_MPOOLFILE *mpf;
00044 PAGE *pagep;
00045 u_int32_t change;
00046 int cmp_n, cmp_p, ret;
00047
00048 COMPQUIET(info, NULL);
00049 REC_PRINT(CDB___db_addrem_print);
00050 REC_INTRO(CDB___db_addrem_read, 1);
00051
00052 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00053 if (DB_UNDO(op)) {
00054
00055
00056
00057
00058
00059
00060 goto done;
00061 } else
00062 if ((ret = CDB_memp_fget(mpf,
00063 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00064 goto out;
00065 }
00066
00067 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00068 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00069 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00070 change = 0;
00071 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_DUP) ||
00072 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_DUP)) {
00073
00074
00075 if ((ret = CDB___db_pitem(dbc, pagep, argp->indx, argp->nbytes,
00076 argp->hdr.size == 0 ? NULL : &argp->hdr,
00077 argp->dbt.size == 0 ? NULL : &argp->dbt)) != 0)
00078 goto out;
00079
00080 change = DB_MPOOL_DIRTY;
00081
00082 } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_DUP) ||
00083 (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_DUP)) {
00084
00085 if ((ret = CDB___db_ditem(dbc,
00086 pagep, argp->indx, argp->nbytes)) != 0)
00087 goto out;
00088 change = DB_MPOOL_DIRTY;
00089 }
00090
00091 if (change) {
00092 if (DB_REDO(op))
00093 LSN(pagep) = *lsnp;
00094 else
00095 LSN(pagep) = argp->pagelsn;
00096 }
00097
00098 if ((ret = CDB_memp_fput(mpf, pagep, change)) != 0)
00099 goto out;
00100
00101 done: *lsnp = argp->prev_lsn;
00102 ret = 0;
00103
00104 out: REC_CLOSE;
00105 }
00106
00107
00108
00109
00110
00111 int
00112 CDB___db_big_recover(dbenv, dbtp, lsnp, op, info)
00113 DB_ENV *dbenv;
00114 DBT *dbtp;
00115 DB_LSN *lsnp;
00116 db_recops op;
00117 void *info;
00118 {
00119 __db_big_args *argp;
00120 DB *file_dbp;
00121 DBC *dbc;
00122 DB_MPOOLFILE *mpf;
00123 PAGE *pagep;
00124 u_int32_t change;
00125 int cmp_n, cmp_p, ret;
00126
00127 COMPQUIET(info, NULL);
00128 REC_PRINT(CDB___db_big_print);
00129 REC_INTRO(CDB___db_big_read, 1);
00130
00131 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00132 if (DB_UNDO(op)) {
00133
00134
00135
00136
00137
00138
00139 ret = 0;
00140 goto ppage;
00141 } else
00142 if ((ret = CDB_memp_fget(mpf,
00143 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00144 goto out;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00154 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00155 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00156 change = 0;
00157 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) ||
00158 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_BIG)) {
00159
00160 P_INIT(pagep, file_dbp->pgsize, argp->pgno, argp->prev_pgno,
00161 argp->next_pgno, 0, P_OVERFLOW, TAGS(argp));
00162 OV_LEN(pagep) = argp->dbt.size;
00163 OV_REF(pagep) = 1;
00164 memcpy((u_int8_t *)pagep + P_OVERHEAD, argp->dbt.data,
00165 argp->dbt.size);
00166 PREV_PGNO(pagep) = argp->prev_pgno;
00167 change = DB_MPOOL_DIRTY;
00168 } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_BIG) ||
00169 (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_BIG)) {
00170
00171
00172
00173
00174
00175 change = DB_MPOOL_DIRTY;
00176 }
00177 if (change)
00178 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00179
00180 if ((ret = CDB_memp_fput(mpf, pagep, change)) != 0)
00181 goto out;
00182
00183
00184 ppage: if (argp->prev_pgno != PGNO_INVALID) {
00185 change = 0;
00186 if ((ret = CDB_memp_fget(mpf, &argp->prev_pgno, 0, &pagep)) != 0) {
00187 if (DB_UNDO(op)) {
00188
00189
00190
00191
00192
00193
00194 *lsnp = argp->prev_lsn;
00195 ret = 0;
00196 goto npage;
00197 } else
00198 if ((ret = CDB_memp_fget(mpf, &argp->prev_pgno,
00199 DB_MPOOL_CREATE, &pagep)) != 0)
00200 goto out;
00201 }
00202
00203 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00204 cmp_p = CDB_log_compare(&LSN(pagep), &argp->prevlsn);
00205 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->prevlsn);
00206
00207 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) ||
00208 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_BIG)) {
00209
00210 NEXT_PGNO(pagep) = argp->pgno;
00211 change = DB_MPOOL_DIRTY;
00212 } else if ((cmp_n == 0 &&
00213 DB_UNDO(op) && argp->opcode == DB_ADD_BIG) ||
00214 (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_BIG)) {
00215
00216 NEXT_PGNO(pagep) = argp->next_pgno;
00217 change = DB_MPOOL_DIRTY;
00218 }
00219 if (change)
00220 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn;
00221 if ((ret = CDB_memp_fput(mpf, pagep, change)) != 0)
00222 goto out;
00223 }
00224
00225
00226 npage: if (argp->next_pgno != PGNO_INVALID) {
00227 change = 0;
00228 if ((ret = CDB_memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
00229 if (DB_UNDO(op)) {
00230
00231
00232
00233
00234
00235
00236 goto done;
00237 } else
00238 if ((ret = CDB_memp_fget(mpf, &argp->next_pgno,
00239 DB_MPOOL_CREATE, &pagep)) != 0)
00240 goto out;
00241 }
00242
00243 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00244 cmp_p = CDB_log_compare(&LSN(pagep), &argp->nextlsn);
00245 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->nextlsn);
00246 if (cmp_p == 0 && DB_REDO(op)) {
00247 PREV_PGNO(pagep) = PGNO_INVALID;
00248 change = DB_MPOOL_DIRTY;
00249 } else if (cmp_n == 0 && DB_UNDO(op)) {
00250 PREV_PGNO(pagep) = argp->pgno;
00251 change = DB_MPOOL_DIRTY;
00252 }
00253 if (change)
00254 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn;
00255 if ((ret = CDB_memp_fput(mpf, pagep, change)) != 0)
00256 goto out;
00257 }
00258
00259 done: *lsnp = argp->prev_lsn;
00260 ret = 0;
00261
00262 out: REC_CLOSE;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 int
00272 CDB___db_ovref_recover(dbenv, dbtp, lsnp, op, info)
00273 DB_ENV *dbenv;
00274 DBT *dbtp;
00275 DB_LSN *lsnp;
00276 db_recops op;
00277 void *info;
00278 {
00279 __db_ovref_args *argp;
00280 DB *file_dbp;
00281 DBC *dbc;
00282 DB_MPOOLFILE *mpf;
00283 PAGE *pagep;
00284 int cmp, modified, ret;
00285
00286 COMPQUIET(info, NULL);
00287 REC_PRINT(CDB___db_ovref_print);
00288 REC_INTRO(CDB___db_ovref_read, 1);
00289
00290 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00291 (void)CDB___db_pgerr(file_dbp, argp->pgno);
00292 goto out;
00293 }
00294
00295 modified = 0;
00296 cmp = CDB_log_compare(&LSN(pagep), &argp->lsn);
00297 CHECK_LSN(op, cmp, &LSN(pagep), &argp->lsn);
00298 if (cmp == 0 && DB_REDO(op)) {
00299
00300 OV_REF(pagep) += argp->adjust;
00301
00302 pagep->lsn = *lsnp;
00303 modified = 1;
00304 } else if (CDB_log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
00305
00306 OV_REF(pagep) -= argp->adjust;
00307
00308 pagep->lsn = argp->lsn;
00309 modified = 1;
00310 }
00311 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00312 goto out;
00313
00314 done: *lsnp = argp->prev_lsn;
00315 ret = 0;
00316
00317 out: REC_CLOSE;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 int
00328 CDB___db_relink_recover(dbenv, dbtp, lsnp, op, info)
00329 DB_ENV *dbenv;
00330 DBT *dbtp;
00331 DB_LSN *lsnp;
00332 db_recops op;
00333 void *info;
00334 {
00335 __db_relink_args *argp;
00336 DB *file_dbp;
00337 DBC *dbc;
00338 DB_MPOOLFILE *mpf;
00339 PAGE *pagep;
00340 int cmp_n, cmp_p, modified, ret;
00341
00342 COMPQUIET(info, NULL);
00343 REC_PRINT(CDB___db_relink_print);
00344 REC_INTRO(CDB___db_relink_read, 1);
00345
00346
00347
00348
00349
00350
00351
00352 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00353 if (DB_REDO(op)) {
00354 (void)CDB___db_pgerr(file_dbp, argp->pgno);
00355 goto out;
00356 }
00357 goto next2;
00358 }
00359 modified = 0;
00360 if (argp->opcode == DB_ADD_PAGE)
00361 goto next1;
00362
00363 cmp_p = CDB_log_compare(&LSN(pagep), &argp->lsn);
00364 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
00365 if (cmp_p == 0 && DB_REDO(op)) {
00366
00367 pagep->lsn = *lsnp;
00368 modified = 1;
00369 } else if (CDB_log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
00370
00371 pagep->next_pgno = argp->next;
00372 pagep->prev_pgno = argp->prev;
00373
00374 pagep->lsn = argp->lsn;
00375 modified = 1;
00376 }
00377 next1: if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00378 goto out;
00379
00380 next2: if ((ret = CDB_memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
00381 if (DB_REDO(op)) {
00382 (void)CDB___db_pgerr(file_dbp, argp->next);
00383 goto out;
00384 }
00385 goto prev;
00386 }
00387 modified = 0;
00388 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00389 cmp_p = CDB_log_compare(&LSN(pagep), &argp->lsn_next);
00390 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_next);
00391 if ((argp->opcode == DB_REM_PAGE && cmp_p == 0 && DB_REDO(op)) ||
00392 (argp->opcode == DB_ADD_PAGE && cmp_n == 0 && DB_UNDO(op))) {
00393
00394 pagep->prev_pgno = argp->prev;
00395
00396 modified = 1;
00397 } else if ((argp->opcode == DB_REM_PAGE && cmp_n == 0 && DB_UNDO(op)) ||
00398 (argp->opcode == DB_ADD_PAGE && cmp_p == 0 && DB_REDO(op))) {
00399
00400 pagep->prev_pgno = argp->pgno;
00401
00402 modified = 1;
00403 }
00404 if (modified == 1) {
00405 if (DB_UNDO(op))
00406 pagep->lsn = argp->lsn_next;
00407 else
00408 pagep->lsn = *lsnp;
00409 }
00410 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00411 goto out;
00412 if (argp->opcode == DB_ADD_PAGE)
00413 goto done;
00414
00415 prev: if ((ret = CDB_memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
00416 if (DB_REDO(op)) {
00417 (void)CDB___db_pgerr(file_dbp, argp->prev);
00418 goto out;
00419 }
00420 goto done;
00421 }
00422 modified = 0;
00423 cmp_p = CDB_log_compare(&LSN(pagep), &argp->lsn_prev);
00424 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_prev);
00425 if (cmp_p == 0 && DB_REDO(op)) {
00426
00427 pagep->next_pgno = argp->next;
00428
00429 modified = 1;
00430 } else if (CDB_log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
00431
00432 pagep->next_pgno = argp->pgno;
00433
00434 modified = 1;
00435 }
00436 if (modified == 1) {
00437 if (DB_UNDO(op))
00438 pagep->lsn = argp->lsn_prev;
00439 else
00440 pagep->lsn = *lsnp;
00441 }
00442 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00443 goto out;
00444
00445 done: *lsnp = argp->prev_lsn;
00446 ret = 0;
00447
00448 out: REC_CLOSE;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458 int
00459 CDB___db_debug_recover(dbenv, dbtp, lsnp, op, info)
00460 DB_ENV *dbenv;
00461 DBT *dbtp;
00462 DB_LSN *lsnp;
00463 db_recops op;
00464 void *info;
00465 {
00466 __db_debug_args *argp;
00467 int ret;
00468
00469 COMPQUIET(op, 0);
00470 COMPQUIET(dbenv, NULL);
00471 COMPQUIET(info, NULL);
00472
00473 REC_PRINT(CDB___db_debug_print);
00474 REC_NOOP_INTRO(CDB___db_debug_read);
00475
00476 *lsnp = argp->prev_lsn;
00477 ret = 0;
00478
00479 REC_NOOP_CLOSE;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489 int
00490 CDB___db_noop_recover(dbenv, dbtp, lsnp, op, info)
00491 DB_ENV *dbenv;
00492 DBT *dbtp;
00493 DB_LSN *lsnp;
00494 db_recops op;
00495 void *info;
00496 {
00497 __db_noop_args *argp;
00498 DB *file_dbp;
00499 DBC *dbc;
00500 DB_MPOOLFILE *mpf;
00501 PAGE *pagep;
00502 u_int32_t change;
00503 int cmp_n, cmp_p, ret;
00504
00505 COMPQUIET(info, NULL);
00506 REC_PRINT(CDB___db_noop_print);
00507 REC_INTRO(CDB___db_noop_read, 0);
00508
00509 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0)
00510 goto out;
00511
00512 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00513 cmp_p = CDB_log_compare(&LSN(pagep), &argp->prevlsn);
00514 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->prevlsn);
00515 change = 0;
00516 if (cmp_p == 0 && DB_REDO(op)) {
00517 LSN(pagep) = *lsnp;
00518 change = DB_MPOOL_DIRTY;
00519 } else if (cmp_n == 0 && DB_UNDO(op)) {
00520 LSN(pagep) = argp->prevlsn;
00521 change = DB_MPOOL_DIRTY;
00522 }
00523 ret = CDB_memp_fput(mpf, pagep, change);
00524
00525 done: *lsnp = argp->prev_lsn;
00526 out: REC_CLOSE;
00527 }