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