1/* Do not edit: automatically built by gen_rec.awk. */ 2 3#include "db_config.h" 4#include "db_int.h" 5#include "dbinc/crypto.h" 6#include "dbinc/db_page.h" 7#include "dbinc/db_dispatch.h" 8#include "dbinc/db_am.h" 9#include "dbinc/log.h" 10#include "dbinc/txn.h" 11 12/* 13 * PUBLIC: int __db_addrem_read __P((ENV *, DB **, void *, void *, 14 * PUBLIC: __db_addrem_args **)); 15 */ 16int 17__db_addrem_read(env, dbpp, td, recbuf, argpp) 18 ENV *env; 19 DB **dbpp; 20 void *td; 21 void *recbuf; 22 __db_addrem_args **argpp; 23{ 24 __db_addrem_args *argp; 25 u_int32_t uinttmp; 26 u_int8_t *bp; 27 int ret; 28 29 if ((ret = __os_malloc(env, 30 sizeof(__db_addrem_args) + sizeof(DB_TXN), &argp)) != 0) 31 return (ret); 32 bp = recbuf; 33 argp->txnp = (DB_TXN *)&argp[1]; 34 memset(argp->txnp, 0, sizeof(DB_TXN)); 35 36 argp->txnp->td = td; 37 LOGCOPY_32(env, &argp->type, bp); 38 bp += sizeof(argp->type); 39 40 LOGCOPY_32(env, &argp->txnp->txnid, bp); 41 bp += sizeof(argp->txnp->txnid); 42 43 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 44 bp += sizeof(DB_LSN); 45 46 LOGCOPY_32(env, &argp->opcode, bp); 47 bp += sizeof(argp->opcode); 48 49 LOGCOPY_32(env, &uinttmp, bp); 50 argp->fileid = (int32_t)uinttmp; 51 bp += sizeof(uinttmp); 52 if (dbpp != NULL) { 53 *dbpp = NULL; 54 ret = __dbreg_id_to_db( 55 env, argp->txnp, dbpp, argp->fileid, 1); 56 } 57 58 LOGCOPY_32(env, &uinttmp, bp); 59 argp->pgno = (db_pgno_t)uinttmp; 60 bp += sizeof(uinttmp); 61 62 LOGCOPY_32(env, &argp->indx, bp); 63 bp += sizeof(argp->indx); 64 65 LOGCOPY_32(env, &argp->nbytes, bp); 66 bp += sizeof(argp->nbytes); 67 68 memset(&argp->hdr, 0, sizeof(argp->hdr)); 69 LOGCOPY_32(env,&argp->hdr.size, bp); 70 bp += sizeof(u_int32_t); 71 argp->hdr.data = bp; 72 bp += argp->hdr.size; 73 74 memset(&argp->dbt, 0, sizeof(argp->dbt)); 75 LOGCOPY_32(env,&argp->dbt.size, bp); 76 bp += sizeof(u_int32_t); 77 argp->dbt.data = bp; 78 bp += argp->dbt.size; 79 80 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 81 bp += sizeof(DB_LSN); 82 83 *argpp = argp; 84 return (ret); 85} 86 87/* 88 * PUBLIC: int __db_addrem_log __P((DB *, DB_TXN *, DB_LSN *, 89 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, u_int32_t, u_int32_t, 90 * PUBLIC: const DBT *, const DBT *, DB_LSN *)); 91 */ 92int 93__db_addrem_log(dbp, txnp, ret_lsnp, flags, 94 opcode, pgno, indx, nbytes, hdr, 95 dbt, pagelsn) 96 DB *dbp; 97 DB_TXN *txnp; 98 DB_LSN *ret_lsnp; 99 u_int32_t flags; 100 u_int32_t opcode; 101 db_pgno_t pgno; 102 u_int32_t indx; 103 u_int32_t nbytes; 104 const DBT *hdr; 105 const DBT *dbt; 106 DB_LSN * pagelsn; 107{ 108 DBT logrec; 109 DB_LSN *lsnp, null_lsn, *rlsnp; 110 DB_TXNLOGREC *lr; 111 ENV *env; 112 u_int32_t zero, uinttmp, rectype, txn_num; 113 u_int npad; 114 u_int8_t *bp; 115 int is_durable, ret; 116 117 COMPQUIET(lr, NULL); 118 119 env = dbp->env; 120 rlsnp = ret_lsnp; 121 rectype = DB___db_addrem; 122 npad = 0; 123 ret = 0; 124 125 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 126 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 127 if (txnp == NULL) 128 return (0); 129 is_durable = 0; 130 } else 131 is_durable = 1; 132 133 if (txnp == NULL) { 134 txn_num = 0; 135 lsnp = &null_lsn; 136 null_lsn.file = null_lsn.offset = 0; 137 } else { 138 if (TAILQ_FIRST(&txnp->kids) != NULL && 139 (ret = __txn_activekids(env, rectype, txnp)) != 0) 140 return (ret); 141 /* 142 * We need to assign begin_lsn while holding region mutex. 143 * That assignment is done inside the DbEnv->log_put call, 144 * so pass in the appropriate memory location to be filled 145 * in by the log_put code. 146 */ 147 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 148 txn_num = txnp->txnid; 149 } 150 151 DB_ASSERT(env, dbp->log_filename != NULL); 152 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 153 (ret = __dbreg_lazy_id(dbp)) != 0) 154 return (ret); 155 156 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 157 + sizeof(u_int32_t) 158 + sizeof(u_int32_t) 159 + sizeof(u_int32_t) 160 + sizeof(u_int32_t) 161 + sizeof(u_int32_t) 162 + sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size) 163 + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size) 164 + sizeof(*pagelsn); 165 if (CRYPTO_ON(env)) { 166 npad = env->crypto_handle->adj_size(logrec.size); 167 logrec.size += npad; 168 } 169 170 if (is_durable || txnp == NULL) { 171 if ((ret = 172 __os_malloc(env, logrec.size, &logrec.data)) != 0) 173 return (ret); 174 } else { 175 if ((ret = __os_malloc(env, 176 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 177 return (ret); 178#ifdef DIAGNOSTIC 179 if ((ret = 180 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 181 __os_free(env, lr); 182 return (ret); 183 } 184#else 185 logrec.data = lr->data; 186#endif 187 } 188 if (npad > 0) 189 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 190 191 bp = logrec.data; 192 193 LOGCOPY_32(env, bp, &rectype); 194 bp += sizeof(rectype); 195 196 LOGCOPY_32(env, bp, &txn_num); 197 bp += sizeof(txn_num); 198 199 LOGCOPY_FROMLSN(env, bp, lsnp); 200 bp += sizeof(DB_LSN); 201 202 LOGCOPY_32(env, bp, &opcode); 203 bp += sizeof(opcode); 204 205 uinttmp = (u_int32_t)dbp->log_filename->id; 206 LOGCOPY_32(env, bp, &uinttmp); 207 bp += sizeof(uinttmp); 208 209 uinttmp = (u_int32_t)pgno; 210 LOGCOPY_32(env,bp, &uinttmp); 211 bp += sizeof(uinttmp); 212 213 LOGCOPY_32(env, bp, &indx); 214 bp += sizeof(indx); 215 216 LOGCOPY_32(env, bp, &nbytes); 217 bp += sizeof(nbytes); 218 219 if (hdr == NULL) { 220 zero = 0; 221 LOGCOPY_32(env, bp, &zero); 222 bp += sizeof(u_int32_t); 223 } else { 224 LOGCOPY_32(env, bp, &hdr->size); 225 bp += sizeof(hdr->size); 226 memcpy(bp, hdr->data, hdr->size); 227 bp += hdr->size; 228 } 229 230 if (dbt == NULL) { 231 zero = 0; 232 LOGCOPY_32(env, bp, &zero); 233 bp += sizeof(u_int32_t); 234 } else { 235 LOGCOPY_32(env, bp, &dbt->size); 236 bp += sizeof(dbt->size); 237 memcpy(bp, dbt->data, dbt->size); 238 bp += dbt->size; 239 } 240 241 if (pagelsn != NULL) { 242 if (txnp != NULL) { 243 LOG *lp = env->lg_handle->reginfo.primary; 244 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 245 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 246 return (ret); 247 } 248 LOGCOPY_FROMLSN(env, bp, pagelsn); 249 } else 250 memset(bp, 0, sizeof(*pagelsn)); 251 bp += sizeof(*pagelsn); 252 253 DB_ASSERT(env, 254 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 255 256 if (is_durable || txnp == NULL) { 257 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 258 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 259 *lsnp = *rlsnp; 260 if (rlsnp != ret_lsnp) 261 *ret_lsnp = *rlsnp; 262 } 263 } else { 264 ret = 0; 265#ifdef DIAGNOSTIC 266 /* 267 * Set the debug bit if we are going to log non-durable 268 * transactions so they will be ignored by recovery. 269 */ 270 memcpy(lr->data, logrec.data, logrec.size); 271 rectype |= DB_debug_FLAG; 272 LOGCOPY_32(env, logrec.data, &rectype); 273 274 if (!IS_REP_CLIENT(env)) 275 ret = __log_put(env, 276 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 277#endif 278 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 279 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 280 LSN_NOT_LOGGED(*ret_lsnp); 281 } 282 283#ifdef LOG_DIAGNOSTIC 284 if (ret != 0) 285 (void)__db_addrem_print(env, 286 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 287#endif 288 289#ifdef DIAGNOSTIC 290 __os_free(env, logrec.data); 291#else 292 if (is_durable || txnp == NULL) 293 __os_free(env, logrec.data); 294#endif 295 return (ret); 296} 297 298/* 299 * PUBLIC: int __db_big_read __P((ENV *, DB **, void *, void *, 300 * PUBLIC: __db_big_args **)); 301 */ 302int 303__db_big_read(env, dbpp, td, recbuf, argpp) 304 ENV *env; 305 DB **dbpp; 306 void *td; 307 void *recbuf; 308 __db_big_args **argpp; 309{ 310 __db_big_args *argp; 311 u_int32_t uinttmp; 312 u_int8_t *bp; 313 int ret; 314 315 if ((ret = __os_malloc(env, 316 sizeof(__db_big_args) + sizeof(DB_TXN), &argp)) != 0) 317 return (ret); 318 bp = recbuf; 319 argp->txnp = (DB_TXN *)&argp[1]; 320 memset(argp->txnp, 0, sizeof(DB_TXN)); 321 322 argp->txnp->td = td; 323 LOGCOPY_32(env, &argp->type, bp); 324 bp += sizeof(argp->type); 325 326 LOGCOPY_32(env, &argp->txnp->txnid, bp); 327 bp += sizeof(argp->txnp->txnid); 328 329 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 330 bp += sizeof(DB_LSN); 331 332 LOGCOPY_32(env, &argp->opcode, bp); 333 bp += sizeof(argp->opcode); 334 335 LOGCOPY_32(env, &uinttmp, bp); 336 argp->fileid = (int32_t)uinttmp; 337 bp += sizeof(uinttmp); 338 if (dbpp != NULL) { 339 *dbpp = NULL; 340 ret = __dbreg_id_to_db( 341 env, argp->txnp, dbpp, argp->fileid, 1); 342 } 343 344 LOGCOPY_32(env, &uinttmp, bp); 345 argp->pgno = (db_pgno_t)uinttmp; 346 bp += sizeof(uinttmp); 347 348 LOGCOPY_32(env, &uinttmp, bp); 349 argp->prev_pgno = (db_pgno_t)uinttmp; 350 bp += sizeof(uinttmp); 351 352 LOGCOPY_32(env, &uinttmp, bp); 353 argp->next_pgno = (db_pgno_t)uinttmp; 354 bp += sizeof(uinttmp); 355 356 memset(&argp->dbt, 0, sizeof(argp->dbt)); 357 LOGCOPY_32(env,&argp->dbt.size, bp); 358 bp += sizeof(u_int32_t); 359 argp->dbt.data = bp; 360 bp += argp->dbt.size; 361 362 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 363 bp += sizeof(DB_LSN); 364 365 LOGCOPY_TOLSN(env, &argp->prevlsn, bp); 366 bp += sizeof(DB_LSN); 367 368 LOGCOPY_TOLSN(env, &argp->nextlsn, bp); 369 bp += sizeof(DB_LSN); 370 371 *argpp = argp; 372 return (ret); 373} 374 375/* 376 * PUBLIC: int __db_big_log __P((DB *, DB_TXN *, DB_LSN *, 377 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t, 378 * PUBLIC: const DBT *, DB_LSN *, DB_LSN *, DB_LSN *)); 379 */ 380int 381__db_big_log(dbp, txnp, ret_lsnp, flags, 382 opcode, pgno, prev_pgno, next_pgno, dbt, 383 pagelsn, prevlsn, nextlsn) 384 DB *dbp; 385 DB_TXN *txnp; 386 DB_LSN *ret_lsnp; 387 u_int32_t flags; 388 u_int32_t opcode; 389 db_pgno_t pgno; 390 db_pgno_t prev_pgno; 391 db_pgno_t next_pgno; 392 const DBT *dbt; 393 DB_LSN * pagelsn; 394 DB_LSN * prevlsn; 395 DB_LSN * nextlsn; 396{ 397 DBT logrec; 398 DB_LSN *lsnp, null_lsn, *rlsnp; 399 DB_TXNLOGREC *lr; 400 ENV *env; 401 u_int32_t zero, uinttmp, rectype, txn_num; 402 u_int npad; 403 u_int8_t *bp; 404 int is_durable, ret; 405 406 COMPQUIET(lr, NULL); 407 408 env = dbp->env; 409 rlsnp = ret_lsnp; 410 rectype = DB___db_big; 411 npad = 0; 412 ret = 0; 413 414 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 415 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 416 if (txnp == NULL) 417 return (0); 418 is_durable = 0; 419 } else 420 is_durable = 1; 421 422 if (txnp == NULL) { 423 txn_num = 0; 424 lsnp = &null_lsn; 425 null_lsn.file = null_lsn.offset = 0; 426 } else { 427 if (TAILQ_FIRST(&txnp->kids) != NULL && 428 (ret = __txn_activekids(env, rectype, txnp)) != 0) 429 return (ret); 430 /* 431 * We need to assign begin_lsn while holding region mutex. 432 * That assignment is done inside the DbEnv->log_put call, 433 * so pass in the appropriate memory location to be filled 434 * in by the log_put code. 435 */ 436 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 437 txn_num = txnp->txnid; 438 } 439 440 DB_ASSERT(env, dbp->log_filename != NULL); 441 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 442 (ret = __dbreg_lazy_id(dbp)) != 0) 443 return (ret); 444 445 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 446 + sizeof(u_int32_t) 447 + sizeof(u_int32_t) 448 + sizeof(u_int32_t) 449 + sizeof(u_int32_t) 450 + sizeof(u_int32_t) 451 + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size) 452 + sizeof(*pagelsn) 453 + sizeof(*prevlsn) 454 + sizeof(*nextlsn); 455 if (CRYPTO_ON(env)) { 456 npad = env->crypto_handle->adj_size(logrec.size); 457 logrec.size += npad; 458 } 459 460 if (is_durable || txnp == NULL) { 461 if ((ret = 462 __os_malloc(env, logrec.size, &logrec.data)) != 0) 463 return (ret); 464 } else { 465 if ((ret = __os_malloc(env, 466 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 467 return (ret); 468#ifdef DIAGNOSTIC 469 if ((ret = 470 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 471 __os_free(env, lr); 472 return (ret); 473 } 474#else 475 logrec.data = lr->data; 476#endif 477 } 478 if (npad > 0) 479 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 480 481 bp = logrec.data; 482 483 LOGCOPY_32(env, bp, &rectype); 484 bp += sizeof(rectype); 485 486 LOGCOPY_32(env, bp, &txn_num); 487 bp += sizeof(txn_num); 488 489 LOGCOPY_FROMLSN(env, bp, lsnp); 490 bp += sizeof(DB_LSN); 491 492 LOGCOPY_32(env, bp, &opcode); 493 bp += sizeof(opcode); 494 495 uinttmp = (u_int32_t)dbp->log_filename->id; 496 LOGCOPY_32(env, bp, &uinttmp); 497 bp += sizeof(uinttmp); 498 499 uinttmp = (u_int32_t)pgno; 500 LOGCOPY_32(env,bp, &uinttmp); 501 bp += sizeof(uinttmp); 502 503 uinttmp = (u_int32_t)prev_pgno; 504 LOGCOPY_32(env,bp, &uinttmp); 505 bp += sizeof(uinttmp); 506 507 uinttmp = (u_int32_t)next_pgno; 508 LOGCOPY_32(env,bp, &uinttmp); 509 bp += sizeof(uinttmp); 510 511 if (dbt == NULL) { 512 zero = 0; 513 LOGCOPY_32(env, bp, &zero); 514 bp += sizeof(u_int32_t); 515 } else { 516 LOGCOPY_32(env, bp, &dbt->size); 517 bp += sizeof(dbt->size); 518 memcpy(bp, dbt->data, dbt->size); 519 bp += dbt->size; 520 } 521 522 if (pagelsn != NULL) { 523 if (txnp != NULL) { 524 LOG *lp = env->lg_handle->reginfo.primary; 525 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 526 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 527 return (ret); 528 } 529 LOGCOPY_FROMLSN(env, bp, pagelsn); 530 } else 531 memset(bp, 0, sizeof(*pagelsn)); 532 bp += sizeof(*pagelsn); 533 534 if (prevlsn != NULL) { 535 if (txnp != NULL) { 536 LOG *lp = env->lg_handle->reginfo.primary; 537 if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = 538 __log_check_page_lsn(env, dbp, prevlsn) != 0)) 539 return (ret); 540 } 541 LOGCOPY_FROMLSN(env, bp, prevlsn); 542 } else 543 memset(bp, 0, sizeof(*prevlsn)); 544 bp += sizeof(*prevlsn); 545 546 if (nextlsn != NULL) { 547 if (txnp != NULL) { 548 LOG *lp = env->lg_handle->reginfo.primary; 549 if (LOG_COMPARE(nextlsn, &lp->lsn) >= 0 && (ret = 550 __log_check_page_lsn(env, dbp, nextlsn) != 0)) 551 return (ret); 552 } 553 LOGCOPY_FROMLSN(env, bp, nextlsn); 554 } else 555 memset(bp, 0, sizeof(*nextlsn)); 556 bp += sizeof(*nextlsn); 557 558 DB_ASSERT(env, 559 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 560 561 if (is_durable || txnp == NULL) { 562 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 563 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 564 *lsnp = *rlsnp; 565 if (rlsnp != ret_lsnp) 566 *ret_lsnp = *rlsnp; 567 } 568 } else { 569 ret = 0; 570#ifdef DIAGNOSTIC 571 /* 572 * Set the debug bit if we are going to log non-durable 573 * transactions so they will be ignored by recovery. 574 */ 575 memcpy(lr->data, logrec.data, logrec.size); 576 rectype |= DB_debug_FLAG; 577 LOGCOPY_32(env, logrec.data, &rectype); 578 579 if (!IS_REP_CLIENT(env)) 580 ret = __log_put(env, 581 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 582#endif 583 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 584 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 585 LSN_NOT_LOGGED(*ret_lsnp); 586 } 587 588#ifdef LOG_DIAGNOSTIC 589 if (ret != 0) 590 (void)__db_big_print(env, 591 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 592#endif 593 594#ifdef DIAGNOSTIC 595 __os_free(env, logrec.data); 596#else 597 if (is_durable || txnp == NULL) 598 __os_free(env, logrec.data); 599#endif 600 return (ret); 601} 602 603/* 604 * PUBLIC: int __db_ovref_read __P((ENV *, DB **, void *, void *, 605 * PUBLIC: __db_ovref_args **)); 606 */ 607int 608__db_ovref_read(env, dbpp, td, recbuf, argpp) 609 ENV *env; 610 DB **dbpp; 611 void *td; 612 void *recbuf; 613 __db_ovref_args **argpp; 614{ 615 __db_ovref_args *argp; 616 u_int32_t uinttmp; 617 u_int8_t *bp; 618 int ret; 619 620 if ((ret = __os_malloc(env, 621 sizeof(__db_ovref_args) + sizeof(DB_TXN), &argp)) != 0) 622 return (ret); 623 bp = recbuf; 624 argp->txnp = (DB_TXN *)&argp[1]; 625 memset(argp->txnp, 0, sizeof(DB_TXN)); 626 627 argp->txnp->td = td; 628 LOGCOPY_32(env, &argp->type, bp); 629 bp += sizeof(argp->type); 630 631 LOGCOPY_32(env, &argp->txnp->txnid, bp); 632 bp += sizeof(argp->txnp->txnid); 633 634 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 635 bp += sizeof(DB_LSN); 636 637 LOGCOPY_32(env, &uinttmp, bp); 638 argp->fileid = (int32_t)uinttmp; 639 bp += sizeof(uinttmp); 640 if (dbpp != NULL) { 641 *dbpp = NULL; 642 ret = __dbreg_id_to_db( 643 env, argp->txnp, dbpp, argp->fileid, 1); 644 } 645 646 LOGCOPY_32(env, &uinttmp, bp); 647 argp->pgno = (db_pgno_t)uinttmp; 648 bp += sizeof(uinttmp); 649 650 LOGCOPY_32(env, &uinttmp, bp); 651 argp->adjust = (int32_t)uinttmp; 652 bp += sizeof(uinttmp); 653 654 LOGCOPY_TOLSN(env, &argp->lsn, bp); 655 bp += sizeof(DB_LSN); 656 657 *argpp = argp; 658 return (ret); 659} 660 661/* 662 * PUBLIC: int __db_ovref_log __P((DB *, DB_TXN *, DB_LSN *, 663 * PUBLIC: u_int32_t, db_pgno_t, int32_t, DB_LSN *)); 664 */ 665int 666__db_ovref_log(dbp, txnp, ret_lsnp, flags, pgno, adjust, lsn) 667 DB *dbp; 668 DB_TXN *txnp; 669 DB_LSN *ret_lsnp; 670 u_int32_t flags; 671 db_pgno_t pgno; 672 int32_t adjust; 673 DB_LSN * lsn; 674{ 675 DBT logrec; 676 DB_LSN *lsnp, null_lsn, *rlsnp; 677 DB_TXNLOGREC *lr; 678 ENV *env; 679 u_int32_t uinttmp, rectype, txn_num; 680 u_int npad; 681 u_int8_t *bp; 682 int is_durable, ret; 683 684 COMPQUIET(lr, NULL); 685 686 env = dbp->env; 687 rlsnp = ret_lsnp; 688 rectype = DB___db_ovref; 689 npad = 0; 690 ret = 0; 691 692 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 693 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 694 if (txnp == NULL) 695 return (0); 696 is_durable = 0; 697 } else 698 is_durable = 1; 699 700 if (txnp == NULL) { 701 txn_num = 0; 702 lsnp = &null_lsn; 703 null_lsn.file = null_lsn.offset = 0; 704 } else { 705 if (TAILQ_FIRST(&txnp->kids) != NULL && 706 (ret = __txn_activekids(env, rectype, txnp)) != 0) 707 return (ret); 708 /* 709 * We need to assign begin_lsn while holding region mutex. 710 * That assignment is done inside the DbEnv->log_put call, 711 * so pass in the appropriate memory location to be filled 712 * in by the log_put code. 713 */ 714 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 715 txn_num = txnp->txnid; 716 } 717 718 DB_ASSERT(env, dbp->log_filename != NULL); 719 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 720 (ret = __dbreg_lazy_id(dbp)) != 0) 721 return (ret); 722 723 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 724 + sizeof(u_int32_t) 725 + sizeof(u_int32_t) 726 + sizeof(u_int32_t) 727 + sizeof(*lsn); 728 if (CRYPTO_ON(env)) { 729 npad = env->crypto_handle->adj_size(logrec.size); 730 logrec.size += npad; 731 } 732 733 if (is_durable || txnp == NULL) { 734 if ((ret = 735 __os_malloc(env, logrec.size, &logrec.data)) != 0) 736 return (ret); 737 } else { 738 if ((ret = __os_malloc(env, 739 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 740 return (ret); 741#ifdef DIAGNOSTIC 742 if ((ret = 743 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 744 __os_free(env, lr); 745 return (ret); 746 } 747#else 748 logrec.data = lr->data; 749#endif 750 } 751 if (npad > 0) 752 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 753 754 bp = logrec.data; 755 756 LOGCOPY_32(env, bp, &rectype); 757 bp += sizeof(rectype); 758 759 LOGCOPY_32(env, bp, &txn_num); 760 bp += sizeof(txn_num); 761 762 LOGCOPY_FROMLSN(env, bp, lsnp); 763 bp += sizeof(DB_LSN); 764 765 uinttmp = (u_int32_t)dbp->log_filename->id; 766 LOGCOPY_32(env, bp, &uinttmp); 767 bp += sizeof(uinttmp); 768 769 uinttmp = (u_int32_t)pgno; 770 LOGCOPY_32(env,bp, &uinttmp); 771 bp += sizeof(uinttmp); 772 773 uinttmp = (u_int32_t)adjust; 774 LOGCOPY_32(env,bp, &uinttmp); 775 bp += sizeof(uinttmp); 776 777 if (lsn != NULL) { 778 if (txnp != NULL) { 779 LOG *lp = env->lg_handle->reginfo.primary; 780 if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = 781 __log_check_page_lsn(env, dbp, lsn) != 0)) 782 return (ret); 783 } 784 LOGCOPY_FROMLSN(env, bp, lsn); 785 } else 786 memset(bp, 0, sizeof(*lsn)); 787 bp += sizeof(*lsn); 788 789 DB_ASSERT(env, 790 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 791 792 if (is_durable || txnp == NULL) { 793 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 794 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 795 *lsnp = *rlsnp; 796 if (rlsnp != ret_lsnp) 797 *ret_lsnp = *rlsnp; 798 } 799 } else { 800 ret = 0; 801#ifdef DIAGNOSTIC 802 /* 803 * Set the debug bit if we are going to log non-durable 804 * transactions so they will be ignored by recovery. 805 */ 806 memcpy(lr->data, logrec.data, logrec.size); 807 rectype |= DB_debug_FLAG; 808 LOGCOPY_32(env, logrec.data, &rectype); 809 810 if (!IS_REP_CLIENT(env)) 811 ret = __log_put(env, 812 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 813#endif 814 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 815 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 816 LSN_NOT_LOGGED(*ret_lsnp); 817 } 818 819#ifdef LOG_DIAGNOSTIC 820 if (ret != 0) 821 (void)__db_ovref_print(env, 822 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 823#endif 824 825#ifdef DIAGNOSTIC 826 __os_free(env, logrec.data); 827#else 828 if (is_durable || txnp == NULL) 829 __os_free(env, logrec.data); 830#endif 831 return (ret); 832} 833 834/* 835 * PUBLIC: int __db_relink_42_read __P((ENV *, DB **, void *, 836 * PUBLIC: void *, __db_relink_42_args **)); 837 */ 838int 839__db_relink_42_read(env, dbpp, td, recbuf, argpp) 840 ENV *env; 841 DB **dbpp; 842 void *td; 843 void *recbuf; 844 __db_relink_42_args **argpp; 845{ 846 __db_relink_42_args *argp; 847 u_int32_t uinttmp; 848 u_int8_t *bp; 849 int ret; 850 851 if ((ret = __os_malloc(env, 852 sizeof(__db_relink_42_args) + sizeof(DB_TXN), &argp)) != 0) 853 return (ret); 854 bp = recbuf; 855 argp->txnp = (DB_TXN *)&argp[1]; 856 memset(argp->txnp, 0, sizeof(DB_TXN)); 857 858 argp->txnp->td = td; 859 LOGCOPY_32(env, &argp->type, bp); 860 bp += sizeof(argp->type); 861 862 LOGCOPY_32(env, &argp->txnp->txnid, bp); 863 bp += sizeof(argp->txnp->txnid); 864 865 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 866 bp += sizeof(DB_LSN); 867 868 LOGCOPY_32(env, &argp->opcode, bp); 869 bp += sizeof(argp->opcode); 870 871 LOGCOPY_32(env, &uinttmp, bp); 872 argp->fileid = (int32_t)uinttmp; 873 bp += sizeof(uinttmp); 874 if (dbpp != NULL) { 875 *dbpp = NULL; 876 ret = __dbreg_id_to_db( 877 env, argp->txnp, dbpp, argp->fileid, 1); 878 } 879 880 LOGCOPY_32(env, &uinttmp, bp); 881 argp->pgno = (db_pgno_t)uinttmp; 882 bp += sizeof(uinttmp); 883 884 LOGCOPY_TOLSN(env, &argp->lsn, bp); 885 bp += sizeof(DB_LSN); 886 887 LOGCOPY_32(env, &uinttmp, bp); 888 argp->prev = (db_pgno_t)uinttmp; 889 bp += sizeof(uinttmp); 890 891 LOGCOPY_TOLSN(env, &argp->lsn_prev, bp); 892 bp += sizeof(DB_LSN); 893 894 LOGCOPY_32(env, &uinttmp, bp); 895 argp->next = (db_pgno_t)uinttmp; 896 bp += sizeof(uinttmp); 897 898 LOGCOPY_TOLSN(env, &argp->lsn_next, bp); 899 bp += sizeof(DB_LSN); 900 901 *argpp = argp; 902 return (ret); 903} 904 905/* 906 * PUBLIC: int __db_debug_read __P((ENV *, void *, __db_debug_args **)); 907 */ 908int 909__db_debug_read(env, recbuf, argpp) 910 ENV *env; 911 void *recbuf; 912 __db_debug_args **argpp; 913{ 914 __db_debug_args *argp; 915 u_int32_t uinttmp; 916 u_int8_t *bp; 917 int ret; 918 919 if ((ret = __os_malloc(env, 920 sizeof(__db_debug_args) + sizeof(DB_TXN), &argp)) != 0) 921 return (ret); 922 bp = recbuf; 923 argp->txnp = (DB_TXN *)&argp[1]; 924 memset(argp->txnp, 0, sizeof(DB_TXN)); 925 926 LOGCOPY_32(env, &argp->type, bp); 927 bp += sizeof(argp->type); 928 929 LOGCOPY_32(env, &argp->txnp->txnid, bp); 930 bp += sizeof(argp->txnp->txnid); 931 932 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 933 bp += sizeof(DB_LSN); 934 935 memset(&argp->op, 0, sizeof(argp->op)); 936 LOGCOPY_32(env,&argp->op.size, bp); 937 bp += sizeof(u_int32_t); 938 argp->op.data = bp; 939 bp += argp->op.size; 940 941 LOGCOPY_32(env, &uinttmp, bp); 942 argp->fileid = (int32_t)uinttmp; 943 bp += sizeof(uinttmp); 944 945 memset(&argp->key, 0, sizeof(argp->key)); 946 LOGCOPY_32(env,&argp->key.size, bp); 947 bp += sizeof(u_int32_t); 948 argp->key.data = bp; 949 bp += argp->key.size; 950 951 memset(&argp->data, 0, sizeof(argp->data)); 952 LOGCOPY_32(env,&argp->data.size, bp); 953 bp += sizeof(u_int32_t); 954 argp->data.data = bp; 955 bp += argp->data.size; 956 957 LOGCOPY_32(env, &argp->arg_flags, bp); 958 bp += sizeof(argp->arg_flags); 959 960 *argpp = argp; 961 return (ret); 962} 963 964/* 965 * PUBLIC: int __db_debug_log __P((ENV *, DB_TXN *, DB_LSN *, 966 * PUBLIC: u_int32_t, const DBT *, int32_t, const DBT *, const DBT *, 967 * PUBLIC: u_int32_t)); 968 */ 969int 970__db_debug_log(env, txnp, ret_lsnp, flags, 971 op, fileid, key, data, arg_flags) 972 ENV *env; 973 DB_TXN *txnp; 974 DB_LSN *ret_lsnp; 975 u_int32_t flags; 976 const DBT *op; 977 int32_t fileid; 978 const DBT *key; 979 const DBT *data; 980 u_int32_t arg_flags; 981{ 982 DBT logrec; 983 DB_LSN *lsnp, null_lsn, *rlsnp; 984 DB_TXNLOGREC *lr; 985 u_int32_t zero, uinttmp, rectype, txn_num; 986 u_int npad; 987 u_int8_t *bp; 988 int is_durable, ret; 989 990 COMPQUIET(lr, NULL); 991 992 rlsnp = ret_lsnp; 993 rectype = DB___db_debug; 994 npad = 0; 995 ret = 0; 996 997 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 998 if (txnp == NULL) 999 return (0); 1000 if (txnp == NULL) 1001 return (0); 1002 is_durable = 0; 1003 } else 1004 is_durable = 1; 1005 1006 if (txnp == NULL) { 1007 txn_num = 0; 1008 lsnp = &null_lsn; 1009 null_lsn.file = null_lsn.offset = 0; 1010 } else { 1011 /* 1012 * We need to assign begin_lsn while holding region mutex. 1013 * That assignment is done inside the DbEnv->log_put call, 1014 * so pass in the appropriate memory location to be filled 1015 * in by the log_put code. 1016 */ 1017 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1018 txn_num = txnp->txnid; 1019 } 1020 1021 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1022 + sizeof(u_int32_t) + (op == NULL ? 0 : op->size) 1023 + sizeof(u_int32_t) 1024 + sizeof(u_int32_t) + (key == NULL ? 0 : key->size) 1025 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size) 1026 + sizeof(u_int32_t); 1027 if (CRYPTO_ON(env)) { 1028 npad = env->crypto_handle->adj_size(logrec.size); 1029 logrec.size += npad; 1030 } 1031 1032 if (is_durable || txnp == NULL) { 1033 if ((ret = 1034 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1035 return (ret); 1036 } else { 1037 if ((ret = __os_malloc(env, 1038 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1039 return (ret); 1040#ifdef DIAGNOSTIC 1041 if ((ret = 1042 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1043 __os_free(env, lr); 1044 return (ret); 1045 } 1046#else 1047 logrec.data = lr->data; 1048#endif 1049 } 1050 if (npad > 0) 1051 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1052 1053 bp = logrec.data; 1054 1055 LOGCOPY_32(env, bp, &rectype); 1056 bp += sizeof(rectype); 1057 1058 LOGCOPY_32(env, bp, &txn_num); 1059 bp += sizeof(txn_num); 1060 1061 LOGCOPY_FROMLSN(env, bp, lsnp); 1062 bp += sizeof(DB_LSN); 1063 1064 if (op == NULL) { 1065 zero = 0; 1066 LOGCOPY_32(env, bp, &zero); 1067 bp += sizeof(u_int32_t); 1068 } else { 1069 LOGCOPY_32(env, bp, &op->size); 1070 bp += sizeof(op->size); 1071 memcpy(bp, op->data, op->size); 1072 bp += op->size; 1073 } 1074 1075 uinttmp = (u_int32_t)fileid; 1076 LOGCOPY_32(env,bp, &uinttmp); 1077 bp += sizeof(uinttmp); 1078 1079 if (key == NULL) { 1080 zero = 0; 1081 LOGCOPY_32(env, bp, &zero); 1082 bp += sizeof(u_int32_t); 1083 } else { 1084 LOGCOPY_32(env, bp, &key->size); 1085 bp += sizeof(key->size); 1086 memcpy(bp, key->data, key->size); 1087 bp += key->size; 1088 } 1089 1090 if (data == NULL) { 1091 zero = 0; 1092 LOGCOPY_32(env, bp, &zero); 1093 bp += sizeof(u_int32_t); 1094 } else { 1095 LOGCOPY_32(env, bp, &data->size); 1096 bp += sizeof(data->size); 1097 memcpy(bp, data->data, data->size); 1098 bp += data->size; 1099 } 1100 1101 LOGCOPY_32(env, bp, &arg_flags); 1102 bp += sizeof(arg_flags); 1103 1104 DB_ASSERT(env, 1105 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1106 1107 if (is_durable || txnp == NULL) { 1108 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1109 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1110 *lsnp = *rlsnp; 1111 if (rlsnp != ret_lsnp) 1112 *ret_lsnp = *rlsnp; 1113 } 1114 } else { 1115 ret = 0; 1116#ifdef DIAGNOSTIC 1117 /* 1118 * Set the debug bit if we are going to log non-durable 1119 * transactions so they will be ignored by recovery. 1120 */ 1121 memcpy(lr->data, logrec.data, logrec.size); 1122 rectype |= DB_debug_FLAG; 1123 LOGCOPY_32(env, logrec.data, &rectype); 1124 1125 if (!IS_REP_CLIENT(env)) 1126 ret = __log_put(env, 1127 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1128#endif 1129 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1130 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1131 LSN_NOT_LOGGED(*ret_lsnp); 1132 } 1133 1134#ifdef LOG_DIAGNOSTIC 1135 if (ret != 0) 1136 (void)__db_debug_print(env, 1137 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1138#endif 1139 1140#ifdef DIAGNOSTIC 1141 __os_free(env, logrec.data); 1142#else 1143 if (is_durable || txnp == NULL) 1144 __os_free(env, logrec.data); 1145#endif 1146 return (ret); 1147} 1148 1149/* 1150 * PUBLIC: int __db_noop_read __P((ENV *, DB **, void *, void *, 1151 * PUBLIC: __db_noop_args **)); 1152 */ 1153int 1154__db_noop_read(env, dbpp, td, recbuf, argpp) 1155 ENV *env; 1156 DB **dbpp; 1157 void *td; 1158 void *recbuf; 1159 __db_noop_args **argpp; 1160{ 1161 __db_noop_args *argp; 1162 u_int32_t uinttmp; 1163 u_int8_t *bp; 1164 int ret; 1165 1166 if ((ret = __os_malloc(env, 1167 sizeof(__db_noop_args) + sizeof(DB_TXN), &argp)) != 0) 1168 return (ret); 1169 bp = recbuf; 1170 argp->txnp = (DB_TXN *)&argp[1]; 1171 memset(argp->txnp, 0, sizeof(DB_TXN)); 1172 1173 argp->txnp->td = td; 1174 LOGCOPY_32(env, &argp->type, bp); 1175 bp += sizeof(argp->type); 1176 1177 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1178 bp += sizeof(argp->txnp->txnid); 1179 1180 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1181 bp += sizeof(DB_LSN); 1182 1183 LOGCOPY_32(env, &uinttmp, bp); 1184 argp->fileid = (int32_t)uinttmp; 1185 bp += sizeof(uinttmp); 1186 if (dbpp != NULL) { 1187 *dbpp = NULL; 1188 ret = __dbreg_id_to_db( 1189 env, argp->txnp, dbpp, argp->fileid, 1); 1190 } 1191 1192 LOGCOPY_32(env, &uinttmp, bp); 1193 argp->pgno = (db_pgno_t)uinttmp; 1194 bp += sizeof(uinttmp); 1195 1196 LOGCOPY_TOLSN(env, &argp->prevlsn, bp); 1197 bp += sizeof(DB_LSN); 1198 1199 *argpp = argp; 1200 return (ret); 1201} 1202 1203/* 1204 * PUBLIC: int __db_noop_log __P((DB *, DB_TXN *, DB_LSN *, 1205 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *)); 1206 */ 1207int 1208__db_noop_log(dbp, txnp, ret_lsnp, flags, pgno, prevlsn) 1209 DB *dbp; 1210 DB_TXN *txnp; 1211 DB_LSN *ret_lsnp; 1212 u_int32_t flags; 1213 db_pgno_t pgno; 1214 DB_LSN * prevlsn; 1215{ 1216 DBT logrec; 1217 DB_LSN *lsnp, null_lsn, *rlsnp; 1218 DB_TXNLOGREC *lr; 1219 ENV *env; 1220 u_int32_t uinttmp, rectype, txn_num; 1221 u_int npad; 1222 u_int8_t *bp; 1223 int is_durable, ret; 1224 1225 COMPQUIET(lr, NULL); 1226 1227 env = dbp->env; 1228 rlsnp = ret_lsnp; 1229 rectype = DB___db_noop; 1230 npad = 0; 1231 ret = 0; 1232 1233 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1234 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1235 if (txnp == NULL) 1236 return (0); 1237 is_durable = 0; 1238 } else 1239 is_durable = 1; 1240 1241 if (txnp == NULL) { 1242 txn_num = 0; 1243 lsnp = &null_lsn; 1244 null_lsn.file = null_lsn.offset = 0; 1245 } else { 1246 if (TAILQ_FIRST(&txnp->kids) != NULL && 1247 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1248 return (ret); 1249 /* 1250 * We need to assign begin_lsn while holding region mutex. 1251 * That assignment is done inside the DbEnv->log_put call, 1252 * so pass in the appropriate memory location to be filled 1253 * in by the log_put code. 1254 */ 1255 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1256 txn_num = txnp->txnid; 1257 } 1258 1259 DB_ASSERT(env, dbp->log_filename != NULL); 1260 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1261 (ret = __dbreg_lazy_id(dbp)) != 0) 1262 return (ret); 1263 1264 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1265 + sizeof(u_int32_t) 1266 + sizeof(u_int32_t) 1267 + sizeof(*prevlsn); 1268 if (CRYPTO_ON(env)) { 1269 npad = env->crypto_handle->adj_size(logrec.size); 1270 logrec.size += npad; 1271 } 1272 1273 if (is_durable || txnp == NULL) { 1274 if ((ret = 1275 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1276 return (ret); 1277 } else { 1278 if ((ret = __os_malloc(env, 1279 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1280 return (ret); 1281#ifdef DIAGNOSTIC 1282 if ((ret = 1283 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1284 __os_free(env, lr); 1285 return (ret); 1286 } 1287#else 1288 logrec.data = lr->data; 1289#endif 1290 } 1291 if (npad > 0) 1292 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1293 1294 bp = logrec.data; 1295 1296 LOGCOPY_32(env, bp, &rectype); 1297 bp += sizeof(rectype); 1298 1299 LOGCOPY_32(env, bp, &txn_num); 1300 bp += sizeof(txn_num); 1301 1302 LOGCOPY_FROMLSN(env, bp, lsnp); 1303 bp += sizeof(DB_LSN); 1304 1305 uinttmp = (u_int32_t)dbp->log_filename->id; 1306 LOGCOPY_32(env, bp, &uinttmp); 1307 bp += sizeof(uinttmp); 1308 1309 uinttmp = (u_int32_t)pgno; 1310 LOGCOPY_32(env,bp, &uinttmp); 1311 bp += sizeof(uinttmp); 1312 1313 if (prevlsn != NULL) { 1314 if (txnp != NULL) { 1315 LOG *lp = env->lg_handle->reginfo.primary; 1316 if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = 1317 __log_check_page_lsn(env, dbp, prevlsn) != 0)) 1318 return (ret); 1319 } 1320 LOGCOPY_FROMLSN(env, bp, prevlsn); 1321 } else 1322 memset(bp, 0, sizeof(*prevlsn)); 1323 bp += sizeof(*prevlsn); 1324 1325 DB_ASSERT(env, 1326 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1327 1328 if (is_durable || txnp == NULL) { 1329 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1330 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1331 *lsnp = *rlsnp; 1332 if (rlsnp != ret_lsnp) 1333 *ret_lsnp = *rlsnp; 1334 } 1335 } else { 1336 ret = 0; 1337#ifdef DIAGNOSTIC 1338 /* 1339 * Set the debug bit if we are going to log non-durable 1340 * transactions so they will be ignored by recovery. 1341 */ 1342 memcpy(lr->data, logrec.data, logrec.size); 1343 rectype |= DB_debug_FLAG; 1344 LOGCOPY_32(env, logrec.data, &rectype); 1345 1346 if (!IS_REP_CLIENT(env)) 1347 ret = __log_put(env, 1348 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1349#endif 1350 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1351 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1352 LSN_NOT_LOGGED(*ret_lsnp); 1353 } 1354 1355#ifdef LOG_DIAGNOSTIC 1356 if (ret != 0) 1357 (void)__db_noop_print(env, 1358 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1359#endif 1360 1361#ifdef DIAGNOSTIC 1362 __os_free(env, logrec.data); 1363#else 1364 if (is_durable || txnp == NULL) 1365 __os_free(env, logrec.data); 1366#endif 1367 return (ret); 1368} 1369 1370/* 1371 * PUBLIC: int __db_pg_alloc_42_read __P((ENV *, DB **, void *, 1372 * PUBLIC: void *, __db_pg_alloc_42_args **)); 1373 */ 1374int 1375__db_pg_alloc_42_read(env, dbpp, td, recbuf, argpp) 1376 ENV *env; 1377 DB **dbpp; 1378 void *td; 1379 void *recbuf; 1380 __db_pg_alloc_42_args **argpp; 1381{ 1382 __db_pg_alloc_42_args *argp; 1383 u_int32_t uinttmp; 1384 u_int8_t *bp; 1385 int ret; 1386 1387 if ((ret = __os_malloc(env, 1388 sizeof(__db_pg_alloc_42_args) + sizeof(DB_TXN), &argp)) != 0) 1389 return (ret); 1390 bp = recbuf; 1391 argp->txnp = (DB_TXN *)&argp[1]; 1392 memset(argp->txnp, 0, sizeof(DB_TXN)); 1393 1394 argp->txnp->td = td; 1395 LOGCOPY_32(env, &argp->type, bp); 1396 bp += sizeof(argp->type); 1397 1398 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1399 bp += sizeof(argp->txnp->txnid); 1400 1401 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1402 bp += sizeof(DB_LSN); 1403 1404 LOGCOPY_32(env, &uinttmp, bp); 1405 argp->fileid = (int32_t)uinttmp; 1406 bp += sizeof(uinttmp); 1407 if (dbpp != NULL) { 1408 *dbpp = NULL; 1409 ret = __dbreg_id_to_db( 1410 env, argp->txnp, dbpp, argp->fileid, 1); 1411 } 1412 1413 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1414 bp += sizeof(DB_LSN); 1415 1416 LOGCOPY_32(env, &uinttmp, bp); 1417 argp->meta_pgno = (db_pgno_t)uinttmp; 1418 bp += sizeof(uinttmp); 1419 1420 LOGCOPY_TOLSN(env, &argp->page_lsn, bp); 1421 bp += sizeof(DB_LSN); 1422 1423 LOGCOPY_32(env, &uinttmp, bp); 1424 argp->pgno = (db_pgno_t)uinttmp; 1425 bp += sizeof(uinttmp); 1426 1427 LOGCOPY_32(env, &argp->ptype, bp); 1428 bp += sizeof(argp->ptype); 1429 1430 LOGCOPY_32(env, &uinttmp, bp); 1431 argp->next = (db_pgno_t)uinttmp; 1432 bp += sizeof(uinttmp); 1433 1434 *argpp = argp; 1435 return (ret); 1436} 1437 1438/* 1439 * PUBLIC: int __db_pg_alloc_read __P((ENV *, DB **, void *, void *, 1440 * PUBLIC: __db_pg_alloc_args **)); 1441 */ 1442int 1443__db_pg_alloc_read(env, dbpp, td, recbuf, argpp) 1444 ENV *env; 1445 DB **dbpp; 1446 void *td; 1447 void *recbuf; 1448 __db_pg_alloc_args **argpp; 1449{ 1450 __db_pg_alloc_args *argp; 1451 u_int32_t uinttmp; 1452 u_int8_t *bp; 1453 int ret; 1454 1455 if ((ret = __os_malloc(env, 1456 sizeof(__db_pg_alloc_args) + sizeof(DB_TXN), &argp)) != 0) 1457 return (ret); 1458 bp = recbuf; 1459 argp->txnp = (DB_TXN *)&argp[1]; 1460 memset(argp->txnp, 0, sizeof(DB_TXN)); 1461 1462 argp->txnp->td = td; 1463 LOGCOPY_32(env, &argp->type, bp); 1464 bp += sizeof(argp->type); 1465 1466 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1467 bp += sizeof(argp->txnp->txnid); 1468 1469 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1470 bp += sizeof(DB_LSN); 1471 1472 LOGCOPY_32(env, &uinttmp, bp); 1473 argp->fileid = (int32_t)uinttmp; 1474 bp += sizeof(uinttmp); 1475 if (dbpp != NULL) { 1476 *dbpp = NULL; 1477 ret = __dbreg_id_to_db( 1478 env, argp->txnp, dbpp, argp->fileid, 1); 1479 } 1480 1481 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1482 bp += sizeof(DB_LSN); 1483 1484 LOGCOPY_32(env, &uinttmp, bp); 1485 argp->meta_pgno = (db_pgno_t)uinttmp; 1486 bp += sizeof(uinttmp); 1487 1488 LOGCOPY_TOLSN(env, &argp->page_lsn, bp); 1489 bp += sizeof(DB_LSN); 1490 1491 LOGCOPY_32(env, &uinttmp, bp); 1492 argp->pgno = (db_pgno_t)uinttmp; 1493 bp += sizeof(uinttmp); 1494 1495 LOGCOPY_32(env, &argp->ptype, bp); 1496 bp += sizeof(argp->ptype); 1497 1498 LOGCOPY_32(env, &uinttmp, bp); 1499 argp->next = (db_pgno_t)uinttmp; 1500 bp += sizeof(uinttmp); 1501 1502 LOGCOPY_32(env, &uinttmp, bp); 1503 argp->last_pgno = (db_pgno_t)uinttmp; 1504 bp += sizeof(uinttmp); 1505 1506 *argpp = argp; 1507 return (ret); 1508} 1509 1510/* 1511 * PUBLIC: int __db_pg_alloc_log __P((DB *, DB_TXN *, DB_LSN *, 1512 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, u_int32_t, 1513 * PUBLIC: db_pgno_t, db_pgno_t)); 1514 */ 1515int 1516__db_pg_alloc_log(dbp, txnp, ret_lsnp, flags, meta_lsn, meta_pgno, page_lsn, pgno, ptype, 1517 next, last_pgno) 1518 DB *dbp; 1519 DB_TXN *txnp; 1520 DB_LSN *ret_lsnp; 1521 u_int32_t flags; 1522 DB_LSN * meta_lsn; 1523 db_pgno_t meta_pgno; 1524 DB_LSN * page_lsn; 1525 db_pgno_t pgno; 1526 u_int32_t ptype; 1527 db_pgno_t next; 1528 db_pgno_t last_pgno; 1529{ 1530 DBT logrec; 1531 DB_LSN *lsnp, null_lsn, *rlsnp; 1532 DB_TXNLOGREC *lr; 1533 ENV *env; 1534 u_int32_t uinttmp, rectype, txn_num; 1535 u_int npad; 1536 u_int8_t *bp; 1537 int is_durable, ret; 1538 1539 COMPQUIET(lr, NULL); 1540 1541 env = dbp->env; 1542 rlsnp = ret_lsnp; 1543 rectype = DB___db_pg_alloc; 1544 npad = 0; 1545 ret = 0; 1546 1547 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1548 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1549 if (txnp == NULL) 1550 return (0); 1551 is_durable = 0; 1552 } else 1553 is_durable = 1; 1554 1555 if (txnp == NULL) { 1556 txn_num = 0; 1557 lsnp = &null_lsn; 1558 null_lsn.file = null_lsn.offset = 0; 1559 } else { 1560 if (TAILQ_FIRST(&txnp->kids) != NULL && 1561 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1562 return (ret); 1563 /* 1564 * We need to assign begin_lsn while holding region mutex. 1565 * That assignment is done inside the DbEnv->log_put call, 1566 * so pass in the appropriate memory location to be filled 1567 * in by the log_put code. 1568 */ 1569 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1570 txn_num = txnp->txnid; 1571 } 1572 1573 DB_ASSERT(env, dbp->log_filename != NULL); 1574 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1575 (ret = __dbreg_lazy_id(dbp)) != 0) 1576 return (ret); 1577 1578 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1579 + sizeof(u_int32_t) 1580 + sizeof(*meta_lsn) 1581 + sizeof(u_int32_t) 1582 + sizeof(*page_lsn) 1583 + sizeof(u_int32_t) 1584 + sizeof(u_int32_t) 1585 + sizeof(u_int32_t) 1586 + sizeof(u_int32_t); 1587 if (CRYPTO_ON(env)) { 1588 npad = env->crypto_handle->adj_size(logrec.size); 1589 logrec.size += npad; 1590 } 1591 1592 if (is_durable || txnp == NULL) { 1593 if ((ret = 1594 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1595 return (ret); 1596 } else { 1597 if ((ret = __os_malloc(env, 1598 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1599 return (ret); 1600#ifdef DIAGNOSTIC 1601 if ((ret = 1602 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1603 __os_free(env, lr); 1604 return (ret); 1605 } 1606#else 1607 logrec.data = lr->data; 1608#endif 1609 } 1610 if (npad > 0) 1611 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1612 1613 bp = logrec.data; 1614 1615 LOGCOPY_32(env, bp, &rectype); 1616 bp += sizeof(rectype); 1617 1618 LOGCOPY_32(env, bp, &txn_num); 1619 bp += sizeof(txn_num); 1620 1621 LOGCOPY_FROMLSN(env, bp, lsnp); 1622 bp += sizeof(DB_LSN); 1623 1624 uinttmp = (u_int32_t)dbp->log_filename->id; 1625 LOGCOPY_32(env, bp, &uinttmp); 1626 bp += sizeof(uinttmp); 1627 1628 if (meta_lsn != NULL) { 1629 if (txnp != NULL) { 1630 LOG *lp = env->lg_handle->reginfo.primary; 1631 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 1632 __log_check_page_lsn(env, dbp, meta_lsn) != 0)) 1633 return (ret); 1634 } 1635 LOGCOPY_FROMLSN(env, bp, meta_lsn); 1636 } else 1637 memset(bp, 0, sizeof(*meta_lsn)); 1638 bp += sizeof(*meta_lsn); 1639 1640 uinttmp = (u_int32_t)meta_pgno; 1641 LOGCOPY_32(env,bp, &uinttmp); 1642 bp += sizeof(uinttmp); 1643 1644 if (page_lsn != NULL) { 1645 if (txnp != NULL) { 1646 LOG *lp = env->lg_handle->reginfo.primary; 1647 if (LOG_COMPARE(page_lsn, &lp->lsn) >= 0 && (ret = 1648 __log_check_page_lsn(env, dbp, page_lsn) != 0)) 1649 return (ret); 1650 } 1651 LOGCOPY_FROMLSN(env, bp, page_lsn); 1652 } else 1653 memset(bp, 0, sizeof(*page_lsn)); 1654 bp += sizeof(*page_lsn); 1655 1656 uinttmp = (u_int32_t)pgno; 1657 LOGCOPY_32(env,bp, &uinttmp); 1658 bp += sizeof(uinttmp); 1659 1660 LOGCOPY_32(env, bp, &ptype); 1661 bp += sizeof(ptype); 1662 1663 uinttmp = (u_int32_t)next; 1664 LOGCOPY_32(env,bp, &uinttmp); 1665 bp += sizeof(uinttmp); 1666 1667 uinttmp = (u_int32_t)last_pgno; 1668 LOGCOPY_32(env,bp, &uinttmp); 1669 bp += sizeof(uinttmp); 1670 1671 DB_ASSERT(env, 1672 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1673 1674 if (is_durable || txnp == NULL) { 1675 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1676 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1677 *lsnp = *rlsnp; 1678 if (rlsnp != ret_lsnp) 1679 *ret_lsnp = *rlsnp; 1680 } 1681 } else { 1682 ret = 0; 1683#ifdef DIAGNOSTIC 1684 /* 1685 * Set the debug bit if we are going to log non-durable 1686 * transactions so they will be ignored by recovery. 1687 */ 1688 memcpy(lr->data, logrec.data, logrec.size); 1689 rectype |= DB_debug_FLAG; 1690 LOGCOPY_32(env, logrec.data, &rectype); 1691 1692 if (!IS_REP_CLIENT(env)) 1693 ret = __log_put(env, 1694 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1695#endif 1696 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1697 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1698 LSN_NOT_LOGGED(*ret_lsnp); 1699 } 1700 1701#ifdef LOG_DIAGNOSTIC 1702 if (ret != 0) 1703 (void)__db_pg_alloc_print(env, 1704 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1705#endif 1706 1707#ifdef DIAGNOSTIC 1708 __os_free(env, logrec.data); 1709#else 1710 if (is_durable || txnp == NULL) 1711 __os_free(env, logrec.data); 1712#endif 1713 return (ret); 1714} 1715 1716/* 1717 * PUBLIC: int __db_pg_free_42_read __P((ENV *, DB **, void *, 1718 * PUBLIC: void *, __db_pg_free_42_args **)); 1719 */ 1720int 1721__db_pg_free_42_read(env, dbpp, td, recbuf, argpp) 1722 ENV *env; 1723 DB **dbpp; 1724 void *td; 1725 void *recbuf; 1726 __db_pg_free_42_args **argpp; 1727{ 1728 __db_pg_free_42_args *argp; 1729 u_int32_t uinttmp; 1730 u_int8_t *bp; 1731 int ret; 1732 1733 if ((ret = __os_malloc(env, 1734 sizeof(__db_pg_free_42_args) + sizeof(DB_TXN), &argp)) != 0) 1735 return (ret); 1736 bp = recbuf; 1737 argp->txnp = (DB_TXN *)&argp[1]; 1738 memset(argp->txnp, 0, sizeof(DB_TXN)); 1739 1740 argp->txnp->td = td; 1741 LOGCOPY_32(env, &argp->type, bp); 1742 bp += sizeof(argp->type); 1743 1744 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1745 bp += sizeof(argp->txnp->txnid); 1746 1747 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1748 bp += sizeof(DB_LSN); 1749 1750 LOGCOPY_32(env, &uinttmp, bp); 1751 argp->fileid = (int32_t)uinttmp; 1752 bp += sizeof(uinttmp); 1753 if (dbpp != NULL) { 1754 *dbpp = NULL; 1755 ret = __dbreg_id_to_db( 1756 env, argp->txnp, dbpp, argp->fileid, 1); 1757 } 1758 1759 LOGCOPY_32(env, &uinttmp, bp); 1760 argp->pgno = (db_pgno_t)uinttmp; 1761 bp += sizeof(uinttmp); 1762 1763 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1764 bp += sizeof(DB_LSN); 1765 1766 LOGCOPY_32(env, &uinttmp, bp); 1767 argp->meta_pgno = (db_pgno_t)uinttmp; 1768 bp += sizeof(uinttmp); 1769 1770 memset(&argp->header, 0, sizeof(argp->header)); 1771 LOGCOPY_32(env,&argp->header.size, bp); 1772 bp += sizeof(u_int32_t); 1773 argp->header.data = bp; 1774 bp += argp->header.size; 1775 1776 LOGCOPY_32(env, &uinttmp, bp); 1777 argp->next = (db_pgno_t)uinttmp; 1778 bp += sizeof(uinttmp); 1779 1780 *argpp = argp; 1781 return (ret); 1782} 1783 1784/* 1785 * PUBLIC: int __db_pg_free_read __P((ENV *, DB **, void *, void *, 1786 * PUBLIC: __db_pg_free_args **)); 1787 */ 1788int 1789__db_pg_free_read(env, dbpp, td, recbuf, argpp) 1790 ENV *env; 1791 DB **dbpp; 1792 void *td; 1793 void *recbuf; 1794 __db_pg_free_args **argpp; 1795{ 1796 __db_pg_free_args *argp; 1797 u_int32_t uinttmp; 1798 u_int8_t *bp; 1799 int ret; 1800 1801 if ((ret = __os_malloc(env, 1802 sizeof(__db_pg_free_args) + sizeof(DB_TXN), &argp)) != 0) 1803 return (ret); 1804 bp = recbuf; 1805 argp->txnp = (DB_TXN *)&argp[1]; 1806 memset(argp->txnp, 0, sizeof(DB_TXN)); 1807 1808 argp->txnp->td = td; 1809 LOGCOPY_32(env, &argp->type, bp); 1810 bp += sizeof(argp->type); 1811 1812 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1813 bp += sizeof(argp->txnp->txnid); 1814 1815 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1816 bp += sizeof(DB_LSN); 1817 1818 LOGCOPY_32(env, &uinttmp, bp); 1819 argp->fileid = (int32_t)uinttmp; 1820 bp += sizeof(uinttmp); 1821 if (dbpp != NULL) { 1822 *dbpp = NULL; 1823 ret = __dbreg_id_to_db( 1824 env, argp->txnp, dbpp, argp->fileid, 1); 1825 } 1826 1827 LOGCOPY_32(env, &uinttmp, bp); 1828 argp->pgno = (db_pgno_t)uinttmp; 1829 bp += sizeof(uinttmp); 1830 1831 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1832 bp += sizeof(DB_LSN); 1833 1834 LOGCOPY_32(env, &uinttmp, bp); 1835 argp->meta_pgno = (db_pgno_t)uinttmp; 1836 bp += sizeof(uinttmp); 1837 1838 memset(&argp->header, 0, sizeof(argp->header)); 1839 LOGCOPY_32(env,&argp->header.size, bp); 1840 bp += sizeof(u_int32_t); 1841 argp->header.data = bp; 1842 bp += argp->header.size; 1843 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 1844 int t_ret; 1845 if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->header.data, 1846 (size_t)argp->header.size, NULL, 1)) != 0) 1847 return (t_ret); 1848 } 1849 1850 LOGCOPY_32(env, &uinttmp, bp); 1851 argp->next = (db_pgno_t)uinttmp; 1852 bp += sizeof(uinttmp); 1853 1854 LOGCOPY_32(env, &uinttmp, bp); 1855 argp->last_pgno = (db_pgno_t)uinttmp; 1856 bp += sizeof(uinttmp); 1857 1858 *argpp = argp; 1859 return (ret); 1860} 1861 1862/* 1863 * PUBLIC: int __db_pg_free_log __P((DB *, DB_TXN *, DB_LSN *, 1864 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, 1865 * PUBLIC: db_pgno_t, db_pgno_t)); 1866 */ 1867int 1868__db_pg_free_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, 1869 last_pgno) 1870 DB *dbp; 1871 DB_TXN *txnp; 1872 DB_LSN *ret_lsnp; 1873 u_int32_t flags; 1874 db_pgno_t pgno; 1875 DB_LSN * meta_lsn; 1876 db_pgno_t meta_pgno; 1877 const DBT *header; 1878 db_pgno_t next; 1879 db_pgno_t last_pgno; 1880{ 1881 DBT logrec; 1882 DB_LSN *lsnp, null_lsn, *rlsnp; 1883 DB_TXNLOGREC *lr; 1884 ENV *env; 1885 u_int32_t zero, uinttmp, rectype, txn_num; 1886 u_int npad; 1887 u_int8_t *bp; 1888 int is_durable, ret; 1889 1890 COMPQUIET(lr, NULL); 1891 1892 env = dbp->env; 1893 rlsnp = ret_lsnp; 1894 rectype = DB___db_pg_free; 1895 npad = 0; 1896 ret = 0; 1897 1898 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1899 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1900 if (txnp == NULL) 1901 return (0); 1902 is_durable = 0; 1903 } else 1904 is_durable = 1; 1905 1906 if (txnp == NULL) { 1907 txn_num = 0; 1908 lsnp = &null_lsn; 1909 null_lsn.file = null_lsn.offset = 0; 1910 } else { 1911 if (TAILQ_FIRST(&txnp->kids) != NULL && 1912 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1913 return (ret); 1914 /* 1915 * We need to assign begin_lsn while holding region mutex. 1916 * That assignment is done inside the DbEnv->log_put call, 1917 * so pass in the appropriate memory location to be filled 1918 * in by the log_put code. 1919 */ 1920 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1921 txn_num = txnp->txnid; 1922 } 1923 1924 DB_ASSERT(env, dbp->log_filename != NULL); 1925 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1926 (ret = __dbreg_lazy_id(dbp)) != 0) 1927 return (ret); 1928 1929 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1930 + sizeof(u_int32_t) 1931 + sizeof(u_int32_t) 1932 + sizeof(*meta_lsn) 1933 + sizeof(u_int32_t) 1934 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 1935 + sizeof(u_int32_t) 1936 + sizeof(u_int32_t); 1937 if (CRYPTO_ON(env)) { 1938 npad = env->crypto_handle->adj_size(logrec.size); 1939 logrec.size += npad; 1940 } 1941 1942 if (is_durable || txnp == NULL) { 1943 if ((ret = 1944 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1945 return (ret); 1946 } else { 1947 if ((ret = __os_malloc(env, 1948 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1949 return (ret); 1950#ifdef DIAGNOSTIC 1951 if ((ret = 1952 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1953 __os_free(env, lr); 1954 return (ret); 1955 } 1956#else 1957 logrec.data = lr->data; 1958#endif 1959 } 1960 if (npad > 0) 1961 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1962 1963 bp = logrec.data; 1964 1965 LOGCOPY_32(env, bp, &rectype); 1966 bp += sizeof(rectype); 1967 1968 LOGCOPY_32(env, bp, &txn_num); 1969 bp += sizeof(txn_num); 1970 1971 LOGCOPY_FROMLSN(env, bp, lsnp); 1972 bp += sizeof(DB_LSN); 1973 1974 uinttmp = (u_int32_t)dbp->log_filename->id; 1975 LOGCOPY_32(env, bp, &uinttmp); 1976 bp += sizeof(uinttmp); 1977 1978 uinttmp = (u_int32_t)pgno; 1979 LOGCOPY_32(env,bp, &uinttmp); 1980 bp += sizeof(uinttmp); 1981 1982 if (meta_lsn != NULL) { 1983 if (txnp != NULL) { 1984 LOG *lp = env->lg_handle->reginfo.primary; 1985 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 1986 __log_check_page_lsn(env, dbp, meta_lsn) != 0)) 1987 return (ret); 1988 } 1989 LOGCOPY_FROMLSN(env, bp, meta_lsn); 1990 } else 1991 memset(bp, 0, sizeof(*meta_lsn)); 1992 bp += sizeof(*meta_lsn); 1993 1994 uinttmp = (u_int32_t)meta_pgno; 1995 LOGCOPY_32(env,bp, &uinttmp); 1996 bp += sizeof(uinttmp); 1997 1998 if (header == NULL) { 1999 zero = 0; 2000 LOGCOPY_32(env, bp, &zero); 2001 bp += sizeof(u_int32_t); 2002 } else { 2003 LOGCOPY_32(env, bp, &header->size); 2004 bp += sizeof(header->size); 2005 memcpy(bp, header->data, header->size); 2006 if (LOG_SWAPPED(env)) 2007 if ((ret = __db_pageswap(dbp, 2008 (PAGE *)bp, (size_t)header->size, (DBT *)NULL, 0)) != 0) 2009 return (ret); 2010 bp += header->size; 2011 } 2012 2013 uinttmp = (u_int32_t)next; 2014 LOGCOPY_32(env,bp, &uinttmp); 2015 bp += sizeof(uinttmp); 2016 2017 uinttmp = (u_int32_t)last_pgno; 2018 LOGCOPY_32(env,bp, &uinttmp); 2019 bp += sizeof(uinttmp); 2020 2021 DB_ASSERT(env, 2022 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2023 2024 if (is_durable || txnp == NULL) { 2025 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2026 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2027 *lsnp = *rlsnp; 2028 if (rlsnp != ret_lsnp) 2029 *ret_lsnp = *rlsnp; 2030 } 2031 } else { 2032 ret = 0; 2033#ifdef DIAGNOSTIC 2034 /* 2035 * Set the debug bit if we are going to log non-durable 2036 * transactions so they will be ignored by recovery. 2037 */ 2038 memcpy(lr->data, logrec.data, logrec.size); 2039 rectype |= DB_debug_FLAG; 2040 LOGCOPY_32(env, logrec.data, &rectype); 2041 2042 if (!IS_REP_CLIENT(env)) 2043 ret = __log_put(env, 2044 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2045#endif 2046 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2047 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2048 LSN_NOT_LOGGED(*ret_lsnp); 2049 } 2050 2051#ifdef LOG_DIAGNOSTIC 2052 if (ret != 0) 2053 (void)__db_pg_free_print(env, 2054 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2055#endif 2056 2057#ifdef DIAGNOSTIC 2058 __os_free(env, logrec.data); 2059#else 2060 if (is_durable || txnp == NULL) 2061 __os_free(env, logrec.data); 2062#endif 2063 return (ret); 2064} 2065 2066/* 2067 * PUBLIC: int __db_cksum_read __P((ENV *, void *, __db_cksum_args **)); 2068 */ 2069int 2070__db_cksum_read(env, recbuf, argpp) 2071 ENV *env; 2072 void *recbuf; 2073 __db_cksum_args **argpp; 2074{ 2075 __db_cksum_args *argp; 2076 u_int8_t *bp; 2077 int ret; 2078 2079 if ((ret = __os_malloc(env, 2080 sizeof(__db_cksum_args) + sizeof(DB_TXN), &argp)) != 0) 2081 return (ret); 2082 bp = recbuf; 2083 argp->txnp = (DB_TXN *)&argp[1]; 2084 memset(argp->txnp, 0, sizeof(DB_TXN)); 2085 2086 LOGCOPY_32(env, &argp->type, bp); 2087 bp += sizeof(argp->type); 2088 2089 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2090 bp += sizeof(argp->txnp->txnid); 2091 2092 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2093 bp += sizeof(DB_LSN); 2094 2095 *argpp = argp; 2096 return (ret); 2097} 2098 2099/* 2100 * PUBLIC: int __db_cksum_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t)); 2101 */ 2102int 2103__db_cksum_log(env, txnp, ret_lsnp, flags) 2104 ENV *env; 2105 DB_TXN *txnp; 2106 DB_LSN *ret_lsnp; 2107 u_int32_t flags; 2108{ 2109 DBT logrec; 2110 DB_LSN *lsnp, null_lsn, *rlsnp; 2111 DB_TXNLOGREC *lr; 2112 u_int32_t rectype, txn_num; 2113 u_int npad; 2114 u_int8_t *bp; 2115 int is_durable, ret; 2116 2117 COMPQUIET(lr, NULL); 2118 2119 rlsnp = ret_lsnp; 2120 rectype = DB___db_cksum; 2121 npad = 0; 2122 ret = 0; 2123 2124 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 2125 if (txnp == NULL) 2126 return (0); 2127 if (txnp == NULL) 2128 return (0); 2129 is_durable = 0; 2130 } else 2131 is_durable = 1; 2132 2133 if (txnp == NULL) { 2134 txn_num = 0; 2135 lsnp = &null_lsn; 2136 null_lsn.file = null_lsn.offset = 0; 2137 } else { 2138 if (TAILQ_FIRST(&txnp->kids) != NULL && 2139 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2140 return (ret); 2141 /* 2142 * We need to assign begin_lsn while holding region mutex. 2143 * That assignment is done inside the DbEnv->log_put call, 2144 * so pass in the appropriate memory location to be filled 2145 * in by the log_put code. 2146 */ 2147 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2148 txn_num = txnp->txnid; 2149 } 2150 2151 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN); 2152 if (CRYPTO_ON(env)) { 2153 npad = env->crypto_handle->adj_size(logrec.size); 2154 logrec.size += npad; 2155 } 2156 2157 if (is_durable || txnp == NULL) { 2158 if ((ret = 2159 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2160 return (ret); 2161 } else { 2162 if ((ret = __os_malloc(env, 2163 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2164 return (ret); 2165#ifdef DIAGNOSTIC 2166 if ((ret = 2167 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2168 __os_free(env, lr); 2169 return (ret); 2170 } 2171#else 2172 logrec.data = lr->data; 2173#endif 2174 } 2175 if (npad > 0) 2176 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2177 2178 bp = logrec.data; 2179 2180 LOGCOPY_32(env, bp, &rectype); 2181 bp += sizeof(rectype); 2182 2183 LOGCOPY_32(env, bp, &txn_num); 2184 bp += sizeof(txn_num); 2185 2186 LOGCOPY_FROMLSN(env, bp, lsnp); 2187 bp += sizeof(DB_LSN); 2188 2189 DB_ASSERT(env, 2190 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2191 2192 if (is_durable || txnp == NULL) { 2193 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2194 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2195 *lsnp = *rlsnp; 2196 if (rlsnp != ret_lsnp) 2197 *ret_lsnp = *rlsnp; 2198 } 2199 } else { 2200 ret = 0; 2201#ifdef DIAGNOSTIC 2202 /* 2203 * Set the debug bit if we are going to log non-durable 2204 * transactions so they will be ignored by recovery. 2205 */ 2206 memcpy(lr->data, logrec.data, logrec.size); 2207 rectype |= DB_debug_FLAG; 2208 LOGCOPY_32(env, logrec.data, &rectype); 2209 2210 if (!IS_REP_CLIENT(env)) 2211 ret = __log_put(env, 2212 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2213#endif 2214 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2215 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2216 LSN_NOT_LOGGED(*ret_lsnp); 2217 } 2218 2219#ifdef LOG_DIAGNOSTIC 2220 if (ret != 0) 2221 (void)__db_cksum_print(env, 2222 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2223#endif 2224 2225#ifdef DIAGNOSTIC 2226 __os_free(env, logrec.data); 2227#else 2228 if (is_durable || txnp == NULL) 2229 __os_free(env, logrec.data); 2230#endif 2231 return (ret); 2232} 2233 2234/* 2235 * PUBLIC: int __db_pg_freedata_42_read __P((ENV *, DB **, void *, 2236 * PUBLIC: void *, __db_pg_freedata_42_args **)); 2237 */ 2238int 2239__db_pg_freedata_42_read(env, dbpp, td, recbuf, argpp) 2240 ENV *env; 2241 DB **dbpp; 2242 void *td; 2243 void *recbuf; 2244 __db_pg_freedata_42_args **argpp; 2245{ 2246 __db_pg_freedata_42_args *argp; 2247 u_int32_t uinttmp; 2248 u_int8_t *bp; 2249 int ret; 2250 2251 if ((ret = __os_malloc(env, 2252 sizeof(__db_pg_freedata_42_args) + sizeof(DB_TXN), &argp)) != 0) 2253 return (ret); 2254 bp = recbuf; 2255 argp->txnp = (DB_TXN *)&argp[1]; 2256 memset(argp->txnp, 0, sizeof(DB_TXN)); 2257 2258 argp->txnp->td = td; 2259 LOGCOPY_32(env, &argp->type, bp); 2260 bp += sizeof(argp->type); 2261 2262 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2263 bp += sizeof(argp->txnp->txnid); 2264 2265 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2266 bp += sizeof(DB_LSN); 2267 2268 LOGCOPY_32(env, &uinttmp, bp); 2269 argp->fileid = (int32_t)uinttmp; 2270 bp += sizeof(uinttmp); 2271 if (dbpp != NULL) { 2272 *dbpp = NULL; 2273 ret = __dbreg_id_to_db( 2274 env, argp->txnp, dbpp, argp->fileid, 1); 2275 } 2276 2277 LOGCOPY_32(env, &uinttmp, bp); 2278 argp->pgno = (db_pgno_t)uinttmp; 2279 bp += sizeof(uinttmp); 2280 2281 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2282 bp += sizeof(DB_LSN); 2283 2284 LOGCOPY_32(env, &uinttmp, bp); 2285 argp->meta_pgno = (db_pgno_t)uinttmp; 2286 bp += sizeof(uinttmp); 2287 2288 memset(&argp->header, 0, sizeof(argp->header)); 2289 LOGCOPY_32(env,&argp->header.size, bp); 2290 bp += sizeof(u_int32_t); 2291 argp->header.data = bp; 2292 bp += argp->header.size; 2293 2294 LOGCOPY_32(env, &uinttmp, bp); 2295 argp->next = (db_pgno_t)uinttmp; 2296 bp += sizeof(uinttmp); 2297 2298 memset(&argp->data, 0, sizeof(argp->data)); 2299 LOGCOPY_32(env,&argp->data.size, bp); 2300 bp += sizeof(u_int32_t); 2301 argp->data.data = bp; 2302 bp += argp->data.size; 2303 2304 *argpp = argp; 2305 return (ret); 2306} 2307 2308/* 2309 * PUBLIC: int __db_pg_freedata_read __P((ENV *, DB **, void *, 2310 * PUBLIC: void *, __db_pg_freedata_args **)); 2311 */ 2312int 2313__db_pg_freedata_read(env, dbpp, td, recbuf, argpp) 2314 ENV *env; 2315 DB **dbpp; 2316 void *td; 2317 void *recbuf; 2318 __db_pg_freedata_args **argpp; 2319{ 2320 __db_pg_freedata_args *argp; 2321 u_int32_t uinttmp; 2322 u_int8_t *bp; 2323 int ret; 2324 2325 if ((ret = __os_malloc(env, 2326 sizeof(__db_pg_freedata_args) + sizeof(DB_TXN), &argp)) != 0) 2327 return (ret); 2328 bp = recbuf; 2329 argp->txnp = (DB_TXN *)&argp[1]; 2330 memset(argp->txnp, 0, sizeof(DB_TXN)); 2331 2332 argp->txnp->td = td; 2333 LOGCOPY_32(env, &argp->type, bp); 2334 bp += sizeof(argp->type); 2335 2336 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2337 bp += sizeof(argp->txnp->txnid); 2338 2339 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2340 bp += sizeof(DB_LSN); 2341 2342 LOGCOPY_32(env, &uinttmp, bp); 2343 argp->fileid = (int32_t)uinttmp; 2344 bp += sizeof(uinttmp); 2345 if (dbpp != NULL) { 2346 *dbpp = NULL; 2347 ret = __dbreg_id_to_db( 2348 env, argp->txnp, dbpp, argp->fileid, 1); 2349 } 2350 2351 LOGCOPY_32(env, &uinttmp, bp); 2352 argp->pgno = (db_pgno_t)uinttmp; 2353 bp += sizeof(uinttmp); 2354 2355 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2356 bp += sizeof(DB_LSN); 2357 2358 LOGCOPY_32(env, &uinttmp, bp); 2359 argp->meta_pgno = (db_pgno_t)uinttmp; 2360 bp += sizeof(uinttmp); 2361 2362 memset(&argp->header, 0, sizeof(argp->header)); 2363 LOGCOPY_32(env,&argp->header.size, bp); 2364 bp += sizeof(u_int32_t); 2365 argp->header.data = bp; 2366 bp += argp->header.size; 2367 2368 LOGCOPY_32(env, &uinttmp, bp); 2369 argp->next = (db_pgno_t)uinttmp; 2370 bp += sizeof(uinttmp); 2371 2372 LOGCOPY_32(env, &uinttmp, bp); 2373 argp->last_pgno = (db_pgno_t)uinttmp; 2374 bp += sizeof(uinttmp); 2375 2376 memset(&argp->data, 0, sizeof(argp->data)); 2377 LOGCOPY_32(env,&argp->data.size, bp); 2378 bp += sizeof(u_int32_t); 2379 argp->data.data = bp; 2380 bp += argp->data.size; 2381 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 2382 int t_ret; 2383 if ((t_ret = __db_pageswap(*dbpp, 2384 (PAGE *)argp->header.data, (size_t)argp->header.size, 2385 &argp->data, 1)) != 0) 2386 return (t_ret); 2387 } 2388 2389 *argpp = argp; 2390 return (ret); 2391} 2392 2393/* 2394 * PUBLIC: int __db_pg_freedata_log __P((DB *, DB_TXN *, DB_LSN *, 2395 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, 2396 * PUBLIC: db_pgno_t, db_pgno_t, const DBT *)); 2397 */ 2398int 2399__db_pg_freedata_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, 2400 last_pgno, data) 2401 DB *dbp; 2402 DB_TXN *txnp; 2403 DB_LSN *ret_lsnp; 2404 u_int32_t flags; 2405 db_pgno_t pgno; 2406 DB_LSN * meta_lsn; 2407 db_pgno_t meta_pgno; 2408 const DBT *header; 2409 db_pgno_t next; 2410 db_pgno_t last_pgno; 2411 const DBT *data; 2412{ 2413 DBT logrec; 2414 DB_LSN *lsnp, null_lsn, *rlsnp; 2415 DB_TXNLOGREC *lr; 2416 ENV *env; 2417 u_int32_t zero, uinttmp, rectype, txn_num; 2418 u_int npad; 2419 u_int8_t *bp; 2420 int is_durable, ret; 2421 2422 COMPQUIET(lr, NULL); 2423 2424 env = dbp->env; 2425 rlsnp = ret_lsnp; 2426 rectype = DB___db_pg_freedata; 2427 npad = 0; 2428 ret = 0; 2429 2430 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2431 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2432 if (txnp == NULL) 2433 return (0); 2434 is_durable = 0; 2435 } else 2436 is_durable = 1; 2437 2438 if (txnp == NULL) { 2439 txn_num = 0; 2440 lsnp = &null_lsn; 2441 null_lsn.file = null_lsn.offset = 0; 2442 } else { 2443 if (TAILQ_FIRST(&txnp->kids) != NULL && 2444 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2445 return (ret); 2446 /* 2447 * We need to assign begin_lsn while holding region mutex. 2448 * That assignment is done inside the DbEnv->log_put call, 2449 * so pass in the appropriate memory location to be filled 2450 * in by the log_put code. 2451 */ 2452 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2453 txn_num = txnp->txnid; 2454 } 2455 2456 DB_ASSERT(env, dbp->log_filename != NULL); 2457 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2458 (ret = __dbreg_lazy_id(dbp)) != 0) 2459 return (ret); 2460 2461 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2462 + sizeof(u_int32_t) 2463 + sizeof(u_int32_t) 2464 + sizeof(*meta_lsn) 2465 + sizeof(u_int32_t) 2466 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 2467 + sizeof(u_int32_t) 2468 + sizeof(u_int32_t) 2469 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 2470 if (CRYPTO_ON(env)) { 2471 npad = env->crypto_handle->adj_size(logrec.size); 2472 logrec.size += npad; 2473 } 2474 2475 if (is_durable || txnp == NULL) { 2476 if ((ret = 2477 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2478 return (ret); 2479 } else { 2480 if ((ret = __os_malloc(env, 2481 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2482 return (ret); 2483#ifdef DIAGNOSTIC 2484 if ((ret = 2485 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2486 __os_free(env, lr); 2487 return (ret); 2488 } 2489#else 2490 logrec.data = lr->data; 2491#endif 2492 } 2493 if (npad > 0) 2494 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2495 2496 bp = logrec.data; 2497 2498 LOGCOPY_32(env, bp, &rectype); 2499 bp += sizeof(rectype); 2500 2501 LOGCOPY_32(env, bp, &txn_num); 2502 bp += sizeof(txn_num); 2503 2504 LOGCOPY_FROMLSN(env, bp, lsnp); 2505 bp += sizeof(DB_LSN); 2506 2507 uinttmp = (u_int32_t)dbp->log_filename->id; 2508 LOGCOPY_32(env, bp, &uinttmp); 2509 bp += sizeof(uinttmp); 2510 2511 uinttmp = (u_int32_t)pgno; 2512 LOGCOPY_32(env,bp, &uinttmp); 2513 bp += sizeof(uinttmp); 2514 2515 if (meta_lsn != NULL) { 2516 if (txnp != NULL) { 2517 LOG *lp = env->lg_handle->reginfo.primary; 2518 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 2519 __log_check_page_lsn(env, dbp, meta_lsn) != 0)) 2520 return (ret); 2521 } 2522 LOGCOPY_FROMLSN(env, bp, meta_lsn); 2523 } else 2524 memset(bp, 0, sizeof(*meta_lsn)); 2525 bp += sizeof(*meta_lsn); 2526 2527 uinttmp = (u_int32_t)meta_pgno; 2528 LOGCOPY_32(env,bp, &uinttmp); 2529 bp += sizeof(uinttmp); 2530 2531 if (header == NULL) { 2532 zero = 0; 2533 LOGCOPY_32(env, bp, &zero); 2534 bp += sizeof(u_int32_t); 2535 } else { 2536 LOGCOPY_32(env, bp, &header->size); 2537 bp += sizeof(header->size); 2538 memcpy(bp, header->data, header->size); 2539 if (LOG_SWAPPED(env)) 2540 if ((ret = __db_pageswap(dbp, 2541 (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) 2542 return (ret); 2543 bp += header->size; 2544 } 2545 2546 uinttmp = (u_int32_t)next; 2547 LOGCOPY_32(env,bp, &uinttmp); 2548 bp += sizeof(uinttmp); 2549 2550 uinttmp = (u_int32_t)last_pgno; 2551 LOGCOPY_32(env,bp, &uinttmp); 2552 bp += sizeof(uinttmp); 2553 2554 if (data == NULL) { 2555 zero = 0; 2556 LOGCOPY_32(env, bp, &zero); 2557 bp += sizeof(u_int32_t); 2558 } else { 2559 LOGCOPY_32(env, bp, &data->size); 2560 bp += sizeof(data->size); 2561 memcpy(bp, data->data, data->size); 2562 if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) 2563 __os_free(env, data->data); 2564 bp += data->size; 2565 } 2566 2567 DB_ASSERT(env, 2568 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2569 2570 if (is_durable || txnp == NULL) { 2571 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2572 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2573 *lsnp = *rlsnp; 2574 if (rlsnp != ret_lsnp) 2575 *ret_lsnp = *rlsnp; 2576 } 2577 } else { 2578 ret = 0; 2579#ifdef DIAGNOSTIC 2580 /* 2581 * Set the debug bit if we are going to log non-durable 2582 * transactions so they will be ignored by recovery. 2583 */ 2584 memcpy(lr->data, logrec.data, logrec.size); 2585 rectype |= DB_debug_FLAG; 2586 LOGCOPY_32(env, logrec.data, &rectype); 2587 2588 if (!IS_REP_CLIENT(env)) 2589 ret = __log_put(env, 2590 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2591#endif 2592 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2593 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2594 LSN_NOT_LOGGED(*ret_lsnp); 2595 } 2596 2597#ifdef LOG_DIAGNOSTIC 2598 if (ret != 0) 2599 (void)__db_pg_freedata_print(env, 2600 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2601#endif 2602 2603#ifdef DIAGNOSTIC 2604 __os_free(env, logrec.data); 2605#else 2606 if (is_durable || txnp == NULL) 2607 __os_free(env, logrec.data); 2608#endif 2609 return (ret); 2610} 2611 2612/* 2613 * PUBLIC: int __db_pg_init_read __P((ENV *, DB **, void *, void *, 2614 * PUBLIC: __db_pg_init_args **)); 2615 */ 2616int 2617__db_pg_init_read(env, dbpp, td, recbuf, argpp) 2618 ENV *env; 2619 DB **dbpp; 2620 void *td; 2621 void *recbuf; 2622 __db_pg_init_args **argpp; 2623{ 2624 __db_pg_init_args *argp; 2625 u_int32_t uinttmp; 2626 u_int8_t *bp; 2627 int ret; 2628 2629 if ((ret = __os_malloc(env, 2630 sizeof(__db_pg_init_args) + sizeof(DB_TXN), &argp)) != 0) 2631 return (ret); 2632 bp = recbuf; 2633 argp->txnp = (DB_TXN *)&argp[1]; 2634 memset(argp->txnp, 0, sizeof(DB_TXN)); 2635 2636 argp->txnp->td = td; 2637 LOGCOPY_32(env, &argp->type, bp); 2638 bp += sizeof(argp->type); 2639 2640 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2641 bp += sizeof(argp->txnp->txnid); 2642 2643 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2644 bp += sizeof(DB_LSN); 2645 2646 LOGCOPY_32(env, &uinttmp, bp); 2647 argp->fileid = (int32_t)uinttmp; 2648 bp += sizeof(uinttmp); 2649 if (dbpp != NULL) { 2650 *dbpp = NULL; 2651 ret = __dbreg_id_to_db( 2652 env, argp->txnp, dbpp, argp->fileid, 1); 2653 } 2654 2655 LOGCOPY_32(env, &uinttmp, bp); 2656 argp->pgno = (db_pgno_t)uinttmp; 2657 bp += sizeof(uinttmp); 2658 2659 memset(&argp->header, 0, sizeof(argp->header)); 2660 LOGCOPY_32(env,&argp->header.size, bp); 2661 bp += sizeof(u_int32_t); 2662 argp->header.data = bp; 2663 bp += argp->header.size; 2664 2665 memset(&argp->data, 0, sizeof(argp->data)); 2666 LOGCOPY_32(env,&argp->data.size, bp); 2667 bp += sizeof(u_int32_t); 2668 argp->data.data = bp; 2669 bp += argp->data.size; 2670 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 2671 int t_ret; 2672 if ((t_ret = __db_pageswap(*dbpp, 2673 (PAGE *)argp->header.data, (size_t)argp->header.size, 2674 &argp->data, 1)) != 0) 2675 return (t_ret); 2676 } 2677 2678 *argpp = argp; 2679 return (ret); 2680} 2681 2682/* 2683 * PUBLIC: int __db_pg_init_log __P((DB *, DB_TXN *, DB_LSN *, 2684 * PUBLIC: u_int32_t, db_pgno_t, const DBT *, const DBT *)); 2685 */ 2686int 2687__db_pg_init_log(dbp, txnp, ret_lsnp, flags, pgno, header, data) 2688 DB *dbp; 2689 DB_TXN *txnp; 2690 DB_LSN *ret_lsnp; 2691 u_int32_t flags; 2692 db_pgno_t pgno; 2693 const DBT *header; 2694 const DBT *data; 2695{ 2696 DBT logrec; 2697 DB_LSN *lsnp, null_lsn, *rlsnp; 2698 DB_TXNLOGREC *lr; 2699 ENV *env; 2700 u_int32_t zero, uinttmp, rectype, txn_num; 2701 u_int npad; 2702 u_int8_t *bp; 2703 int is_durable, ret; 2704 2705 COMPQUIET(lr, NULL); 2706 2707 env = dbp->env; 2708 rlsnp = ret_lsnp; 2709 rectype = DB___db_pg_init; 2710 npad = 0; 2711 ret = 0; 2712 2713 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2714 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2715 if (txnp == NULL) 2716 return (0); 2717 is_durable = 0; 2718 } else 2719 is_durable = 1; 2720 2721 if (txnp == NULL) { 2722 txn_num = 0; 2723 lsnp = &null_lsn; 2724 null_lsn.file = null_lsn.offset = 0; 2725 } else { 2726 if (TAILQ_FIRST(&txnp->kids) != NULL && 2727 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2728 return (ret); 2729 /* 2730 * We need to assign begin_lsn while holding region mutex. 2731 * That assignment is done inside the DbEnv->log_put call, 2732 * so pass in the appropriate memory location to be filled 2733 * in by the log_put code. 2734 */ 2735 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2736 txn_num = txnp->txnid; 2737 } 2738 2739 DB_ASSERT(env, dbp->log_filename != NULL); 2740 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2741 (ret = __dbreg_lazy_id(dbp)) != 0) 2742 return (ret); 2743 2744 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2745 + sizeof(u_int32_t) 2746 + sizeof(u_int32_t) 2747 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 2748 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 2749 if (CRYPTO_ON(env)) { 2750 npad = env->crypto_handle->adj_size(logrec.size); 2751 logrec.size += npad; 2752 } 2753 2754 if (is_durable || txnp == NULL) { 2755 if ((ret = 2756 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2757 return (ret); 2758 } else { 2759 if ((ret = __os_malloc(env, 2760 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2761 return (ret); 2762#ifdef DIAGNOSTIC 2763 if ((ret = 2764 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2765 __os_free(env, lr); 2766 return (ret); 2767 } 2768#else 2769 logrec.data = lr->data; 2770#endif 2771 } 2772 if (npad > 0) 2773 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2774 2775 bp = logrec.data; 2776 2777 LOGCOPY_32(env, bp, &rectype); 2778 bp += sizeof(rectype); 2779 2780 LOGCOPY_32(env, bp, &txn_num); 2781 bp += sizeof(txn_num); 2782 2783 LOGCOPY_FROMLSN(env, bp, lsnp); 2784 bp += sizeof(DB_LSN); 2785 2786 uinttmp = (u_int32_t)dbp->log_filename->id; 2787 LOGCOPY_32(env, bp, &uinttmp); 2788 bp += sizeof(uinttmp); 2789 2790 uinttmp = (u_int32_t)pgno; 2791 LOGCOPY_32(env,bp, &uinttmp); 2792 bp += sizeof(uinttmp); 2793 2794 if (header == NULL) { 2795 zero = 0; 2796 LOGCOPY_32(env, bp, &zero); 2797 bp += sizeof(u_int32_t); 2798 } else { 2799 LOGCOPY_32(env, bp, &header->size); 2800 bp += sizeof(header->size); 2801 memcpy(bp, header->data, header->size); 2802 if (LOG_SWAPPED(env)) 2803 if ((ret = __db_pageswap(dbp, 2804 (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) 2805 return (ret); 2806 bp += header->size; 2807 } 2808 2809 if (data == NULL) { 2810 zero = 0; 2811 LOGCOPY_32(env, bp, &zero); 2812 bp += sizeof(u_int32_t); 2813 } else { 2814 LOGCOPY_32(env, bp, &data->size); 2815 bp += sizeof(data->size); 2816 memcpy(bp, data->data, data->size); 2817 if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) 2818 __os_free(env, data->data); 2819 bp += data->size; 2820 } 2821 2822 DB_ASSERT(env, 2823 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2824 2825 if (is_durable || txnp == NULL) { 2826 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2827 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2828 *lsnp = *rlsnp; 2829 if (rlsnp != ret_lsnp) 2830 *ret_lsnp = *rlsnp; 2831 } 2832 } else { 2833 ret = 0; 2834#ifdef DIAGNOSTIC 2835 /* 2836 * Set the debug bit if we are going to log non-durable 2837 * transactions so they will be ignored by recovery. 2838 */ 2839 memcpy(lr->data, logrec.data, logrec.size); 2840 rectype |= DB_debug_FLAG; 2841 LOGCOPY_32(env, logrec.data, &rectype); 2842 2843 if (!IS_REP_CLIENT(env)) 2844 ret = __log_put(env, 2845 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2846#endif 2847 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2848 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2849 LSN_NOT_LOGGED(*ret_lsnp); 2850 } 2851 2852#ifdef LOG_DIAGNOSTIC 2853 if (ret != 0) 2854 (void)__db_pg_init_print(env, 2855 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2856#endif 2857 2858#ifdef DIAGNOSTIC 2859 __os_free(env, logrec.data); 2860#else 2861 if (is_durable || txnp == NULL) 2862 __os_free(env, logrec.data); 2863#endif 2864 return (ret); 2865} 2866 2867/* 2868 * PUBLIC: int __db_pg_sort_read __P((ENV *, DB **, void *, void *, 2869 * PUBLIC: __db_pg_sort_args **)); 2870 */ 2871int 2872__db_pg_sort_read(env, dbpp, td, recbuf, argpp) 2873 ENV *env; 2874 DB **dbpp; 2875 void *td; 2876 void *recbuf; 2877 __db_pg_sort_args **argpp; 2878{ 2879 __db_pg_sort_args *argp; 2880 u_int32_t uinttmp; 2881 u_int8_t *bp; 2882 int ret; 2883 2884 if ((ret = __os_malloc(env, 2885 sizeof(__db_pg_sort_args) + sizeof(DB_TXN), &argp)) != 0) 2886 return (ret); 2887 bp = recbuf; 2888 argp->txnp = (DB_TXN *)&argp[1]; 2889 memset(argp->txnp, 0, sizeof(DB_TXN)); 2890 2891 argp->txnp->td = td; 2892 LOGCOPY_32(env, &argp->type, bp); 2893 bp += sizeof(argp->type); 2894 2895 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2896 bp += sizeof(argp->txnp->txnid); 2897 2898 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2899 bp += sizeof(DB_LSN); 2900 2901 LOGCOPY_32(env, &uinttmp, bp); 2902 argp->fileid = (int32_t)uinttmp; 2903 bp += sizeof(uinttmp); 2904 if (dbpp != NULL) { 2905 *dbpp = NULL; 2906 ret = __dbreg_id_to_db( 2907 env, argp->txnp, dbpp, argp->fileid, 1); 2908 } 2909 2910 LOGCOPY_32(env, &uinttmp, bp); 2911 argp->meta = (db_pgno_t)uinttmp; 2912 bp += sizeof(uinttmp); 2913 2914 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2915 bp += sizeof(DB_LSN); 2916 2917 LOGCOPY_32(env, &uinttmp, bp); 2918 argp->last_free = (db_pgno_t)uinttmp; 2919 bp += sizeof(uinttmp); 2920 2921 LOGCOPY_TOLSN(env, &argp->last_lsn, bp); 2922 bp += sizeof(DB_LSN); 2923 2924 LOGCOPY_32(env, &uinttmp, bp); 2925 argp->last_pgno = (db_pgno_t)uinttmp; 2926 bp += sizeof(uinttmp); 2927 2928 memset(&argp->list, 0, sizeof(argp->list)); 2929 LOGCOPY_32(env,&argp->list.size, bp); 2930 bp += sizeof(u_int32_t); 2931 argp->list.data = bp; 2932 bp += argp->list.size; 2933 2934 *argpp = argp; 2935 return (ret); 2936} 2937 2938/* 2939 * PUBLIC: int __db_pg_sort_log __P((DB *, DB_TXN *, DB_LSN *, 2940 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, 2941 * PUBLIC: const DBT *)); 2942 */ 2943int 2944__db_pg_sort_log(dbp, txnp, ret_lsnp, flags, meta, meta_lsn, last_free, last_lsn, last_pgno, 2945 list) 2946 DB *dbp; 2947 DB_TXN *txnp; 2948 DB_LSN *ret_lsnp; 2949 u_int32_t flags; 2950 db_pgno_t meta; 2951 DB_LSN * meta_lsn; 2952 db_pgno_t last_free; 2953 DB_LSN * last_lsn; 2954 db_pgno_t last_pgno; 2955 const DBT *list; 2956{ 2957 DBT logrec; 2958 DB_LSN *lsnp, null_lsn, *rlsnp; 2959 DB_TXNLOGREC *lr; 2960 ENV *env; 2961 u_int32_t zero, uinttmp, rectype, txn_num; 2962 u_int npad; 2963 u_int8_t *bp; 2964 int is_durable, ret; 2965 2966 COMPQUIET(lr, NULL); 2967 2968 env = dbp->env; 2969 rlsnp = ret_lsnp; 2970 rectype = DB___db_pg_sort; 2971 npad = 0; 2972 ret = 0; 2973 2974 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2975 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2976 if (txnp == NULL) 2977 return (0); 2978 is_durable = 0; 2979 } else 2980 is_durable = 1; 2981 2982 if (txnp == NULL) { 2983 txn_num = 0; 2984 lsnp = &null_lsn; 2985 null_lsn.file = null_lsn.offset = 0; 2986 } else { 2987 if (TAILQ_FIRST(&txnp->kids) != NULL && 2988 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2989 return (ret); 2990 /* 2991 * We need to assign begin_lsn while holding region mutex. 2992 * That assignment is done inside the DbEnv->log_put call, 2993 * so pass in the appropriate memory location to be filled 2994 * in by the log_put code. 2995 */ 2996 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2997 txn_num = txnp->txnid; 2998 } 2999 3000 DB_ASSERT(env, dbp->log_filename != NULL); 3001 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 3002 (ret = __dbreg_lazy_id(dbp)) != 0) 3003 return (ret); 3004 3005 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 3006 + sizeof(u_int32_t) 3007 + sizeof(u_int32_t) 3008 + sizeof(*meta_lsn) 3009 + sizeof(u_int32_t) 3010 + sizeof(*last_lsn) 3011 + sizeof(u_int32_t) 3012 + sizeof(u_int32_t) + (list == NULL ? 0 : list->size); 3013 if (CRYPTO_ON(env)) { 3014 npad = env->crypto_handle->adj_size(logrec.size); 3015 logrec.size += npad; 3016 } 3017 3018 if (is_durable || txnp == NULL) { 3019 if ((ret = 3020 __os_malloc(env, logrec.size, &logrec.data)) != 0) 3021 return (ret); 3022 } else { 3023 if ((ret = __os_malloc(env, 3024 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 3025 return (ret); 3026#ifdef DIAGNOSTIC 3027 if ((ret = 3028 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 3029 __os_free(env, lr); 3030 return (ret); 3031 } 3032#else 3033 logrec.data = lr->data; 3034#endif 3035 } 3036 if (npad > 0) 3037 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 3038 3039 bp = logrec.data; 3040 3041 LOGCOPY_32(env, bp, &rectype); 3042 bp += sizeof(rectype); 3043 3044 LOGCOPY_32(env, bp, &txn_num); 3045 bp += sizeof(txn_num); 3046 3047 LOGCOPY_FROMLSN(env, bp, lsnp); 3048 bp += sizeof(DB_LSN); 3049 3050 uinttmp = (u_int32_t)dbp->log_filename->id; 3051 LOGCOPY_32(env, bp, &uinttmp); 3052 bp += sizeof(uinttmp); 3053 3054 uinttmp = (u_int32_t)meta; 3055 LOGCOPY_32(env,bp, &uinttmp); 3056 bp += sizeof(uinttmp); 3057 3058 if (meta_lsn != NULL) { 3059 if (txnp != NULL) { 3060 LOG *lp = env->lg_handle->reginfo.primary; 3061 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 3062 __log_check_page_lsn(env, dbp, meta_lsn) != 0)) 3063 return (ret); 3064 } 3065 LOGCOPY_FROMLSN(env, bp, meta_lsn); 3066 } else 3067 memset(bp, 0, sizeof(*meta_lsn)); 3068 bp += sizeof(*meta_lsn); 3069 3070 uinttmp = (u_int32_t)last_free; 3071 LOGCOPY_32(env,bp, &uinttmp); 3072 bp += sizeof(uinttmp); 3073 3074 if (last_lsn != NULL) { 3075 if (txnp != NULL) { 3076 LOG *lp = env->lg_handle->reginfo.primary; 3077 if (LOG_COMPARE(last_lsn, &lp->lsn) >= 0 && (ret = 3078 __log_check_page_lsn(env, dbp, last_lsn) != 0)) 3079 return (ret); 3080 } 3081 LOGCOPY_FROMLSN(env, bp, last_lsn); 3082 } else 3083 memset(bp, 0, sizeof(*last_lsn)); 3084 bp += sizeof(*last_lsn); 3085 3086 uinttmp = (u_int32_t)last_pgno; 3087 LOGCOPY_32(env,bp, &uinttmp); 3088 bp += sizeof(uinttmp); 3089 3090 if (list == NULL) { 3091 zero = 0; 3092 LOGCOPY_32(env, bp, &zero); 3093 bp += sizeof(u_int32_t); 3094 } else { 3095 LOGCOPY_32(env, bp, &list->size); 3096 bp += sizeof(list->size); 3097 memcpy(bp, list->data, list->size); 3098 bp += list->size; 3099 } 3100 3101 DB_ASSERT(env, 3102 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 3103 3104 if (is_durable || txnp == NULL) { 3105 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 3106 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 3107 *lsnp = *rlsnp; 3108 if (rlsnp != ret_lsnp) 3109 *ret_lsnp = *rlsnp; 3110 } 3111 } else { 3112 ret = 0; 3113#ifdef DIAGNOSTIC 3114 /* 3115 * Set the debug bit if we are going to log non-durable 3116 * transactions so they will be ignored by recovery. 3117 */ 3118 memcpy(lr->data, logrec.data, logrec.size); 3119 rectype |= DB_debug_FLAG; 3120 LOGCOPY_32(env, logrec.data, &rectype); 3121 3122 if (!IS_REP_CLIENT(env)) 3123 ret = __log_put(env, 3124 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 3125#endif 3126 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 3127 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 3128 LSN_NOT_LOGGED(*ret_lsnp); 3129 } 3130 3131#ifdef LOG_DIAGNOSTIC 3132 if (ret != 0) 3133 (void)__db_pg_sort_print(env, 3134 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 3135#endif 3136 3137#ifdef DIAGNOSTIC 3138 __os_free(env, logrec.data); 3139#else 3140 if (is_durable || txnp == NULL) 3141 __os_free(env, logrec.data); 3142#endif 3143 return (ret); 3144} 3145 3146/* 3147 * PUBLIC: int __db_init_recover __P((ENV *, DB_DISTAB *)); 3148 */ 3149int 3150__db_init_recover(env, dtabp) 3151 ENV *env; 3152 DB_DISTAB *dtabp; 3153{ 3154 int ret; 3155 3156 if ((ret = __db_add_recovery_int(env, dtabp, 3157 __db_addrem_recover, DB___db_addrem)) != 0) 3158 return (ret); 3159 if ((ret = __db_add_recovery_int(env, dtabp, 3160 __db_big_recover, DB___db_big)) != 0) 3161 return (ret); 3162 if ((ret = __db_add_recovery_int(env, dtabp, 3163 __db_ovref_recover, DB___db_ovref)) != 0) 3164 return (ret); 3165 if ((ret = __db_add_recovery_int(env, dtabp, 3166 __db_debug_recover, DB___db_debug)) != 0) 3167 return (ret); 3168 if ((ret = __db_add_recovery_int(env, dtabp, 3169 __db_noop_recover, DB___db_noop)) != 0) 3170 return (ret); 3171 if ((ret = __db_add_recovery_int(env, dtabp, 3172 __db_pg_alloc_recover, DB___db_pg_alloc)) != 0) 3173 return (ret); 3174 if ((ret = __db_add_recovery_int(env, dtabp, 3175 __db_pg_free_recover, DB___db_pg_free)) != 0) 3176 return (ret); 3177 if ((ret = __db_add_recovery_int(env, dtabp, 3178 __db_cksum_recover, DB___db_cksum)) != 0) 3179 return (ret); 3180 if ((ret = __db_add_recovery_int(env, dtabp, 3181 __db_pg_freedata_recover, DB___db_pg_freedata)) != 0) 3182 return (ret); 3183 if ((ret = __db_add_recovery_int(env, dtabp, 3184 __db_pg_init_recover, DB___db_pg_init)) != 0) 3185 return (ret); 3186 if ((ret = __db_add_recovery_int(env, dtabp, 3187 __db_pg_sort_recover, DB___db_pg_sort)) != 0) 3188 return (ret); 3189 return (0); 3190} 3191