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