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 is_durable = 0; 1001 } else 1002 is_durable = 1; 1003 1004 if (txnp == NULL) { 1005 txn_num = 0; 1006 lsnp = &null_lsn; 1007 null_lsn.file = null_lsn.offset = 0; 1008 } else { 1009 /* 1010 * We need to assign begin_lsn while holding region mutex. 1011 * That assignment is done inside the DbEnv->log_put call, 1012 * so pass in the appropriate memory location to be filled 1013 * in by the log_put code. 1014 */ 1015 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1016 txn_num = txnp->txnid; 1017 } 1018 1019 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1020 + sizeof(u_int32_t) + (op == NULL ? 0 : op->size) 1021 + sizeof(u_int32_t) 1022 + sizeof(u_int32_t) + (key == NULL ? 0 : key->size) 1023 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size) 1024 + sizeof(u_int32_t); 1025 if (CRYPTO_ON(env)) { 1026 npad = env->crypto_handle->adj_size(logrec.size); 1027 logrec.size += npad; 1028 } 1029 1030 if (is_durable || txnp == NULL) { 1031 if ((ret = 1032 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1033 return (ret); 1034 } else { 1035 if ((ret = __os_malloc(env, 1036 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1037 return (ret); 1038#ifdef DIAGNOSTIC 1039 if ((ret = 1040 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1041 __os_free(env, lr); 1042 return (ret); 1043 } 1044#else 1045 logrec.data = lr->data; 1046#endif 1047 } 1048 if (npad > 0) 1049 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1050 1051 bp = logrec.data; 1052 1053 LOGCOPY_32(env, bp, &rectype); 1054 bp += sizeof(rectype); 1055 1056 LOGCOPY_32(env, bp, &txn_num); 1057 bp += sizeof(txn_num); 1058 1059 LOGCOPY_FROMLSN(env, bp, lsnp); 1060 bp += sizeof(DB_LSN); 1061 1062 if (op == NULL) { 1063 zero = 0; 1064 LOGCOPY_32(env, bp, &zero); 1065 bp += sizeof(u_int32_t); 1066 } else { 1067 LOGCOPY_32(env, bp, &op->size); 1068 bp += sizeof(op->size); 1069 memcpy(bp, op->data, op->size); 1070 bp += op->size; 1071 } 1072 1073 uinttmp = (u_int32_t)fileid; 1074 LOGCOPY_32(env,bp, &uinttmp); 1075 bp += sizeof(uinttmp); 1076 1077 if (key == NULL) { 1078 zero = 0; 1079 LOGCOPY_32(env, bp, &zero); 1080 bp += sizeof(u_int32_t); 1081 } else { 1082 LOGCOPY_32(env, bp, &key->size); 1083 bp += sizeof(key->size); 1084 memcpy(bp, key->data, key->size); 1085 bp += key->size; 1086 } 1087 1088 if (data == NULL) { 1089 zero = 0; 1090 LOGCOPY_32(env, bp, &zero); 1091 bp += sizeof(u_int32_t); 1092 } else { 1093 LOGCOPY_32(env, bp, &data->size); 1094 bp += sizeof(data->size); 1095 memcpy(bp, data->data, data->size); 1096 bp += data->size; 1097 } 1098 1099 LOGCOPY_32(env, bp, &arg_flags); 1100 bp += sizeof(arg_flags); 1101 1102 DB_ASSERT(env, 1103 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1104 1105 if (is_durable || txnp == NULL) { 1106 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1107 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1108 *lsnp = *rlsnp; 1109 if (rlsnp != ret_lsnp) 1110 *ret_lsnp = *rlsnp; 1111 } 1112 } else { 1113 ret = 0; 1114#ifdef DIAGNOSTIC 1115 /* 1116 * Set the debug bit if we are going to log non-durable 1117 * transactions so they will be ignored by recovery. 1118 */ 1119 memcpy(lr->data, logrec.data, logrec.size); 1120 rectype |= DB_debug_FLAG; 1121 LOGCOPY_32(env, logrec.data, &rectype); 1122 1123 if (!IS_REP_CLIENT(env)) 1124 ret = __log_put(env, 1125 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1126#endif 1127 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1128 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1129 LSN_NOT_LOGGED(*ret_lsnp); 1130 } 1131 1132#ifdef LOG_DIAGNOSTIC 1133 if (ret != 0) 1134 (void)__db_debug_print(env, 1135 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1136#endif 1137 1138#ifdef DIAGNOSTIC 1139 __os_free(env, logrec.data); 1140#else 1141 if (is_durable || txnp == NULL) 1142 __os_free(env, logrec.data); 1143#endif 1144 return (ret); 1145} 1146 1147/* 1148 * PUBLIC: int __db_noop_read __P((ENV *, DB **, void *, void *, 1149 * PUBLIC: __db_noop_args **)); 1150 */ 1151int 1152__db_noop_read(env, dbpp, td, recbuf, argpp) 1153 ENV *env; 1154 DB **dbpp; 1155 void *td; 1156 void *recbuf; 1157 __db_noop_args **argpp; 1158{ 1159 __db_noop_args *argp; 1160 u_int32_t uinttmp; 1161 u_int8_t *bp; 1162 int ret; 1163 1164 if ((ret = __os_malloc(env, 1165 sizeof(__db_noop_args) + sizeof(DB_TXN), &argp)) != 0) 1166 return (ret); 1167 bp = recbuf; 1168 argp->txnp = (DB_TXN *)&argp[1]; 1169 memset(argp->txnp, 0, sizeof(DB_TXN)); 1170 1171 argp->txnp->td = td; 1172 LOGCOPY_32(env, &argp->type, bp); 1173 bp += sizeof(argp->type); 1174 1175 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1176 bp += sizeof(argp->txnp->txnid); 1177 1178 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1179 bp += sizeof(DB_LSN); 1180 1181 LOGCOPY_32(env, &uinttmp, bp); 1182 argp->fileid = (int32_t)uinttmp; 1183 bp += sizeof(uinttmp); 1184 if (dbpp != NULL) { 1185 *dbpp = NULL; 1186 ret = __dbreg_id_to_db( 1187 env, argp->txnp, dbpp, argp->fileid, 1); 1188 } 1189 1190 LOGCOPY_32(env, &uinttmp, bp); 1191 argp->pgno = (db_pgno_t)uinttmp; 1192 bp += sizeof(uinttmp); 1193 1194 LOGCOPY_TOLSN(env, &argp->prevlsn, bp); 1195 bp += sizeof(DB_LSN); 1196 1197 *argpp = argp; 1198 return (ret); 1199} 1200 1201/* 1202 * PUBLIC: int __db_noop_log __P((DB *, DB_TXN *, DB_LSN *, 1203 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *)); 1204 */ 1205int 1206__db_noop_log(dbp, txnp, ret_lsnp, flags, pgno, prevlsn) 1207 DB *dbp; 1208 DB_TXN *txnp; 1209 DB_LSN *ret_lsnp; 1210 u_int32_t flags; 1211 db_pgno_t pgno; 1212 DB_LSN * prevlsn; 1213{ 1214 DBT logrec; 1215 DB_LSN *lsnp, null_lsn, *rlsnp; 1216 DB_TXNLOGREC *lr; 1217 ENV *env; 1218 u_int32_t uinttmp, rectype, txn_num; 1219 u_int npad; 1220 u_int8_t *bp; 1221 int is_durable, ret; 1222 1223 COMPQUIET(lr, NULL); 1224 1225 env = dbp->env; 1226 rlsnp = ret_lsnp; 1227 rectype = DB___db_noop; 1228 npad = 0; 1229 ret = 0; 1230 1231 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1232 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1233 if (txnp == NULL) 1234 return (0); 1235 is_durable = 0; 1236 } else 1237 is_durable = 1; 1238 1239 if (txnp == NULL) { 1240 txn_num = 0; 1241 lsnp = &null_lsn; 1242 null_lsn.file = null_lsn.offset = 0; 1243 } else { 1244 if (TAILQ_FIRST(&txnp->kids) != NULL && 1245 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1246 return (ret); 1247 /* 1248 * We need to assign begin_lsn while holding region mutex. 1249 * That assignment is done inside the DbEnv->log_put call, 1250 * so pass in the appropriate memory location to be filled 1251 * in by the log_put code. 1252 */ 1253 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1254 txn_num = txnp->txnid; 1255 } 1256 1257 DB_ASSERT(env, dbp->log_filename != NULL); 1258 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1259 (ret = __dbreg_lazy_id(dbp)) != 0) 1260 return (ret); 1261 1262 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1263 + sizeof(u_int32_t) 1264 + sizeof(u_int32_t) 1265 + sizeof(*prevlsn); 1266 if (CRYPTO_ON(env)) { 1267 npad = env->crypto_handle->adj_size(logrec.size); 1268 logrec.size += npad; 1269 } 1270 1271 if (is_durable || txnp == NULL) { 1272 if ((ret = 1273 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1274 return (ret); 1275 } else { 1276 if ((ret = __os_malloc(env, 1277 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1278 return (ret); 1279#ifdef DIAGNOSTIC 1280 if ((ret = 1281 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1282 __os_free(env, lr); 1283 return (ret); 1284 } 1285#else 1286 logrec.data = lr->data; 1287#endif 1288 } 1289 if (npad > 0) 1290 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1291 1292 bp = logrec.data; 1293 1294 LOGCOPY_32(env, bp, &rectype); 1295 bp += sizeof(rectype); 1296 1297 LOGCOPY_32(env, bp, &txn_num); 1298 bp += sizeof(txn_num); 1299 1300 LOGCOPY_FROMLSN(env, bp, lsnp); 1301 bp += sizeof(DB_LSN); 1302 1303 uinttmp = (u_int32_t)dbp->log_filename->id; 1304 LOGCOPY_32(env, bp, &uinttmp); 1305 bp += sizeof(uinttmp); 1306 1307 uinttmp = (u_int32_t)pgno; 1308 LOGCOPY_32(env,bp, &uinttmp); 1309 bp += sizeof(uinttmp); 1310 1311 if (prevlsn != NULL) { 1312 if (txnp != NULL) { 1313 LOG *lp = env->lg_handle->reginfo.primary; 1314 if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = 1315 __log_check_page_lsn(env, dbp, prevlsn)) != 0) 1316 return (ret); 1317 } 1318 LOGCOPY_FROMLSN(env, bp, prevlsn); 1319 } else 1320 memset(bp, 0, sizeof(*prevlsn)); 1321 bp += sizeof(*prevlsn); 1322 1323 DB_ASSERT(env, 1324 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1325 1326 if (is_durable || txnp == NULL) { 1327 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1328 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1329 *lsnp = *rlsnp; 1330 if (rlsnp != ret_lsnp) 1331 *ret_lsnp = *rlsnp; 1332 } 1333 } else { 1334 ret = 0; 1335#ifdef DIAGNOSTIC 1336 /* 1337 * Set the debug bit if we are going to log non-durable 1338 * transactions so they will be ignored by recovery. 1339 */ 1340 memcpy(lr->data, logrec.data, logrec.size); 1341 rectype |= DB_debug_FLAG; 1342 LOGCOPY_32(env, logrec.data, &rectype); 1343 1344 if (!IS_REP_CLIENT(env)) 1345 ret = __log_put(env, 1346 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1347#endif 1348 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1349 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1350 LSN_NOT_LOGGED(*ret_lsnp); 1351 } 1352 1353#ifdef LOG_DIAGNOSTIC 1354 if (ret != 0) 1355 (void)__db_noop_print(env, 1356 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1357#endif 1358 1359#ifdef DIAGNOSTIC 1360 __os_free(env, logrec.data); 1361#else 1362 if (is_durable || txnp == NULL) 1363 __os_free(env, logrec.data); 1364#endif 1365 return (ret); 1366} 1367 1368/* 1369 * PUBLIC: int __db_pg_alloc_42_read __P((ENV *, DB **, void *, 1370 * PUBLIC: void *, __db_pg_alloc_42_args **)); 1371 */ 1372int 1373__db_pg_alloc_42_read(env, dbpp, td, recbuf, argpp) 1374 ENV *env; 1375 DB **dbpp; 1376 void *td; 1377 void *recbuf; 1378 __db_pg_alloc_42_args **argpp; 1379{ 1380 __db_pg_alloc_42_args *argp; 1381 u_int32_t uinttmp; 1382 u_int8_t *bp; 1383 int ret; 1384 1385 if ((ret = __os_malloc(env, 1386 sizeof(__db_pg_alloc_42_args) + sizeof(DB_TXN), &argp)) != 0) 1387 return (ret); 1388 bp = recbuf; 1389 argp->txnp = (DB_TXN *)&argp[1]; 1390 memset(argp->txnp, 0, sizeof(DB_TXN)); 1391 1392 argp->txnp->td = td; 1393 LOGCOPY_32(env, &argp->type, bp); 1394 bp += sizeof(argp->type); 1395 1396 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1397 bp += sizeof(argp->txnp->txnid); 1398 1399 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1400 bp += sizeof(DB_LSN); 1401 1402 LOGCOPY_32(env, &uinttmp, bp); 1403 argp->fileid = (int32_t)uinttmp; 1404 bp += sizeof(uinttmp); 1405 if (dbpp != NULL) { 1406 *dbpp = NULL; 1407 ret = __dbreg_id_to_db( 1408 env, argp->txnp, dbpp, argp->fileid, 1); 1409 } 1410 1411 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1412 bp += sizeof(DB_LSN); 1413 1414 LOGCOPY_32(env, &uinttmp, bp); 1415 argp->meta_pgno = (db_pgno_t)uinttmp; 1416 bp += sizeof(uinttmp); 1417 1418 LOGCOPY_TOLSN(env, &argp->page_lsn, bp); 1419 bp += sizeof(DB_LSN); 1420 1421 LOGCOPY_32(env, &uinttmp, bp); 1422 argp->pgno = (db_pgno_t)uinttmp; 1423 bp += sizeof(uinttmp); 1424 1425 LOGCOPY_32(env, &argp->ptype, bp); 1426 bp += sizeof(argp->ptype); 1427 1428 LOGCOPY_32(env, &uinttmp, bp); 1429 argp->next = (db_pgno_t)uinttmp; 1430 bp += sizeof(uinttmp); 1431 1432 *argpp = argp; 1433 return (ret); 1434} 1435 1436/* 1437 * PUBLIC: int __db_pg_alloc_read __P((ENV *, DB **, void *, void *, 1438 * PUBLIC: __db_pg_alloc_args **)); 1439 */ 1440int 1441__db_pg_alloc_read(env, dbpp, td, recbuf, argpp) 1442 ENV *env; 1443 DB **dbpp; 1444 void *td; 1445 void *recbuf; 1446 __db_pg_alloc_args **argpp; 1447{ 1448 __db_pg_alloc_args *argp; 1449 u_int32_t uinttmp; 1450 u_int8_t *bp; 1451 int ret; 1452 1453 if ((ret = __os_malloc(env, 1454 sizeof(__db_pg_alloc_args) + sizeof(DB_TXN), &argp)) != 0) 1455 return (ret); 1456 bp = recbuf; 1457 argp->txnp = (DB_TXN *)&argp[1]; 1458 memset(argp->txnp, 0, sizeof(DB_TXN)); 1459 1460 argp->txnp->td = td; 1461 LOGCOPY_32(env, &argp->type, bp); 1462 bp += sizeof(argp->type); 1463 1464 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1465 bp += sizeof(argp->txnp->txnid); 1466 1467 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1468 bp += sizeof(DB_LSN); 1469 1470 LOGCOPY_32(env, &uinttmp, bp); 1471 argp->fileid = (int32_t)uinttmp; 1472 bp += sizeof(uinttmp); 1473 if (dbpp != NULL) { 1474 *dbpp = NULL; 1475 ret = __dbreg_id_to_db( 1476 env, argp->txnp, dbpp, argp->fileid, 1); 1477 } 1478 1479 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1480 bp += sizeof(DB_LSN); 1481 1482 LOGCOPY_32(env, &uinttmp, bp); 1483 argp->meta_pgno = (db_pgno_t)uinttmp; 1484 bp += sizeof(uinttmp); 1485 1486 LOGCOPY_TOLSN(env, &argp->page_lsn, bp); 1487 bp += sizeof(DB_LSN); 1488 1489 LOGCOPY_32(env, &uinttmp, bp); 1490 argp->pgno = (db_pgno_t)uinttmp; 1491 bp += sizeof(uinttmp); 1492 1493 LOGCOPY_32(env, &argp->ptype, bp); 1494 bp += sizeof(argp->ptype); 1495 1496 LOGCOPY_32(env, &uinttmp, bp); 1497 argp->next = (db_pgno_t)uinttmp; 1498 bp += sizeof(uinttmp); 1499 1500 LOGCOPY_32(env, &uinttmp, bp); 1501 argp->last_pgno = (db_pgno_t)uinttmp; 1502 bp += sizeof(uinttmp); 1503 1504 *argpp = argp; 1505 return (ret); 1506} 1507 1508/* 1509 * PUBLIC: int __db_pg_alloc_log __P((DB *, DB_TXN *, DB_LSN *, 1510 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, u_int32_t, 1511 * PUBLIC: db_pgno_t, db_pgno_t)); 1512 */ 1513int 1514__db_pg_alloc_log(dbp, txnp, ret_lsnp, flags, meta_lsn, meta_pgno, page_lsn, pgno, ptype, 1515 next, last_pgno) 1516 DB *dbp; 1517 DB_TXN *txnp; 1518 DB_LSN *ret_lsnp; 1519 u_int32_t flags; 1520 DB_LSN * meta_lsn; 1521 db_pgno_t meta_pgno; 1522 DB_LSN * page_lsn; 1523 db_pgno_t pgno; 1524 u_int32_t ptype; 1525 db_pgno_t next; 1526 db_pgno_t last_pgno; 1527{ 1528 DBT logrec; 1529 DB_LSN *lsnp, null_lsn, *rlsnp; 1530 DB_TXNLOGREC *lr; 1531 ENV *env; 1532 u_int32_t uinttmp, rectype, txn_num; 1533 u_int npad; 1534 u_int8_t *bp; 1535 int is_durable, ret; 1536 1537 COMPQUIET(lr, NULL); 1538 1539 env = dbp->env; 1540 rlsnp = ret_lsnp; 1541 rectype = DB___db_pg_alloc; 1542 npad = 0; 1543 ret = 0; 1544 1545 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1546 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1547 if (txnp == NULL) 1548 return (0); 1549 is_durable = 0; 1550 } else 1551 is_durable = 1; 1552 1553 if (txnp == NULL) { 1554 txn_num = 0; 1555 lsnp = &null_lsn; 1556 null_lsn.file = null_lsn.offset = 0; 1557 } else { 1558 if (TAILQ_FIRST(&txnp->kids) != NULL && 1559 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1560 return (ret); 1561 /* 1562 * We need to assign begin_lsn while holding region mutex. 1563 * That assignment is done inside the DbEnv->log_put call, 1564 * so pass in the appropriate memory location to be filled 1565 * in by the log_put code. 1566 */ 1567 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1568 txn_num = txnp->txnid; 1569 } 1570 1571 DB_ASSERT(env, dbp->log_filename != NULL); 1572 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1573 (ret = __dbreg_lazy_id(dbp)) != 0) 1574 return (ret); 1575 1576 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1577 + sizeof(u_int32_t) 1578 + sizeof(*meta_lsn) 1579 + sizeof(u_int32_t) 1580 + sizeof(*page_lsn) 1581 + sizeof(u_int32_t) 1582 + sizeof(u_int32_t) 1583 + sizeof(u_int32_t) 1584 + sizeof(u_int32_t); 1585 if (CRYPTO_ON(env)) { 1586 npad = env->crypto_handle->adj_size(logrec.size); 1587 logrec.size += npad; 1588 } 1589 1590 if (is_durable || txnp == NULL) { 1591 if ((ret = 1592 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1593 return (ret); 1594 } else { 1595 if ((ret = __os_malloc(env, 1596 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1597 return (ret); 1598#ifdef DIAGNOSTIC 1599 if ((ret = 1600 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1601 __os_free(env, lr); 1602 return (ret); 1603 } 1604#else 1605 logrec.data = lr->data; 1606#endif 1607 } 1608 if (npad > 0) 1609 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1610 1611 bp = logrec.data; 1612 1613 LOGCOPY_32(env, bp, &rectype); 1614 bp += sizeof(rectype); 1615 1616 LOGCOPY_32(env, bp, &txn_num); 1617 bp += sizeof(txn_num); 1618 1619 LOGCOPY_FROMLSN(env, bp, lsnp); 1620 bp += sizeof(DB_LSN); 1621 1622 uinttmp = (u_int32_t)dbp->log_filename->id; 1623 LOGCOPY_32(env, bp, &uinttmp); 1624 bp += sizeof(uinttmp); 1625 1626 if (meta_lsn != NULL) { 1627 if (txnp != NULL) { 1628 LOG *lp = env->lg_handle->reginfo.primary; 1629 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 1630 __log_check_page_lsn(env, dbp, meta_lsn)) != 0) 1631 return (ret); 1632 } 1633 LOGCOPY_FROMLSN(env, bp, meta_lsn); 1634 } else 1635 memset(bp, 0, sizeof(*meta_lsn)); 1636 bp += sizeof(*meta_lsn); 1637 1638 uinttmp = (u_int32_t)meta_pgno; 1639 LOGCOPY_32(env,bp, &uinttmp); 1640 bp += sizeof(uinttmp); 1641 1642 if (page_lsn != NULL) { 1643 if (txnp != NULL) { 1644 LOG *lp = env->lg_handle->reginfo.primary; 1645 if (LOG_COMPARE(page_lsn, &lp->lsn) >= 0 && (ret = 1646 __log_check_page_lsn(env, dbp, page_lsn)) != 0) 1647 return (ret); 1648 } 1649 LOGCOPY_FROMLSN(env, bp, page_lsn); 1650 } else 1651 memset(bp, 0, sizeof(*page_lsn)); 1652 bp += sizeof(*page_lsn); 1653 1654 uinttmp = (u_int32_t)pgno; 1655 LOGCOPY_32(env,bp, &uinttmp); 1656 bp += sizeof(uinttmp); 1657 1658 LOGCOPY_32(env, bp, &ptype); 1659 bp += sizeof(ptype); 1660 1661 uinttmp = (u_int32_t)next; 1662 LOGCOPY_32(env,bp, &uinttmp); 1663 bp += sizeof(uinttmp); 1664 1665 uinttmp = (u_int32_t)last_pgno; 1666 LOGCOPY_32(env,bp, &uinttmp); 1667 bp += sizeof(uinttmp); 1668 1669 DB_ASSERT(env, 1670 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1671 1672 if (is_durable || txnp == NULL) { 1673 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1674 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1675 *lsnp = *rlsnp; 1676 if (rlsnp != ret_lsnp) 1677 *ret_lsnp = *rlsnp; 1678 } 1679 } else { 1680 ret = 0; 1681#ifdef DIAGNOSTIC 1682 /* 1683 * Set the debug bit if we are going to log non-durable 1684 * transactions so they will be ignored by recovery. 1685 */ 1686 memcpy(lr->data, logrec.data, logrec.size); 1687 rectype |= DB_debug_FLAG; 1688 LOGCOPY_32(env, logrec.data, &rectype); 1689 1690 if (!IS_REP_CLIENT(env)) 1691 ret = __log_put(env, 1692 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1693#endif 1694 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1695 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1696 LSN_NOT_LOGGED(*ret_lsnp); 1697 } 1698 1699#ifdef LOG_DIAGNOSTIC 1700 if (ret != 0) 1701 (void)__db_pg_alloc_print(env, 1702 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1703#endif 1704 1705#ifdef DIAGNOSTIC 1706 __os_free(env, logrec.data); 1707#else 1708 if (is_durable || txnp == NULL) 1709 __os_free(env, logrec.data); 1710#endif 1711 return (ret); 1712} 1713 1714/* 1715 * PUBLIC: int __db_pg_free_42_read __P((ENV *, DB **, void *, 1716 * PUBLIC: void *, __db_pg_free_42_args **)); 1717 */ 1718int 1719__db_pg_free_42_read(env, dbpp, td, recbuf, argpp) 1720 ENV *env; 1721 DB **dbpp; 1722 void *td; 1723 void *recbuf; 1724 __db_pg_free_42_args **argpp; 1725{ 1726 __db_pg_free_42_args *argp; 1727 u_int32_t uinttmp; 1728 u_int8_t *bp; 1729 int ret; 1730 1731 if ((ret = __os_malloc(env, 1732 sizeof(__db_pg_free_42_args) + sizeof(DB_TXN), &argp)) != 0) 1733 return (ret); 1734 bp = recbuf; 1735 argp->txnp = (DB_TXN *)&argp[1]; 1736 memset(argp->txnp, 0, sizeof(DB_TXN)); 1737 1738 argp->txnp->td = td; 1739 LOGCOPY_32(env, &argp->type, bp); 1740 bp += sizeof(argp->type); 1741 1742 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1743 bp += sizeof(argp->txnp->txnid); 1744 1745 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1746 bp += sizeof(DB_LSN); 1747 1748 LOGCOPY_32(env, &uinttmp, bp); 1749 argp->fileid = (int32_t)uinttmp; 1750 bp += sizeof(uinttmp); 1751 if (dbpp != NULL) { 1752 *dbpp = NULL; 1753 ret = __dbreg_id_to_db( 1754 env, argp->txnp, dbpp, argp->fileid, 1); 1755 } 1756 1757 LOGCOPY_32(env, &uinttmp, bp); 1758 argp->pgno = (db_pgno_t)uinttmp; 1759 bp += sizeof(uinttmp); 1760 1761 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1762 bp += sizeof(DB_LSN); 1763 1764 LOGCOPY_32(env, &uinttmp, bp); 1765 argp->meta_pgno = (db_pgno_t)uinttmp; 1766 bp += sizeof(uinttmp); 1767 1768 memset(&argp->header, 0, sizeof(argp->header)); 1769 LOGCOPY_32(env,&argp->header.size, bp); 1770 bp += sizeof(u_int32_t); 1771 argp->header.data = bp; 1772 bp += argp->header.size; 1773 1774 LOGCOPY_32(env, &uinttmp, bp); 1775 argp->next = (db_pgno_t)uinttmp; 1776 bp += sizeof(uinttmp); 1777 1778 *argpp = argp; 1779 return (ret); 1780} 1781 1782/* 1783 * PUBLIC: int __db_pg_free_read __P((ENV *, DB **, void *, void *, 1784 * PUBLIC: __db_pg_free_args **)); 1785 */ 1786int 1787__db_pg_free_read(env, dbpp, td, recbuf, argpp) 1788 ENV *env; 1789 DB **dbpp; 1790 void *td; 1791 void *recbuf; 1792 __db_pg_free_args **argpp; 1793{ 1794 __db_pg_free_args *argp; 1795 u_int32_t uinttmp; 1796 u_int8_t *bp; 1797 int ret; 1798 1799 if ((ret = __os_malloc(env, 1800 sizeof(__db_pg_free_args) + sizeof(DB_TXN), &argp)) != 0) 1801 return (ret); 1802 bp = recbuf; 1803 argp->txnp = (DB_TXN *)&argp[1]; 1804 memset(argp->txnp, 0, sizeof(DB_TXN)); 1805 1806 argp->txnp->td = td; 1807 LOGCOPY_32(env, &argp->type, bp); 1808 bp += sizeof(argp->type); 1809 1810 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1811 bp += sizeof(argp->txnp->txnid); 1812 1813 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1814 bp += sizeof(DB_LSN); 1815 1816 LOGCOPY_32(env, &uinttmp, bp); 1817 argp->fileid = (int32_t)uinttmp; 1818 bp += sizeof(uinttmp); 1819 if (dbpp != NULL) { 1820 *dbpp = NULL; 1821 ret = __dbreg_id_to_db( 1822 env, argp->txnp, dbpp, argp->fileid, 1); 1823 } 1824 1825 LOGCOPY_32(env, &uinttmp, bp); 1826 argp->pgno = (db_pgno_t)uinttmp; 1827 bp += sizeof(uinttmp); 1828 1829 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1830 bp += sizeof(DB_LSN); 1831 1832 LOGCOPY_32(env, &uinttmp, bp); 1833 argp->meta_pgno = (db_pgno_t)uinttmp; 1834 bp += sizeof(uinttmp); 1835 1836 memset(&argp->header, 0, sizeof(argp->header)); 1837 LOGCOPY_32(env,&argp->header.size, bp); 1838 bp += sizeof(u_int32_t); 1839 argp->header.data = bp; 1840 bp += argp->header.size; 1841 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 1842 int t_ret; 1843 if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->header.data, 1844 (size_t)argp->header.size, NULL, 1)) != 0) 1845 return (t_ret); 1846 } 1847 1848 LOGCOPY_32(env, &uinttmp, bp); 1849 argp->next = (db_pgno_t)uinttmp; 1850 bp += sizeof(uinttmp); 1851 1852 LOGCOPY_32(env, &uinttmp, bp); 1853 argp->last_pgno = (db_pgno_t)uinttmp; 1854 bp += sizeof(uinttmp); 1855 1856 *argpp = argp; 1857 return (ret); 1858} 1859 1860/* 1861 * PUBLIC: int __db_pg_free_log __P((DB *, DB_TXN *, DB_LSN *, 1862 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, 1863 * PUBLIC: db_pgno_t, db_pgno_t)); 1864 */ 1865int 1866__db_pg_free_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, 1867 last_pgno) 1868 DB *dbp; 1869 DB_TXN *txnp; 1870 DB_LSN *ret_lsnp; 1871 u_int32_t flags; 1872 db_pgno_t pgno; 1873 DB_LSN * meta_lsn; 1874 db_pgno_t meta_pgno; 1875 const DBT *header; 1876 db_pgno_t next; 1877 db_pgno_t last_pgno; 1878{ 1879 DBT logrec; 1880 DB_LSN *lsnp, null_lsn, *rlsnp; 1881 DB_TXNLOGREC *lr; 1882 ENV *env; 1883 u_int32_t zero, uinttmp, rectype, txn_num; 1884 u_int npad; 1885 u_int8_t *bp; 1886 int is_durable, ret; 1887 1888 COMPQUIET(lr, NULL); 1889 1890 env = dbp->env; 1891 rlsnp = ret_lsnp; 1892 rectype = DB___db_pg_free; 1893 npad = 0; 1894 ret = 0; 1895 1896 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1897 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1898 if (txnp == NULL) 1899 return (0); 1900 is_durable = 0; 1901 } else 1902 is_durable = 1; 1903 1904 if (txnp == NULL) { 1905 txn_num = 0; 1906 lsnp = &null_lsn; 1907 null_lsn.file = null_lsn.offset = 0; 1908 } else { 1909 if (TAILQ_FIRST(&txnp->kids) != NULL && 1910 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1911 return (ret); 1912 /* 1913 * We need to assign begin_lsn while holding region mutex. 1914 * That assignment is done inside the DbEnv->log_put call, 1915 * so pass in the appropriate memory location to be filled 1916 * in by the log_put code. 1917 */ 1918 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1919 txn_num = txnp->txnid; 1920 } 1921 1922 DB_ASSERT(env, dbp->log_filename != NULL); 1923 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1924 (ret = __dbreg_lazy_id(dbp)) != 0) 1925 return (ret); 1926 1927 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1928 + sizeof(u_int32_t) 1929 + sizeof(u_int32_t) 1930 + sizeof(*meta_lsn) 1931 + sizeof(u_int32_t) 1932 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 1933 + sizeof(u_int32_t) 1934 + sizeof(u_int32_t); 1935 if (CRYPTO_ON(env)) { 1936 npad = env->crypto_handle->adj_size(logrec.size); 1937 logrec.size += npad; 1938 } 1939 1940 if (is_durable || txnp == NULL) { 1941 if ((ret = 1942 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1943 return (ret); 1944 } else { 1945 if ((ret = __os_malloc(env, 1946 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1947 return (ret); 1948#ifdef DIAGNOSTIC 1949 if ((ret = 1950 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1951 __os_free(env, lr); 1952 return (ret); 1953 } 1954#else 1955 logrec.data = lr->data; 1956#endif 1957 } 1958 if (npad > 0) 1959 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1960 1961 bp = logrec.data; 1962 1963 LOGCOPY_32(env, bp, &rectype); 1964 bp += sizeof(rectype); 1965 1966 LOGCOPY_32(env, bp, &txn_num); 1967 bp += sizeof(txn_num); 1968 1969 LOGCOPY_FROMLSN(env, bp, lsnp); 1970 bp += sizeof(DB_LSN); 1971 1972 uinttmp = (u_int32_t)dbp->log_filename->id; 1973 LOGCOPY_32(env, bp, &uinttmp); 1974 bp += sizeof(uinttmp); 1975 1976 uinttmp = (u_int32_t)pgno; 1977 LOGCOPY_32(env,bp, &uinttmp); 1978 bp += sizeof(uinttmp); 1979 1980 if (meta_lsn != NULL) { 1981 if (txnp != NULL) { 1982 LOG *lp = env->lg_handle->reginfo.primary; 1983 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 1984 __log_check_page_lsn(env, dbp, meta_lsn)) != 0) 1985 return (ret); 1986 } 1987 LOGCOPY_FROMLSN(env, bp, meta_lsn); 1988 } else 1989 memset(bp, 0, sizeof(*meta_lsn)); 1990 bp += sizeof(*meta_lsn); 1991 1992 uinttmp = (u_int32_t)meta_pgno; 1993 LOGCOPY_32(env,bp, &uinttmp); 1994 bp += sizeof(uinttmp); 1995 1996 if (header == NULL) { 1997 zero = 0; 1998 LOGCOPY_32(env, bp, &zero); 1999 bp += sizeof(u_int32_t); 2000 } else { 2001 LOGCOPY_32(env, bp, &header->size); 2002 bp += sizeof(header->size); 2003 memcpy(bp, header->data, header->size); 2004 if (LOG_SWAPPED(env)) 2005 if ((ret = __db_pageswap(dbp, 2006 (PAGE *)bp, (size_t)header->size, (DBT *)NULL, 0)) != 0) 2007 return (ret); 2008 bp += header->size; 2009 } 2010 2011 uinttmp = (u_int32_t)next; 2012 LOGCOPY_32(env,bp, &uinttmp); 2013 bp += sizeof(uinttmp); 2014 2015 uinttmp = (u_int32_t)last_pgno; 2016 LOGCOPY_32(env,bp, &uinttmp); 2017 bp += sizeof(uinttmp); 2018 2019 DB_ASSERT(env, 2020 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2021 2022 if (is_durable || txnp == NULL) { 2023 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2024 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2025 *lsnp = *rlsnp; 2026 if (rlsnp != ret_lsnp) 2027 *ret_lsnp = *rlsnp; 2028 } 2029 } else { 2030 ret = 0; 2031#ifdef DIAGNOSTIC 2032 /* 2033 * Set the debug bit if we are going to log non-durable 2034 * transactions so they will be ignored by recovery. 2035 */ 2036 memcpy(lr->data, logrec.data, logrec.size); 2037 rectype |= DB_debug_FLAG; 2038 LOGCOPY_32(env, logrec.data, &rectype); 2039 2040 if (!IS_REP_CLIENT(env)) 2041 ret = __log_put(env, 2042 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2043#endif 2044 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2045 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2046 LSN_NOT_LOGGED(*ret_lsnp); 2047 } 2048 2049#ifdef LOG_DIAGNOSTIC 2050 if (ret != 0) 2051 (void)__db_pg_free_print(env, 2052 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2053#endif 2054 2055#ifdef DIAGNOSTIC 2056 __os_free(env, logrec.data); 2057#else 2058 if (is_durable || txnp == NULL) 2059 __os_free(env, logrec.data); 2060#endif 2061 return (ret); 2062} 2063 2064/* 2065 * PUBLIC: int __db_cksum_read __P((ENV *, void *, __db_cksum_args **)); 2066 */ 2067int 2068__db_cksum_read(env, recbuf, argpp) 2069 ENV *env; 2070 void *recbuf; 2071 __db_cksum_args **argpp; 2072{ 2073 __db_cksum_args *argp; 2074 u_int8_t *bp; 2075 int ret; 2076 2077 if ((ret = __os_malloc(env, 2078 sizeof(__db_cksum_args) + sizeof(DB_TXN), &argp)) != 0) 2079 return (ret); 2080 bp = recbuf; 2081 argp->txnp = (DB_TXN *)&argp[1]; 2082 memset(argp->txnp, 0, sizeof(DB_TXN)); 2083 2084 LOGCOPY_32(env, &argp->type, bp); 2085 bp += sizeof(argp->type); 2086 2087 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2088 bp += sizeof(argp->txnp->txnid); 2089 2090 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2091 bp += sizeof(DB_LSN); 2092 2093 *argpp = argp; 2094 return (ret); 2095} 2096 2097/* 2098 * PUBLIC: int __db_cksum_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t)); 2099 */ 2100int 2101__db_cksum_log(env, txnp, ret_lsnp, flags) 2102 ENV *env; 2103 DB_TXN *txnp; 2104 DB_LSN *ret_lsnp; 2105 u_int32_t flags; 2106{ 2107 DBT logrec; 2108 DB_LSN *lsnp, null_lsn, *rlsnp; 2109 DB_TXNLOGREC *lr; 2110 u_int32_t rectype, txn_num; 2111 u_int npad; 2112 u_int8_t *bp; 2113 int is_durable, ret; 2114 2115 COMPQUIET(lr, NULL); 2116 2117 rlsnp = ret_lsnp; 2118 rectype = DB___db_cksum; 2119 npad = 0; 2120 ret = 0; 2121 2122 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 2123 if (txnp == NULL) 2124 return (0); 2125 is_durable = 0; 2126 } else 2127 is_durable = 1; 2128 2129 if (txnp == NULL) { 2130 txn_num = 0; 2131 lsnp = &null_lsn; 2132 null_lsn.file = null_lsn.offset = 0; 2133 } else { 2134 if (TAILQ_FIRST(&txnp->kids) != NULL && 2135 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2136 return (ret); 2137 /* 2138 * We need to assign begin_lsn while holding region mutex. 2139 * That assignment is done inside the DbEnv->log_put call, 2140 * so pass in the appropriate memory location to be filled 2141 * in by the log_put code. 2142 */ 2143 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2144 txn_num = txnp->txnid; 2145 } 2146 2147 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN); 2148 if (CRYPTO_ON(env)) { 2149 npad = env->crypto_handle->adj_size(logrec.size); 2150 logrec.size += npad; 2151 } 2152 2153 if (is_durable || txnp == NULL) { 2154 if ((ret = 2155 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2156 return (ret); 2157 } else { 2158 if ((ret = __os_malloc(env, 2159 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2160 return (ret); 2161#ifdef DIAGNOSTIC 2162 if ((ret = 2163 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2164 __os_free(env, lr); 2165 return (ret); 2166 } 2167#else 2168 logrec.data = lr->data; 2169#endif 2170 } 2171 if (npad > 0) 2172 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2173 2174 bp = logrec.data; 2175 2176 LOGCOPY_32(env, bp, &rectype); 2177 bp += sizeof(rectype); 2178 2179 LOGCOPY_32(env, bp, &txn_num); 2180 bp += sizeof(txn_num); 2181 2182 LOGCOPY_FROMLSN(env, bp, lsnp); 2183 bp += sizeof(DB_LSN); 2184 2185 DB_ASSERT(env, 2186 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2187 2188 if (is_durable || txnp == NULL) { 2189 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2190 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2191 *lsnp = *rlsnp; 2192 if (rlsnp != ret_lsnp) 2193 *ret_lsnp = *rlsnp; 2194 } 2195 } else { 2196 ret = 0; 2197#ifdef DIAGNOSTIC 2198 /* 2199 * Set the debug bit if we are going to log non-durable 2200 * transactions so they will be ignored by recovery. 2201 */ 2202 memcpy(lr->data, logrec.data, logrec.size); 2203 rectype |= DB_debug_FLAG; 2204 LOGCOPY_32(env, logrec.data, &rectype); 2205 2206 if (!IS_REP_CLIENT(env)) 2207 ret = __log_put(env, 2208 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2209#endif 2210 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2211 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2212 LSN_NOT_LOGGED(*ret_lsnp); 2213 } 2214 2215#ifdef LOG_DIAGNOSTIC 2216 if (ret != 0) 2217 (void)__db_cksum_print(env, 2218 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2219#endif 2220 2221#ifdef DIAGNOSTIC 2222 __os_free(env, logrec.data); 2223#else 2224 if (is_durable || txnp == NULL) 2225 __os_free(env, logrec.data); 2226#endif 2227 return (ret); 2228} 2229 2230/* 2231 * PUBLIC: int __db_pg_freedata_42_read __P((ENV *, DB **, void *, 2232 * PUBLIC: void *, __db_pg_freedata_42_args **)); 2233 */ 2234int 2235__db_pg_freedata_42_read(env, dbpp, td, recbuf, argpp) 2236 ENV *env; 2237 DB **dbpp; 2238 void *td; 2239 void *recbuf; 2240 __db_pg_freedata_42_args **argpp; 2241{ 2242 __db_pg_freedata_42_args *argp; 2243 u_int32_t uinttmp; 2244 u_int8_t *bp; 2245 int ret; 2246 2247 if ((ret = __os_malloc(env, 2248 sizeof(__db_pg_freedata_42_args) + sizeof(DB_TXN), &argp)) != 0) 2249 return (ret); 2250 bp = recbuf; 2251 argp->txnp = (DB_TXN *)&argp[1]; 2252 memset(argp->txnp, 0, sizeof(DB_TXN)); 2253 2254 argp->txnp->td = td; 2255 LOGCOPY_32(env, &argp->type, bp); 2256 bp += sizeof(argp->type); 2257 2258 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2259 bp += sizeof(argp->txnp->txnid); 2260 2261 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2262 bp += sizeof(DB_LSN); 2263 2264 LOGCOPY_32(env, &uinttmp, bp); 2265 argp->fileid = (int32_t)uinttmp; 2266 bp += sizeof(uinttmp); 2267 if (dbpp != NULL) { 2268 *dbpp = NULL; 2269 ret = __dbreg_id_to_db( 2270 env, argp->txnp, dbpp, argp->fileid, 1); 2271 } 2272 2273 LOGCOPY_32(env, &uinttmp, bp); 2274 argp->pgno = (db_pgno_t)uinttmp; 2275 bp += sizeof(uinttmp); 2276 2277 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2278 bp += sizeof(DB_LSN); 2279 2280 LOGCOPY_32(env, &uinttmp, bp); 2281 argp->meta_pgno = (db_pgno_t)uinttmp; 2282 bp += sizeof(uinttmp); 2283 2284 memset(&argp->header, 0, sizeof(argp->header)); 2285 LOGCOPY_32(env,&argp->header.size, bp); 2286 bp += sizeof(u_int32_t); 2287 argp->header.data = bp; 2288 bp += argp->header.size; 2289 2290 LOGCOPY_32(env, &uinttmp, bp); 2291 argp->next = (db_pgno_t)uinttmp; 2292 bp += sizeof(uinttmp); 2293 2294 memset(&argp->data, 0, sizeof(argp->data)); 2295 LOGCOPY_32(env,&argp->data.size, bp); 2296 bp += sizeof(u_int32_t); 2297 argp->data.data = bp; 2298 bp += argp->data.size; 2299 2300 *argpp = argp; 2301 return (ret); 2302} 2303 2304/* 2305 * PUBLIC: int __db_pg_freedata_read __P((ENV *, DB **, void *, 2306 * PUBLIC: void *, __db_pg_freedata_args **)); 2307 */ 2308int 2309__db_pg_freedata_read(env, dbpp, td, recbuf, argpp) 2310 ENV *env; 2311 DB **dbpp; 2312 void *td; 2313 void *recbuf; 2314 __db_pg_freedata_args **argpp; 2315{ 2316 __db_pg_freedata_args *argp; 2317 u_int32_t uinttmp; 2318 u_int8_t *bp; 2319 int ret; 2320 2321 if ((ret = __os_malloc(env, 2322 sizeof(__db_pg_freedata_args) + sizeof(DB_TXN), &argp)) != 0) 2323 return (ret); 2324 bp = recbuf; 2325 argp->txnp = (DB_TXN *)&argp[1]; 2326 memset(argp->txnp, 0, sizeof(DB_TXN)); 2327 2328 argp->txnp->td = td; 2329 LOGCOPY_32(env, &argp->type, bp); 2330 bp += sizeof(argp->type); 2331 2332 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2333 bp += sizeof(argp->txnp->txnid); 2334 2335 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2336 bp += sizeof(DB_LSN); 2337 2338 LOGCOPY_32(env, &uinttmp, bp); 2339 argp->fileid = (int32_t)uinttmp; 2340 bp += sizeof(uinttmp); 2341 if (dbpp != NULL) { 2342 *dbpp = NULL; 2343 ret = __dbreg_id_to_db( 2344 env, argp->txnp, dbpp, argp->fileid, 1); 2345 } 2346 2347 LOGCOPY_32(env, &uinttmp, bp); 2348 argp->pgno = (db_pgno_t)uinttmp; 2349 bp += sizeof(uinttmp); 2350 2351 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2352 bp += sizeof(DB_LSN); 2353 2354 LOGCOPY_32(env, &uinttmp, bp); 2355 argp->meta_pgno = (db_pgno_t)uinttmp; 2356 bp += sizeof(uinttmp); 2357 2358 memset(&argp->header, 0, sizeof(argp->header)); 2359 LOGCOPY_32(env,&argp->header.size, bp); 2360 bp += sizeof(u_int32_t); 2361 argp->header.data = bp; 2362 bp += argp->header.size; 2363 2364 LOGCOPY_32(env, &uinttmp, bp); 2365 argp->next = (db_pgno_t)uinttmp; 2366 bp += sizeof(uinttmp); 2367 2368 LOGCOPY_32(env, &uinttmp, bp); 2369 argp->last_pgno = (db_pgno_t)uinttmp; 2370 bp += sizeof(uinttmp); 2371 2372 memset(&argp->data, 0, sizeof(argp->data)); 2373 LOGCOPY_32(env,&argp->data.size, bp); 2374 bp += sizeof(u_int32_t); 2375 argp->data.data = bp; 2376 bp += argp->data.size; 2377 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 2378 int t_ret; 2379 if ((t_ret = __db_pageswap(*dbpp, 2380 (PAGE *)argp->header.data, (size_t)argp->header.size, 2381 &argp->data, 1)) != 0) 2382 return (t_ret); 2383 } 2384 2385 *argpp = argp; 2386 return (ret); 2387} 2388 2389/* 2390 * PUBLIC: int __db_pg_freedata_log __P((DB *, DB_TXN *, DB_LSN *, 2391 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, 2392 * PUBLIC: db_pgno_t, db_pgno_t, const DBT *)); 2393 */ 2394int 2395__db_pg_freedata_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, 2396 last_pgno, data) 2397 DB *dbp; 2398 DB_TXN *txnp; 2399 DB_LSN *ret_lsnp; 2400 u_int32_t flags; 2401 db_pgno_t pgno; 2402 DB_LSN * meta_lsn; 2403 db_pgno_t meta_pgno; 2404 const DBT *header; 2405 db_pgno_t next; 2406 db_pgno_t last_pgno; 2407 const DBT *data; 2408{ 2409 DBT logrec; 2410 DB_LSN *lsnp, null_lsn, *rlsnp; 2411 DB_TXNLOGREC *lr; 2412 ENV *env; 2413 u_int32_t zero, uinttmp, rectype, txn_num; 2414 u_int npad; 2415 u_int8_t *bp; 2416 int is_durable, ret; 2417 2418 COMPQUIET(lr, NULL); 2419 2420 env = dbp->env; 2421 rlsnp = ret_lsnp; 2422 rectype = DB___db_pg_freedata; 2423 npad = 0; 2424 ret = 0; 2425 2426 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2427 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2428 if (txnp == NULL) 2429 return (0); 2430 is_durable = 0; 2431 } else 2432 is_durable = 1; 2433 2434 if (txnp == NULL) { 2435 txn_num = 0; 2436 lsnp = &null_lsn; 2437 null_lsn.file = null_lsn.offset = 0; 2438 } else { 2439 if (TAILQ_FIRST(&txnp->kids) != NULL && 2440 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2441 return (ret); 2442 /* 2443 * We need to assign begin_lsn while holding region mutex. 2444 * That assignment is done inside the DbEnv->log_put call, 2445 * so pass in the appropriate memory location to be filled 2446 * in by the log_put code. 2447 */ 2448 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2449 txn_num = txnp->txnid; 2450 } 2451 2452 DB_ASSERT(env, dbp->log_filename != NULL); 2453 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2454 (ret = __dbreg_lazy_id(dbp)) != 0) 2455 return (ret); 2456 2457 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2458 + sizeof(u_int32_t) 2459 + sizeof(u_int32_t) 2460 + sizeof(*meta_lsn) 2461 + sizeof(u_int32_t) 2462 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 2463 + sizeof(u_int32_t) 2464 + sizeof(u_int32_t) 2465 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 2466 if (CRYPTO_ON(env)) { 2467 npad = env->crypto_handle->adj_size(logrec.size); 2468 logrec.size += npad; 2469 } 2470 2471 if (is_durable || txnp == NULL) { 2472 if ((ret = 2473 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2474 return (ret); 2475 } else { 2476 if ((ret = __os_malloc(env, 2477 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2478 return (ret); 2479#ifdef DIAGNOSTIC 2480 if ((ret = 2481 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2482 __os_free(env, lr); 2483 return (ret); 2484 } 2485#else 2486 logrec.data = lr->data; 2487#endif 2488 } 2489 if (npad > 0) 2490 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2491 2492 bp = logrec.data; 2493 2494 LOGCOPY_32(env, bp, &rectype); 2495 bp += sizeof(rectype); 2496 2497 LOGCOPY_32(env, bp, &txn_num); 2498 bp += sizeof(txn_num); 2499 2500 LOGCOPY_FROMLSN(env, bp, lsnp); 2501 bp += sizeof(DB_LSN); 2502 2503 uinttmp = (u_int32_t)dbp->log_filename->id; 2504 LOGCOPY_32(env, bp, &uinttmp); 2505 bp += sizeof(uinttmp); 2506 2507 uinttmp = (u_int32_t)pgno; 2508 LOGCOPY_32(env,bp, &uinttmp); 2509 bp += sizeof(uinttmp); 2510 2511 if (meta_lsn != NULL) { 2512 if (txnp != NULL) { 2513 LOG *lp = env->lg_handle->reginfo.primary; 2514 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 2515 __log_check_page_lsn(env, dbp, meta_lsn)) != 0) 2516 return (ret); 2517 } 2518 LOGCOPY_FROMLSN(env, bp, meta_lsn); 2519 } else 2520 memset(bp, 0, sizeof(*meta_lsn)); 2521 bp += sizeof(*meta_lsn); 2522 2523 uinttmp = (u_int32_t)meta_pgno; 2524 LOGCOPY_32(env,bp, &uinttmp); 2525 bp += sizeof(uinttmp); 2526 2527 if (header == NULL) { 2528 zero = 0; 2529 LOGCOPY_32(env, bp, &zero); 2530 bp += sizeof(u_int32_t); 2531 } else { 2532 LOGCOPY_32(env, bp, &header->size); 2533 bp += sizeof(header->size); 2534 memcpy(bp, header->data, header->size); 2535 if (LOG_SWAPPED(env)) 2536 if ((ret = __db_pageswap(dbp, 2537 (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) 2538 return (ret); 2539 bp += header->size; 2540 } 2541 2542 uinttmp = (u_int32_t)next; 2543 LOGCOPY_32(env,bp, &uinttmp); 2544 bp += sizeof(uinttmp); 2545 2546 uinttmp = (u_int32_t)last_pgno; 2547 LOGCOPY_32(env,bp, &uinttmp); 2548 bp += sizeof(uinttmp); 2549 2550 if (data == NULL) { 2551 zero = 0; 2552 LOGCOPY_32(env, bp, &zero); 2553 bp += sizeof(u_int32_t); 2554 } else { 2555 LOGCOPY_32(env, bp, &data->size); 2556 bp += sizeof(data->size); 2557 memcpy(bp, data->data, data->size); 2558 if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) 2559 __os_free(env, data->data); 2560 bp += data->size; 2561 } 2562 2563 DB_ASSERT(env, 2564 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2565 2566 if (is_durable || txnp == NULL) { 2567 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2568 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2569 *lsnp = *rlsnp; 2570 if (rlsnp != ret_lsnp) 2571 *ret_lsnp = *rlsnp; 2572 } 2573 } else { 2574 ret = 0; 2575#ifdef DIAGNOSTIC 2576 /* 2577 * Set the debug bit if we are going to log non-durable 2578 * transactions so they will be ignored by recovery. 2579 */ 2580 memcpy(lr->data, logrec.data, logrec.size); 2581 rectype |= DB_debug_FLAG; 2582 LOGCOPY_32(env, logrec.data, &rectype); 2583 2584 if (!IS_REP_CLIENT(env)) 2585 ret = __log_put(env, 2586 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2587#endif 2588 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2589 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2590 LSN_NOT_LOGGED(*ret_lsnp); 2591 } 2592 2593#ifdef LOG_DIAGNOSTIC 2594 if (ret != 0) 2595 (void)__db_pg_freedata_print(env, 2596 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2597#endif 2598 2599#ifdef DIAGNOSTIC 2600 __os_free(env, logrec.data); 2601#else 2602 if (is_durable || txnp == NULL) 2603 __os_free(env, logrec.data); 2604#endif 2605 return (ret); 2606} 2607 2608/* 2609 * PUBLIC: int __db_pg_init_read __P((ENV *, DB **, void *, void *, 2610 * PUBLIC: __db_pg_init_args **)); 2611 */ 2612int 2613__db_pg_init_read(env, dbpp, td, recbuf, argpp) 2614 ENV *env; 2615 DB **dbpp; 2616 void *td; 2617 void *recbuf; 2618 __db_pg_init_args **argpp; 2619{ 2620 __db_pg_init_args *argp; 2621 u_int32_t uinttmp; 2622 u_int8_t *bp; 2623 int ret; 2624 2625 if ((ret = __os_malloc(env, 2626 sizeof(__db_pg_init_args) + sizeof(DB_TXN), &argp)) != 0) 2627 return (ret); 2628 bp = recbuf; 2629 argp->txnp = (DB_TXN *)&argp[1]; 2630 memset(argp->txnp, 0, sizeof(DB_TXN)); 2631 2632 argp->txnp->td = td; 2633 LOGCOPY_32(env, &argp->type, bp); 2634 bp += sizeof(argp->type); 2635 2636 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2637 bp += sizeof(argp->txnp->txnid); 2638 2639 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2640 bp += sizeof(DB_LSN); 2641 2642 LOGCOPY_32(env, &uinttmp, bp); 2643 argp->fileid = (int32_t)uinttmp; 2644 bp += sizeof(uinttmp); 2645 if (dbpp != NULL) { 2646 *dbpp = NULL; 2647 ret = __dbreg_id_to_db( 2648 env, argp->txnp, dbpp, argp->fileid, 1); 2649 } 2650 2651 LOGCOPY_32(env, &uinttmp, bp); 2652 argp->pgno = (db_pgno_t)uinttmp; 2653 bp += sizeof(uinttmp); 2654 2655 memset(&argp->header, 0, sizeof(argp->header)); 2656 LOGCOPY_32(env,&argp->header.size, bp); 2657 bp += sizeof(u_int32_t); 2658 argp->header.data = bp; 2659 bp += argp->header.size; 2660 2661 memset(&argp->data, 0, sizeof(argp->data)); 2662 LOGCOPY_32(env,&argp->data.size, bp); 2663 bp += sizeof(u_int32_t); 2664 argp->data.data = bp; 2665 bp += argp->data.size; 2666 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 2667 int t_ret; 2668 if ((t_ret = __db_pageswap(*dbpp, 2669 (PAGE *)argp->header.data, (size_t)argp->header.size, 2670 &argp->data, 1)) != 0) 2671 return (t_ret); 2672 } 2673 2674 *argpp = argp; 2675 return (ret); 2676} 2677 2678/* 2679 * PUBLIC: int __db_pg_init_log __P((DB *, DB_TXN *, DB_LSN *, 2680 * PUBLIC: u_int32_t, db_pgno_t, const DBT *, const DBT *)); 2681 */ 2682int 2683__db_pg_init_log(dbp, txnp, ret_lsnp, flags, pgno, header, data) 2684 DB *dbp; 2685 DB_TXN *txnp; 2686 DB_LSN *ret_lsnp; 2687 u_int32_t flags; 2688 db_pgno_t pgno; 2689 const DBT *header; 2690 const DBT *data; 2691{ 2692 DBT logrec; 2693 DB_LSN *lsnp, null_lsn, *rlsnp; 2694 DB_TXNLOGREC *lr; 2695 ENV *env; 2696 u_int32_t zero, uinttmp, rectype, txn_num; 2697 u_int npad; 2698 u_int8_t *bp; 2699 int is_durable, ret; 2700 2701 COMPQUIET(lr, NULL); 2702 2703 env = dbp->env; 2704 rlsnp = ret_lsnp; 2705 rectype = DB___db_pg_init; 2706 npad = 0; 2707 ret = 0; 2708 2709 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2710 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2711 if (txnp == NULL) 2712 return (0); 2713 is_durable = 0; 2714 } else 2715 is_durable = 1; 2716 2717 if (txnp == NULL) { 2718 txn_num = 0; 2719 lsnp = &null_lsn; 2720 null_lsn.file = null_lsn.offset = 0; 2721 } else { 2722 if (TAILQ_FIRST(&txnp->kids) != NULL && 2723 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2724 return (ret); 2725 /* 2726 * We need to assign begin_lsn while holding region mutex. 2727 * That assignment is done inside the DbEnv->log_put call, 2728 * so pass in the appropriate memory location to be filled 2729 * in by the log_put code. 2730 */ 2731 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2732 txn_num = txnp->txnid; 2733 } 2734 2735 DB_ASSERT(env, dbp->log_filename != NULL); 2736 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2737 (ret = __dbreg_lazy_id(dbp)) != 0) 2738 return (ret); 2739 2740 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2741 + sizeof(u_int32_t) 2742 + sizeof(u_int32_t) 2743 + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) 2744 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 2745 if (CRYPTO_ON(env)) { 2746 npad = env->crypto_handle->adj_size(logrec.size); 2747 logrec.size += npad; 2748 } 2749 2750 if (is_durable || txnp == NULL) { 2751 if ((ret = 2752 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2753 return (ret); 2754 } else { 2755 if ((ret = __os_malloc(env, 2756 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2757 return (ret); 2758#ifdef DIAGNOSTIC 2759 if ((ret = 2760 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2761 __os_free(env, lr); 2762 return (ret); 2763 } 2764#else 2765 logrec.data = lr->data; 2766#endif 2767 } 2768 if (npad > 0) 2769 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2770 2771 bp = logrec.data; 2772 2773 LOGCOPY_32(env, bp, &rectype); 2774 bp += sizeof(rectype); 2775 2776 LOGCOPY_32(env, bp, &txn_num); 2777 bp += sizeof(txn_num); 2778 2779 LOGCOPY_FROMLSN(env, bp, lsnp); 2780 bp += sizeof(DB_LSN); 2781 2782 uinttmp = (u_int32_t)dbp->log_filename->id; 2783 LOGCOPY_32(env, bp, &uinttmp); 2784 bp += sizeof(uinttmp); 2785 2786 uinttmp = (u_int32_t)pgno; 2787 LOGCOPY_32(env,bp, &uinttmp); 2788 bp += sizeof(uinttmp); 2789 2790 if (header == NULL) { 2791 zero = 0; 2792 LOGCOPY_32(env, bp, &zero); 2793 bp += sizeof(u_int32_t); 2794 } else { 2795 LOGCOPY_32(env, bp, &header->size); 2796 bp += sizeof(header->size); 2797 memcpy(bp, header->data, header->size); 2798 if (LOG_SWAPPED(env)) 2799 if ((ret = __db_pageswap(dbp, 2800 (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) 2801 return (ret); 2802 bp += header->size; 2803 } 2804 2805 if (data == NULL) { 2806 zero = 0; 2807 LOGCOPY_32(env, bp, &zero); 2808 bp += sizeof(u_int32_t); 2809 } else { 2810 LOGCOPY_32(env, bp, &data->size); 2811 bp += sizeof(data->size); 2812 memcpy(bp, data->data, data->size); 2813 if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) 2814 __os_free(env, data->data); 2815 bp += data->size; 2816 } 2817 2818 DB_ASSERT(env, 2819 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2820 2821 if (is_durable || txnp == NULL) { 2822 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2823 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2824 *lsnp = *rlsnp; 2825 if (rlsnp != ret_lsnp) 2826 *ret_lsnp = *rlsnp; 2827 } 2828 } else { 2829 ret = 0; 2830#ifdef DIAGNOSTIC 2831 /* 2832 * Set the debug bit if we are going to log non-durable 2833 * transactions so they will be ignored by recovery. 2834 */ 2835 memcpy(lr->data, logrec.data, logrec.size); 2836 rectype |= DB_debug_FLAG; 2837 LOGCOPY_32(env, logrec.data, &rectype); 2838 2839 if (!IS_REP_CLIENT(env)) 2840 ret = __log_put(env, 2841 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2842#endif 2843 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2844 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2845 LSN_NOT_LOGGED(*ret_lsnp); 2846 } 2847 2848#ifdef LOG_DIAGNOSTIC 2849 if (ret != 0) 2850 (void)__db_pg_init_print(env, 2851 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2852#endif 2853 2854#ifdef DIAGNOSTIC 2855 __os_free(env, logrec.data); 2856#else 2857 if (is_durable || txnp == NULL) 2858 __os_free(env, logrec.data); 2859#endif 2860 return (ret); 2861} 2862 2863/* 2864 * PUBLIC: int __db_pg_sort_44_read __P((ENV *, DB **, void *, 2865 * PUBLIC: void *, __db_pg_sort_44_args **)); 2866 */ 2867int 2868__db_pg_sort_44_read(env, dbpp, td, recbuf, argpp) 2869 ENV *env; 2870 DB **dbpp; 2871 void *td; 2872 void *recbuf; 2873 __db_pg_sort_44_args **argpp; 2874{ 2875 __db_pg_sort_44_args *argp; 2876 u_int32_t uinttmp; 2877 u_int8_t *bp; 2878 int ret; 2879 2880 if ((ret = __os_malloc(env, 2881 sizeof(__db_pg_sort_44_args) + sizeof(DB_TXN), &argp)) != 0) 2882 return (ret); 2883 bp = recbuf; 2884 argp->txnp = (DB_TXN *)&argp[1]; 2885 memset(argp->txnp, 0, sizeof(DB_TXN)); 2886 2887 argp->txnp->td = td; 2888 LOGCOPY_32(env, &argp->type, bp); 2889 bp += sizeof(argp->type); 2890 2891 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2892 bp += sizeof(argp->txnp->txnid); 2893 2894 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2895 bp += sizeof(DB_LSN); 2896 2897 LOGCOPY_32(env, &uinttmp, bp); 2898 argp->fileid = (int32_t)uinttmp; 2899 bp += sizeof(uinttmp); 2900 if (dbpp != NULL) { 2901 *dbpp = NULL; 2902 ret = __dbreg_id_to_db( 2903 env, argp->txnp, dbpp, argp->fileid, 1); 2904 } 2905 2906 LOGCOPY_32(env, &uinttmp, bp); 2907 argp->meta = (db_pgno_t)uinttmp; 2908 bp += sizeof(uinttmp); 2909 2910 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2911 bp += sizeof(DB_LSN); 2912 2913 LOGCOPY_32(env, &uinttmp, bp); 2914 argp->last_free = (db_pgno_t)uinttmp; 2915 bp += sizeof(uinttmp); 2916 2917 LOGCOPY_TOLSN(env, &argp->last_lsn, bp); 2918 bp += sizeof(DB_LSN); 2919 2920 LOGCOPY_32(env, &uinttmp, bp); 2921 argp->last_pgno = (db_pgno_t)uinttmp; 2922 bp += sizeof(uinttmp); 2923 2924 memset(&argp->list, 0, sizeof(argp->list)); 2925 LOGCOPY_32(env,&argp->list.size, bp); 2926 bp += sizeof(u_int32_t); 2927 argp->list.data = bp; 2928 bp += argp->list.size; 2929 2930 *argpp = argp; 2931 return (ret); 2932} 2933 2934/* 2935 * PUBLIC: int __db_pg_trunc_read __P((ENV *, DB **, void *, void *, 2936 * PUBLIC: __db_pg_trunc_args **)); 2937 */ 2938int 2939__db_pg_trunc_read(env, dbpp, td, recbuf, argpp) 2940 ENV *env; 2941 DB **dbpp; 2942 void *td; 2943 void *recbuf; 2944 __db_pg_trunc_args **argpp; 2945{ 2946 __db_pg_trunc_args *argp; 2947 u_int32_t uinttmp; 2948 u_int8_t *bp; 2949 int ret; 2950 2951 if ((ret = __os_malloc(env, 2952 sizeof(__db_pg_trunc_args) + sizeof(DB_TXN), &argp)) != 0) 2953 return (ret); 2954 bp = recbuf; 2955 argp->txnp = (DB_TXN *)&argp[1]; 2956 memset(argp->txnp, 0, sizeof(DB_TXN)); 2957 2958 argp->txnp->td = td; 2959 LOGCOPY_32(env, &argp->type, bp); 2960 bp += sizeof(argp->type); 2961 2962 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2963 bp += sizeof(argp->txnp->txnid); 2964 2965 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2966 bp += sizeof(DB_LSN); 2967 2968 LOGCOPY_32(env, &uinttmp, bp); 2969 argp->fileid = (int32_t)uinttmp; 2970 bp += sizeof(uinttmp); 2971 if (dbpp != NULL) { 2972 *dbpp = NULL; 2973 ret = __dbreg_id_to_db( 2974 env, argp->txnp, dbpp, argp->fileid, 1); 2975 } 2976 2977 LOGCOPY_32(env, &uinttmp, bp); 2978 argp->meta = (db_pgno_t)uinttmp; 2979 bp += sizeof(uinttmp); 2980 2981 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 2982 bp += sizeof(DB_LSN); 2983 2984 LOGCOPY_32(env, &uinttmp, bp); 2985 argp->last_free = (db_pgno_t)uinttmp; 2986 bp += sizeof(uinttmp); 2987 2988 LOGCOPY_TOLSN(env, &argp->last_lsn, bp); 2989 bp += sizeof(DB_LSN); 2990 2991 LOGCOPY_32(env, &uinttmp, bp); 2992 argp->next_free = (db_pgno_t)uinttmp; 2993 bp += sizeof(uinttmp); 2994 2995 LOGCOPY_32(env, &uinttmp, bp); 2996 argp->last_pgno = (db_pgno_t)uinttmp; 2997 bp += sizeof(uinttmp); 2998 2999 memset(&argp->list, 0, sizeof(argp->list)); 3000 LOGCOPY_32(env,&argp->list.size, bp); 3001 bp += sizeof(u_int32_t); 3002 argp->list.data = bp; 3003 bp += argp->list.size; 3004 3005 *argpp = argp; 3006 return (ret); 3007} 3008 3009/* 3010 * PUBLIC: int __db_pg_trunc_log __P((DB *, DB_TXN *, DB_LSN *, 3011 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, 3012 * PUBLIC: db_pgno_t, const DBT *)); 3013 */ 3014int 3015__db_pg_trunc_log(dbp, txnp, ret_lsnp, flags, meta, meta_lsn, last_free, last_lsn, next_free, 3016 last_pgno, list) 3017 DB *dbp; 3018 DB_TXN *txnp; 3019 DB_LSN *ret_lsnp; 3020 u_int32_t flags; 3021 db_pgno_t meta; 3022 DB_LSN * meta_lsn; 3023 db_pgno_t last_free; 3024 DB_LSN * last_lsn; 3025 db_pgno_t next_free; 3026 db_pgno_t last_pgno; 3027 const DBT *list; 3028{ 3029 DBT logrec; 3030 DB_LSN *lsnp, null_lsn, *rlsnp; 3031 DB_TXNLOGREC *lr; 3032 ENV *env; 3033 u_int32_t zero, uinttmp, rectype, txn_num; 3034 u_int npad; 3035 u_int8_t *bp; 3036 int is_durable, ret; 3037 3038 COMPQUIET(lr, NULL); 3039 3040 env = dbp->env; 3041 rlsnp = ret_lsnp; 3042 rectype = DB___db_pg_trunc; 3043 npad = 0; 3044 ret = 0; 3045 3046 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 3047 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 3048 if (txnp == NULL) 3049 return (0); 3050 is_durable = 0; 3051 } else 3052 is_durable = 1; 3053 3054 if (txnp == NULL) { 3055 txn_num = 0; 3056 lsnp = &null_lsn; 3057 null_lsn.file = null_lsn.offset = 0; 3058 } else { 3059 if (TAILQ_FIRST(&txnp->kids) != NULL && 3060 (ret = __txn_activekids(env, rectype, txnp)) != 0) 3061 return (ret); 3062 /* 3063 * We need to assign begin_lsn while holding region mutex. 3064 * That assignment is done inside the DbEnv->log_put call, 3065 * so pass in the appropriate memory location to be filled 3066 * in by the log_put code. 3067 */ 3068 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 3069 txn_num = txnp->txnid; 3070 } 3071 3072 DB_ASSERT(env, dbp->log_filename != NULL); 3073 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 3074 (ret = __dbreg_lazy_id(dbp)) != 0) 3075 return (ret); 3076 3077 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 3078 + sizeof(u_int32_t) 3079 + sizeof(u_int32_t) 3080 + sizeof(*meta_lsn) 3081 + sizeof(u_int32_t) 3082 + sizeof(*last_lsn) 3083 + sizeof(u_int32_t) 3084 + sizeof(u_int32_t) 3085 + sizeof(u_int32_t) + (list == NULL ? 0 : list->size); 3086 if (CRYPTO_ON(env)) { 3087 npad = env->crypto_handle->adj_size(logrec.size); 3088 logrec.size += npad; 3089 } 3090 3091 if (is_durable || txnp == NULL) { 3092 if ((ret = 3093 __os_malloc(env, logrec.size, &logrec.data)) != 0) 3094 return (ret); 3095 } else { 3096 if ((ret = __os_malloc(env, 3097 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 3098 return (ret); 3099#ifdef DIAGNOSTIC 3100 if ((ret = 3101 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 3102 __os_free(env, lr); 3103 return (ret); 3104 } 3105#else 3106 logrec.data = lr->data; 3107#endif 3108 } 3109 if (npad > 0) 3110 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 3111 3112 bp = logrec.data; 3113 3114 LOGCOPY_32(env, bp, &rectype); 3115 bp += sizeof(rectype); 3116 3117 LOGCOPY_32(env, bp, &txn_num); 3118 bp += sizeof(txn_num); 3119 3120 LOGCOPY_FROMLSN(env, bp, lsnp); 3121 bp += sizeof(DB_LSN); 3122 3123 uinttmp = (u_int32_t)dbp->log_filename->id; 3124 LOGCOPY_32(env, bp, &uinttmp); 3125 bp += sizeof(uinttmp); 3126 3127 uinttmp = (u_int32_t)meta; 3128 LOGCOPY_32(env,bp, &uinttmp); 3129 bp += sizeof(uinttmp); 3130 3131 if (meta_lsn != NULL) { 3132 if (txnp != NULL) { 3133 LOG *lp = env->lg_handle->reginfo.primary; 3134 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 3135 __log_check_page_lsn(env, dbp, meta_lsn)) != 0) 3136 return (ret); 3137 } 3138 LOGCOPY_FROMLSN(env, bp, meta_lsn); 3139 } else 3140 memset(bp, 0, sizeof(*meta_lsn)); 3141 bp += sizeof(*meta_lsn); 3142 3143 uinttmp = (u_int32_t)last_free; 3144 LOGCOPY_32(env,bp, &uinttmp); 3145 bp += sizeof(uinttmp); 3146 3147 if (last_lsn != NULL) { 3148 if (txnp != NULL) { 3149 LOG *lp = env->lg_handle->reginfo.primary; 3150 if (LOG_COMPARE(last_lsn, &lp->lsn) >= 0 && (ret = 3151 __log_check_page_lsn(env, dbp, last_lsn)) != 0) 3152 return (ret); 3153 } 3154 LOGCOPY_FROMLSN(env, bp, last_lsn); 3155 } else 3156 memset(bp, 0, sizeof(*last_lsn)); 3157 bp += sizeof(*last_lsn); 3158 3159 uinttmp = (u_int32_t)next_free; 3160 LOGCOPY_32(env,bp, &uinttmp); 3161 bp += sizeof(uinttmp); 3162 3163 uinttmp = (u_int32_t)last_pgno; 3164 LOGCOPY_32(env,bp, &uinttmp); 3165 bp += sizeof(uinttmp); 3166 3167 if (list == NULL) { 3168 zero = 0; 3169 LOGCOPY_32(env, bp, &zero); 3170 bp += sizeof(u_int32_t); 3171 } else { 3172 LOGCOPY_32(env, bp, &list->size); 3173 bp += sizeof(list->size); 3174 memcpy(bp, list->data, list->size); 3175 bp += list->size; 3176 } 3177 3178 DB_ASSERT(env, 3179 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 3180 3181 if (is_durable || txnp == NULL) { 3182 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 3183 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 3184 *lsnp = *rlsnp; 3185 if (rlsnp != ret_lsnp) 3186 *ret_lsnp = *rlsnp; 3187 } 3188 } else { 3189 ret = 0; 3190#ifdef DIAGNOSTIC 3191 /* 3192 * Set the debug bit if we are going to log non-durable 3193 * transactions so they will be ignored by recovery. 3194 */ 3195 memcpy(lr->data, logrec.data, logrec.size); 3196 rectype |= DB_debug_FLAG; 3197 LOGCOPY_32(env, logrec.data, &rectype); 3198 3199 if (!IS_REP_CLIENT(env)) 3200 ret = __log_put(env, 3201 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 3202#endif 3203 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 3204 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 3205 LSN_NOT_LOGGED(*ret_lsnp); 3206 } 3207 3208#ifdef LOG_DIAGNOSTIC 3209 if (ret != 0) 3210 (void)__db_pg_trunc_print(env, 3211 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 3212#endif 3213 3214#ifdef DIAGNOSTIC 3215 __os_free(env, logrec.data); 3216#else 3217 if (is_durable || txnp == NULL) 3218 __os_free(env, logrec.data); 3219#endif 3220 return (ret); 3221} 3222 3223/* 3224 * PUBLIC: int __db_init_recover __P((ENV *, DB_DISTAB *)); 3225 */ 3226int 3227__db_init_recover(env, dtabp) 3228 ENV *env; 3229 DB_DISTAB *dtabp; 3230{ 3231 int ret; 3232 3233 if ((ret = __db_add_recovery_int(env, dtabp, 3234 __db_addrem_recover, DB___db_addrem)) != 0) 3235 return (ret); 3236 if ((ret = __db_add_recovery_int(env, dtabp, 3237 __db_big_recover, DB___db_big)) != 0) 3238 return (ret); 3239 if ((ret = __db_add_recovery_int(env, dtabp, 3240 __db_ovref_recover, DB___db_ovref)) != 0) 3241 return (ret); 3242 if ((ret = __db_add_recovery_int(env, dtabp, 3243 __db_debug_recover, DB___db_debug)) != 0) 3244 return (ret); 3245 if ((ret = __db_add_recovery_int(env, dtabp, 3246 __db_noop_recover, DB___db_noop)) != 0) 3247 return (ret); 3248 if ((ret = __db_add_recovery_int(env, dtabp, 3249 __db_pg_alloc_recover, DB___db_pg_alloc)) != 0) 3250 return (ret); 3251 if ((ret = __db_add_recovery_int(env, dtabp, 3252 __db_pg_free_recover, DB___db_pg_free)) != 0) 3253 return (ret); 3254 if ((ret = __db_add_recovery_int(env, dtabp, 3255 __db_cksum_recover, DB___db_cksum)) != 0) 3256 return (ret); 3257 if ((ret = __db_add_recovery_int(env, dtabp, 3258 __db_pg_freedata_recover, DB___db_pg_freedata)) != 0) 3259 return (ret); 3260 if ((ret = __db_add_recovery_int(env, dtabp, 3261 __db_pg_init_recover, DB___db_pg_init)) != 0) 3262 return (ret); 3263 if ((ret = __db_add_recovery_int(env, dtabp, 3264 __db_pg_trunc_recover, DB___db_pg_trunc)) != 0) 3265 return (ret); 3266 return (0); 3267} 3268