1/* Do not edit: automatically built by gen_rec.awk. */ 2 3#include "db_config.h" 4#include "db_int.h" 5#include "dbinc/crypto.h" 6#include "dbinc/db_page.h" 7#include "dbinc/db_dispatch.h" 8#include "dbinc/db_am.h" 9#include "dbinc/hash.h" 10#include "dbinc/log.h" 11#include "dbinc/txn.h" 12 13/* 14 * PUBLIC: int __ham_insdel_read __P((ENV *, DB **, void *, void *, 15 * PUBLIC: __ham_insdel_args **)); 16 */ 17int 18__ham_insdel_read(env, dbpp, td, recbuf, argpp) 19 ENV *env; 20 DB **dbpp; 21 void *td; 22 void *recbuf; 23 __ham_insdel_args **argpp; 24{ 25 __ham_insdel_args *argp; 26 u_int32_t uinttmp; 27 u_int8_t *bp; 28 int ret; 29 30 if ((ret = __os_malloc(env, 31 sizeof(__ham_insdel_args) + sizeof(DB_TXN), &argp)) != 0) 32 return (ret); 33 bp = recbuf; 34 argp->txnp = (DB_TXN *)&argp[1]; 35 memset(argp->txnp, 0, sizeof(DB_TXN)); 36 37 argp->txnp->td = td; 38 LOGCOPY_32(env, &argp->type, bp); 39 bp += sizeof(argp->type); 40 41 LOGCOPY_32(env, &argp->txnp->txnid, bp); 42 bp += sizeof(argp->txnp->txnid); 43 44 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 45 bp += sizeof(DB_LSN); 46 47 LOGCOPY_32(env, &argp->opcode, bp); 48 bp += sizeof(argp->opcode); 49 50 LOGCOPY_32(env, &uinttmp, bp); 51 argp->fileid = (int32_t)uinttmp; 52 bp += sizeof(uinttmp); 53 if (dbpp != NULL) { 54 *dbpp = NULL; 55 ret = __dbreg_id_to_db( 56 env, argp->txnp, dbpp, argp->fileid, 1); 57 } 58 59 LOGCOPY_32(env, &uinttmp, bp); 60 argp->pgno = (db_pgno_t)uinttmp; 61 bp += sizeof(uinttmp); 62 63 LOGCOPY_32(env, &argp->ndx, bp); 64 bp += sizeof(argp->ndx); 65 66 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 67 bp += sizeof(DB_LSN); 68 69 memset(&argp->key, 0, sizeof(argp->key)); 70 LOGCOPY_32(env,&argp->key.size, bp); 71 bp += sizeof(u_int32_t); 72 argp->key.data = bp; 73 bp += argp->key.size; 74 75 memset(&argp->data, 0, sizeof(argp->data)); 76 LOGCOPY_32(env,&argp->data.size, bp); 77 bp += sizeof(u_int32_t); 78 argp->data.data = bp; 79 bp += argp->data.size; 80 81 *argpp = argp; 82 return (ret); 83} 84 85/* 86 * PUBLIC: int __ham_insdel_log __P((DB *, DB_TXN *, DB_LSN *, 87 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, u_int32_t, DB_LSN *, 88 * PUBLIC: const DBT *, const DBT *)); 89 */ 90int 91__ham_insdel_log(dbp, txnp, ret_lsnp, flags, 92 opcode, pgno, ndx, pagelsn, key, 93 data) 94 DB *dbp; 95 DB_TXN *txnp; 96 DB_LSN *ret_lsnp; 97 u_int32_t flags; 98 u_int32_t opcode; 99 db_pgno_t pgno; 100 u_int32_t ndx; 101 DB_LSN * pagelsn; 102 const DBT *key; 103 const DBT *data; 104{ 105 DBT logrec; 106 DB_LSN *lsnp, null_lsn, *rlsnp; 107 DB_TXNLOGREC *lr; 108 ENV *env; 109 u_int32_t zero, uinttmp, rectype, txn_num; 110 u_int npad; 111 u_int8_t *bp; 112 int is_durable, ret; 113 114 COMPQUIET(lr, NULL); 115 116 env = dbp->env; 117 rlsnp = ret_lsnp; 118 rectype = DB___ham_insdel; 119 npad = 0; 120 ret = 0; 121 122 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 123 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 124 if (txnp == NULL) 125 return (0); 126 is_durable = 0; 127 } else 128 is_durable = 1; 129 130 if (txnp == NULL) { 131 txn_num = 0; 132 lsnp = &null_lsn; 133 null_lsn.file = null_lsn.offset = 0; 134 } else { 135 if (TAILQ_FIRST(&txnp->kids) != NULL && 136 (ret = __txn_activekids(env, rectype, txnp)) != 0) 137 return (ret); 138 /* 139 * We need to assign begin_lsn while holding region mutex. 140 * That assignment is done inside the DbEnv->log_put call, 141 * so pass in the appropriate memory location to be filled 142 * in by the log_put code. 143 */ 144 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 145 txn_num = txnp->txnid; 146 } 147 148 DB_ASSERT(env, dbp->log_filename != NULL); 149 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 150 (ret = __dbreg_lazy_id(dbp)) != 0) 151 return (ret); 152 153 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 154 + sizeof(u_int32_t) 155 + sizeof(u_int32_t) 156 + sizeof(u_int32_t) 157 + sizeof(u_int32_t) 158 + sizeof(*pagelsn) 159 + sizeof(u_int32_t) + (key == NULL ? 0 : key->size) 160 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 161 if (CRYPTO_ON(env)) { 162 npad = env->crypto_handle->adj_size(logrec.size); 163 logrec.size += npad; 164 } 165 166 if (is_durable || txnp == NULL) { 167 if ((ret = 168 __os_malloc(env, logrec.size, &logrec.data)) != 0) 169 return (ret); 170 } else { 171 if ((ret = __os_malloc(env, 172 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 173 return (ret); 174#ifdef DIAGNOSTIC 175 if ((ret = 176 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 177 __os_free(env, lr); 178 return (ret); 179 } 180#else 181 logrec.data = lr->data; 182#endif 183 } 184 if (npad > 0) 185 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 186 187 bp = logrec.data; 188 189 LOGCOPY_32(env, bp, &rectype); 190 bp += sizeof(rectype); 191 192 LOGCOPY_32(env, bp, &txn_num); 193 bp += sizeof(txn_num); 194 195 LOGCOPY_FROMLSN(env, bp, lsnp); 196 bp += sizeof(DB_LSN); 197 198 LOGCOPY_32(env, bp, &opcode); 199 bp += sizeof(opcode); 200 201 uinttmp = (u_int32_t)dbp->log_filename->id; 202 LOGCOPY_32(env, bp, &uinttmp); 203 bp += sizeof(uinttmp); 204 205 uinttmp = (u_int32_t)pgno; 206 LOGCOPY_32(env,bp, &uinttmp); 207 bp += sizeof(uinttmp); 208 209 LOGCOPY_32(env, bp, &ndx); 210 bp += sizeof(ndx); 211 212 if (pagelsn != NULL) { 213 if (txnp != NULL) { 214 LOG *lp = env->lg_handle->reginfo.primary; 215 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 216 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 217 return (ret); 218 } 219 LOGCOPY_FROMLSN(env, bp, pagelsn); 220 } else 221 memset(bp, 0, sizeof(*pagelsn)); 222 bp += sizeof(*pagelsn); 223 224 if (key == NULL) { 225 zero = 0; 226 LOGCOPY_32(env, bp, &zero); 227 bp += sizeof(u_int32_t); 228 } else { 229 LOGCOPY_32(env, bp, &key->size); 230 bp += sizeof(key->size); 231 memcpy(bp, key->data, key->size); 232 bp += key->size; 233 } 234 235 if (data == NULL) { 236 zero = 0; 237 LOGCOPY_32(env, bp, &zero); 238 bp += sizeof(u_int32_t); 239 } else { 240 LOGCOPY_32(env, bp, &data->size); 241 bp += sizeof(data->size); 242 memcpy(bp, data->data, data->size); 243 bp += data->size; 244 } 245 246 DB_ASSERT(env, 247 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 248 249 if (is_durable || txnp == NULL) { 250 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 251 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 252 *lsnp = *rlsnp; 253 if (rlsnp != ret_lsnp) 254 *ret_lsnp = *rlsnp; 255 } 256 } else { 257 ret = 0; 258#ifdef DIAGNOSTIC 259 /* 260 * Set the debug bit if we are going to log non-durable 261 * transactions so they will be ignored by recovery. 262 */ 263 memcpy(lr->data, logrec.data, logrec.size); 264 rectype |= DB_debug_FLAG; 265 LOGCOPY_32(env, logrec.data, &rectype); 266 267 if (!IS_REP_CLIENT(env)) 268 ret = __log_put(env, 269 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 270#endif 271 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 272 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 273 LSN_NOT_LOGGED(*ret_lsnp); 274 } 275 276#ifdef LOG_DIAGNOSTIC 277 if (ret != 0) 278 (void)__ham_insdel_print(env, 279 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 280#endif 281 282#ifdef DIAGNOSTIC 283 __os_free(env, logrec.data); 284#else 285 if (is_durable || txnp == NULL) 286 __os_free(env, logrec.data); 287#endif 288 return (ret); 289} 290 291/* 292 * PUBLIC: int __ham_newpage_read __P((ENV *, DB **, void *, void *, 293 * PUBLIC: __ham_newpage_args **)); 294 */ 295int 296__ham_newpage_read(env, dbpp, td, recbuf, argpp) 297 ENV *env; 298 DB **dbpp; 299 void *td; 300 void *recbuf; 301 __ham_newpage_args **argpp; 302{ 303 __ham_newpage_args *argp; 304 u_int32_t uinttmp; 305 u_int8_t *bp; 306 int ret; 307 308 if ((ret = __os_malloc(env, 309 sizeof(__ham_newpage_args) + sizeof(DB_TXN), &argp)) != 0) 310 return (ret); 311 bp = recbuf; 312 argp->txnp = (DB_TXN *)&argp[1]; 313 memset(argp->txnp, 0, sizeof(DB_TXN)); 314 315 argp->txnp->td = td; 316 LOGCOPY_32(env, &argp->type, bp); 317 bp += sizeof(argp->type); 318 319 LOGCOPY_32(env, &argp->txnp->txnid, bp); 320 bp += sizeof(argp->txnp->txnid); 321 322 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 323 bp += sizeof(DB_LSN); 324 325 LOGCOPY_32(env, &argp->opcode, bp); 326 bp += sizeof(argp->opcode); 327 328 LOGCOPY_32(env, &uinttmp, bp); 329 argp->fileid = (int32_t)uinttmp; 330 bp += sizeof(uinttmp); 331 if (dbpp != NULL) { 332 *dbpp = NULL; 333 ret = __dbreg_id_to_db( 334 env, argp->txnp, dbpp, argp->fileid, 1); 335 } 336 337 LOGCOPY_32(env, &uinttmp, bp); 338 argp->prev_pgno = (db_pgno_t)uinttmp; 339 bp += sizeof(uinttmp); 340 341 LOGCOPY_TOLSN(env, &argp->prevlsn, bp); 342 bp += sizeof(DB_LSN); 343 344 LOGCOPY_32(env, &uinttmp, bp); 345 argp->new_pgno = (db_pgno_t)uinttmp; 346 bp += sizeof(uinttmp); 347 348 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 349 bp += sizeof(DB_LSN); 350 351 LOGCOPY_32(env, &uinttmp, bp); 352 argp->next_pgno = (db_pgno_t)uinttmp; 353 bp += sizeof(uinttmp); 354 355 LOGCOPY_TOLSN(env, &argp->nextlsn, bp); 356 bp += sizeof(DB_LSN); 357 358 *argpp = argp; 359 return (ret); 360} 361 362/* 363 * PUBLIC: int __ham_newpage_log __P((DB *, DB_TXN *, DB_LSN *, 364 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, 365 * PUBLIC: db_pgno_t, DB_LSN *)); 366 */ 367int 368__ham_newpage_log(dbp, txnp, ret_lsnp, flags, 369 opcode, prev_pgno, prevlsn, new_pgno, pagelsn, 370 next_pgno, nextlsn) 371 DB *dbp; 372 DB_TXN *txnp; 373 DB_LSN *ret_lsnp; 374 u_int32_t flags; 375 u_int32_t opcode; 376 db_pgno_t prev_pgno; 377 DB_LSN * prevlsn; 378 db_pgno_t new_pgno; 379 DB_LSN * pagelsn; 380 db_pgno_t next_pgno; 381 DB_LSN * nextlsn; 382{ 383 DBT logrec; 384 DB_LSN *lsnp, null_lsn, *rlsnp; 385 DB_TXNLOGREC *lr; 386 ENV *env; 387 u_int32_t uinttmp, rectype, txn_num; 388 u_int npad; 389 u_int8_t *bp; 390 int is_durable, ret; 391 392 COMPQUIET(lr, NULL); 393 394 env = dbp->env; 395 rlsnp = ret_lsnp; 396 rectype = DB___ham_newpage; 397 npad = 0; 398 ret = 0; 399 400 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 401 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 402 if (txnp == NULL) 403 return (0); 404 is_durable = 0; 405 } else 406 is_durable = 1; 407 408 if (txnp == NULL) { 409 txn_num = 0; 410 lsnp = &null_lsn; 411 null_lsn.file = null_lsn.offset = 0; 412 } else { 413 if (TAILQ_FIRST(&txnp->kids) != NULL && 414 (ret = __txn_activekids(env, rectype, txnp)) != 0) 415 return (ret); 416 /* 417 * We need to assign begin_lsn while holding region mutex. 418 * That assignment is done inside the DbEnv->log_put call, 419 * so pass in the appropriate memory location to be filled 420 * in by the log_put code. 421 */ 422 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 423 txn_num = txnp->txnid; 424 } 425 426 DB_ASSERT(env, dbp->log_filename != NULL); 427 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 428 (ret = __dbreg_lazy_id(dbp)) != 0) 429 return (ret); 430 431 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 432 + sizeof(u_int32_t) 433 + sizeof(u_int32_t) 434 + sizeof(u_int32_t) 435 + sizeof(*prevlsn) 436 + sizeof(u_int32_t) 437 + sizeof(*pagelsn) 438 + sizeof(u_int32_t) 439 + sizeof(*nextlsn); 440 if (CRYPTO_ON(env)) { 441 npad = env->crypto_handle->adj_size(logrec.size); 442 logrec.size += npad; 443 } 444 445 if (is_durable || txnp == NULL) { 446 if ((ret = 447 __os_malloc(env, logrec.size, &logrec.data)) != 0) 448 return (ret); 449 } else { 450 if ((ret = __os_malloc(env, 451 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 452 return (ret); 453#ifdef DIAGNOSTIC 454 if ((ret = 455 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 456 __os_free(env, lr); 457 return (ret); 458 } 459#else 460 logrec.data = lr->data; 461#endif 462 } 463 if (npad > 0) 464 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 465 466 bp = logrec.data; 467 468 LOGCOPY_32(env, bp, &rectype); 469 bp += sizeof(rectype); 470 471 LOGCOPY_32(env, bp, &txn_num); 472 bp += sizeof(txn_num); 473 474 LOGCOPY_FROMLSN(env, bp, lsnp); 475 bp += sizeof(DB_LSN); 476 477 LOGCOPY_32(env, bp, &opcode); 478 bp += sizeof(opcode); 479 480 uinttmp = (u_int32_t)dbp->log_filename->id; 481 LOGCOPY_32(env, bp, &uinttmp); 482 bp += sizeof(uinttmp); 483 484 uinttmp = (u_int32_t)prev_pgno; 485 LOGCOPY_32(env,bp, &uinttmp); 486 bp += sizeof(uinttmp); 487 488 if (prevlsn != NULL) { 489 if (txnp != NULL) { 490 LOG *lp = env->lg_handle->reginfo.primary; 491 if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = 492 __log_check_page_lsn(env, dbp, prevlsn) != 0)) 493 return (ret); 494 } 495 LOGCOPY_FROMLSN(env, bp, prevlsn); 496 } else 497 memset(bp, 0, sizeof(*prevlsn)); 498 bp += sizeof(*prevlsn); 499 500 uinttmp = (u_int32_t)new_pgno; 501 LOGCOPY_32(env,bp, &uinttmp); 502 bp += sizeof(uinttmp); 503 504 if (pagelsn != NULL) { 505 if (txnp != NULL) { 506 LOG *lp = env->lg_handle->reginfo.primary; 507 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 508 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 509 return (ret); 510 } 511 LOGCOPY_FROMLSN(env, bp, pagelsn); 512 } else 513 memset(bp, 0, sizeof(*pagelsn)); 514 bp += sizeof(*pagelsn); 515 516 uinttmp = (u_int32_t)next_pgno; 517 LOGCOPY_32(env,bp, &uinttmp); 518 bp += sizeof(uinttmp); 519 520 if (nextlsn != NULL) { 521 if (txnp != NULL) { 522 LOG *lp = env->lg_handle->reginfo.primary; 523 if (LOG_COMPARE(nextlsn, &lp->lsn) >= 0 && (ret = 524 __log_check_page_lsn(env, dbp, nextlsn) != 0)) 525 return (ret); 526 } 527 LOGCOPY_FROMLSN(env, bp, nextlsn); 528 } else 529 memset(bp, 0, sizeof(*nextlsn)); 530 bp += sizeof(*nextlsn); 531 532 DB_ASSERT(env, 533 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 534 535 if (is_durable || txnp == NULL) { 536 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 537 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 538 *lsnp = *rlsnp; 539 if (rlsnp != ret_lsnp) 540 *ret_lsnp = *rlsnp; 541 } 542 } else { 543 ret = 0; 544#ifdef DIAGNOSTIC 545 /* 546 * Set the debug bit if we are going to log non-durable 547 * transactions so they will be ignored by recovery. 548 */ 549 memcpy(lr->data, logrec.data, logrec.size); 550 rectype |= DB_debug_FLAG; 551 LOGCOPY_32(env, logrec.data, &rectype); 552 553 if (!IS_REP_CLIENT(env)) 554 ret = __log_put(env, 555 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 556#endif 557 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 558 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 559 LSN_NOT_LOGGED(*ret_lsnp); 560 } 561 562#ifdef LOG_DIAGNOSTIC 563 if (ret != 0) 564 (void)__ham_newpage_print(env, 565 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 566#endif 567 568#ifdef DIAGNOSTIC 569 __os_free(env, logrec.data); 570#else 571 if (is_durable || txnp == NULL) 572 __os_free(env, logrec.data); 573#endif 574 return (ret); 575} 576 577/* 578 * PUBLIC: int __ham_splitdata_read __P((ENV *, DB **, void *, 579 * PUBLIC: void *, __ham_splitdata_args **)); 580 */ 581int 582__ham_splitdata_read(env, dbpp, td, recbuf, argpp) 583 ENV *env; 584 DB **dbpp; 585 void *td; 586 void *recbuf; 587 __ham_splitdata_args **argpp; 588{ 589 __ham_splitdata_args *argp; 590 u_int32_t uinttmp; 591 u_int8_t *bp; 592 int ret; 593 594 if ((ret = __os_malloc(env, 595 sizeof(__ham_splitdata_args) + sizeof(DB_TXN), &argp)) != 0) 596 return (ret); 597 bp = recbuf; 598 argp->txnp = (DB_TXN *)&argp[1]; 599 memset(argp->txnp, 0, sizeof(DB_TXN)); 600 601 argp->txnp->td = td; 602 LOGCOPY_32(env, &argp->type, bp); 603 bp += sizeof(argp->type); 604 605 LOGCOPY_32(env, &argp->txnp->txnid, bp); 606 bp += sizeof(argp->txnp->txnid); 607 608 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 609 bp += sizeof(DB_LSN); 610 611 LOGCOPY_32(env, &uinttmp, bp); 612 argp->fileid = (int32_t)uinttmp; 613 bp += sizeof(uinttmp); 614 if (dbpp != NULL) { 615 *dbpp = NULL; 616 ret = __dbreg_id_to_db( 617 env, argp->txnp, dbpp, argp->fileid, 1); 618 } 619 620 LOGCOPY_32(env, &argp->opcode, bp); 621 bp += sizeof(argp->opcode); 622 623 LOGCOPY_32(env, &uinttmp, bp); 624 argp->pgno = (db_pgno_t)uinttmp; 625 bp += sizeof(uinttmp); 626 627 memset(&argp->pageimage, 0, sizeof(argp->pageimage)); 628 LOGCOPY_32(env,&argp->pageimage.size, bp); 629 bp += sizeof(u_int32_t); 630 argp->pageimage.data = bp; 631 bp += argp->pageimage.size; 632 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 633 int t_ret; 634 if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->pageimage.data, 635 (size_t)argp->pageimage.size, NULL, 1)) != 0) 636 return (t_ret); 637 } 638 639 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 640 bp += sizeof(DB_LSN); 641 642 *argpp = argp; 643 return (ret); 644} 645 646/* 647 * PUBLIC: int __ham_splitdata_log __P((DB *, DB_TXN *, DB_LSN *, 648 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, const DBT *, DB_LSN *)); 649 */ 650int 651__ham_splitdata_log(dbp, txnp, ret_lsnp, flags, opcode, pgno, pageimage, pagelsn) 652 DB *dbp; 653 DB_TXN *txnp; 654 DB_LSN *ret_lsnp; 655 u_int32_t flags; 656 u_int32_t opcode; 657 db_pgno_t pgno; 658 const DBT *pageimage; 659 DB_LSN * pagelsn; 660{ 661 DBT logrec; 662 DB_LSN *lsnp, null_lsn, *rlsnp; 663 DB_TXNLOGREC *lr; 664 ENV *env; 665 u_int32_t zero, uinttmp, rectype, txn_num; 666 u_int npad; 667 u_int8_t *bp; 668 int is_durable, ret; 669 670 COMPQUIET(lr, NULL); 671 672 env = dbp->env; 673 rlsnp = ret_lsnp; 674 rectype = DB___ham_splitdata; 675 npad = 0; 676 ret = 0; 677 678 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 679 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 680 if (txnp == NULL) 681 return (0); 682 is_durable = 0; 683 } else 684 is_durable = 1; 685 686 if (txnp == NULL) { 687 txn_num = 0; 688 lsnp = &null_lsn; 689 null_lsn.file = null_lsn.offset = 0; 690 } else { 691 if (TAILQ_FIRST(&txnp->kids) != NULL && 692 (ret = __txn_activekids(env, rectype, txnp)) != 0) 693 return (ret); 694 /* 695 * We need to assign begin_lsn while holding region mutex. 696 * That assignment is done inside the DbEnv->log_put call, 697 * so pass in the appropriate memory location to be filled 698 * in by the log_put code. 699 */ 700 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 701 txn_num = txnp->txnid; 702 } 703 704 DB_ASSERT(env, dbp->log_filename != NULL); 705 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 706 (ret = __dbreg_lazy_id(dbp)) != 0) 707 return (ret); 708 709 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 710 + sizeof(u_int32_t) 711 + sizeof(u_int32_t) 712 + sizeof(u_int32_t) 713 + sizeof(u_int32_t) + (pageimage == NULL ? 0 : pageimage->size) 714 + sizeof(*pagelsn); 715 if (CRYPTO_ON(env)) { 716 npad = env->crypto_handle->adj_size(logrec.size); 717 logrec.size += npad; 718 } 719 720 if (is_durable || txnp == NULL) { 721 if ((ret = 722 __os_malloc(env, logrec.size, &logrec.data)) != 0) 723 return (ret); 724 } else { 725 if ((ret = __os_malloc(env, 726 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 727 return (ret); 728#ifdef DIAGNOSTIC 729 if ((ret = 730 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 731 __os_free(env, lr); 732 return (ret); 733 } 734#else 735 logrec.data = lr->data; 736#endif 737 } 738 if (npad > 0) 739 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 740 741 bp = logrec.data; 742 743 LOGCOPY_32(env, bp, &rectype); 744 bp += sizeof(rectype); 745 746 LOGCOPY_32(env, bp, &txn_num); 747 bp += sizeof(txn_num); 748 749 LOGCOPY_FROMLSN(env, bp, lsnp); 750 bp += sizeof(DB_LSN); 751 752 uinttmp = (u_int32_t)dbp->log_filename->id; 753 LOGCOPY_32(env, bp, &uinttmp); 754 bp += sizeof(uinttmp); 755 756 LOGCOPY_32(env, bp, &opcode); 757 bp += sizeof(opcode); 758 759 uinttmp = (u_int32_t)pgno; 760 LOGCOPY_32(env,bp, &uinttmp); 761 bp += sizeof(uinttmp); 762 763 if (pageimage == NULL) { 764 zero = 0; 765 LOGCOPY_32(env, bp, &zero); 766 bp += sizeof(u_int32_t); 767 } else { 768 LOGCOPY_32(env, bp, &pageimage->size); 769 bp += sizeof(pageimage->size); 770 memcpy(bp, pageimage->data, pageimage->size); 771 if (LOG_SWAPPED(env)) 772 if ((ret = __db_pageswap(dbp, 773 (PAGE *)bp, (size_t)pageimage->size, (DBT *)NULL, 0)) != 0) 774 return (ret); 775 bp += pageimage->size; 776 } 777 778 if (pagelsn != NULL) { 779 if (txnp != NULL) { 780 LOG *lp = env->lg_handle->reginfo.primary; 781 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 782 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 783 return (ret); 784 } 785 LOGCOPY_FROMLSN(env, bp, pagelsn); 786 } else 787 memset(bp, 0, sizeof(*pagelsn)); 788 bp += sizeof(*pagelsn); 789 790 DB_ASSERT(env, 791 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 792 793 if (is_durable || txnp == NULL) { 794 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 795 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 796 *lsnp = *rlsnp; 797 if (rlsnp != ret_lsnp) 798 *ret_lsnp = *rlsnp; 799 } 800 } else { 801 ret = 0; 802#ifdef DIAGNOSTIC 803 /* 804 * Set the debug bit if we are going to log non-durable 805 * transactions so they will be ignored by recovery. 806 */ 807 memcpy(lr->data, logrec.data, logrec.size); 808 rectype |= DB_debug_FLAG; 809 LOGCOPY_32(env, logrec.data, &rectype); 810 811 if (!IS_REP_CLIENT(env)) 812 ret = __log_put(env, 813 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 814#endif 815 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 816 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 817 LSN_NOT_LOGGED(*ret_lsnp); 818 } 819 820#ifdef LOG_DIAGNOSTIC 821 if (ret != 0) 822 (void)__ham_splitdata_print(env, 823 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 824#endif 825 826#ifdef DIAGNOSTIC 827 __os_free(env, logrec.data); 828#else 829 if (is_durable || txnp == NULL) 830 __os_free(env, logrec.data); 831#endif 832 return (ret); 833} 834 835/* 836 * PUBLIC: int __ham_replace_read __P((ENV *, DB **, void *, void *, 837 * PUBLIC: __ham_replace_args **)); 838 */ 839int 840__ham_replace_read(env, dbpp, td, recbuf, argpp) 841 ENV *env; 842 DB **dbpp; 843 void *td; 844 void *recbuf; 845 __ham_replace_args **argpp; 846{ 847 __ham_replace_args *argp; 848 u_int32_t uinttmp; 849 u_int8_t *bp; 850 int ret; 851 852 if ((ret = __os_malloc(env, 853 sizeof(__ham_replace_args) + sizeof(DB_TXN), &argp)) != 0) 854 return (ret); 855 bp = recbuf; 856 argp->txnp = (DB_TXN *)&argp[1]; 857 memset(argp->txnp, 0, sizeof(DB_TXN)); 858 859 argp->txnp->td = td; 860 LOGCOPY_32(env, &argp->type, bp); 861 bp += sizeof(argp->type); 862 863 LOGCOPY_32(env, &argp->txnp->txnid, bp); 864 bp += sizeof(argp->txnp->txnid); 865 866 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 867 bp += sizeof(DB_LSN); 868 869 LOGCOPY_32(env, &uinttmp, bp); 870 argp->fileid = (int32_t)uinttmp; 871 bp += sizeof(uinttmp); 872 if (dbpp != NULL) { 873 *dbpp = NULL; 874 ret = __dbreg_id_to_db( 875 env, argp->txnp, dbpp, argp->fileid, 1); 876 } 877 878 LOGCOPY_32(env, &uinttmp, bp); 879 argp->pgno = (db_pgno_t)uinttmp; 880 bp += sizeof(uinttmp); 881 882 LOGCOPY_32(env, &argp->ndx, bp); 883 bp += sizeof(argp->ndx); 884 885 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 886 bp += sizeof(DB_LSN); 887 888 LOGCOPY_32(env, &uinttmp, bp); 889 argp->off = (int32_t)uinttmp; 890 bp += sizeof(uinttmp); 891 892 memset(&argp->olditem, 0, sizeof(argp->olditem)); 893 LOGCOPY_32(env,&argp->olditem.size, bp); 894 bp += sizeof(u_int32_t); 895 argp->olditem.data = bp; 896 bp += argp->olditem.size; 897 898 memset(&argp->newitem, 0, sizeof(argp->newitem)); 899 LOGCOPY_32(env,&argp->newitem.size, bp); 900 bp += sizeof(u_int32_t); 901 argp->newitem.data = bp; 902 bp += argp->newitem.size; 903 904 LOGCOPY_32(env, &argp->makedup, bp); 905 bp += sizeof(argp->makedup); 906 907 *argpp = argp; 908 return (ret); 909} 910 911/* 912 * PUBLIC: int __ham_replace_log __P((DB *, DB_TXN *, DB_LSN *, 913 * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, DB_LSN *, int32_t, const DBT *, 914 * PUBLIC: const DBT *, u_int32_t)); 915 */ 916int 917__ham_replace_log(dbp, txnp, ret_lsnp, flags, pgno, ndx, pagelsn, off, olditem, 918 newitem, makedup) 919 DB *dbp; 920 DB_TXN *txnp; 921 DB_LSN *ret_lsnp; 922 u_int32_t flags; 923 db_pgno_t pgno; 924 u_int32_t ndx; 925 DB_LSN * pagelsn; 926 int32_t off; 927 const DBT *olditem; 928 const DBT *newitem; 929 u_int32_t makedup; 930{ 931 DBT logrec; 932 DB_LSN *lsnp, null_lsn, *rlsnp; 933 DB_TXNLOGREC *lr; 934 ENV *env; 935 u_int32_t zero, uinttmp, rectype, txn_num; 936 u_int npad; 937 u_int8_t *bp; 938 int is_durable, ret; 939 940 COMPQUIET(lr, NULL); 941 942 env = dbp->env; 943 rlsnp = ret_lsnp; 944 rectype = DB___ham_replace; 945 npad = 0; 946 ret = 0; 947 948 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 949 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 950 if (txnp == NULL) 951 return (0); 952 is_durable = 0; 953 } else 954 is_durable = 1; 955 956 if (txnp == NULL) { 957 txn_num = 0; 958 lsnp = &null_lsn; 959 null_lsn.file = null_lsn.offset = 0; 960 } else { 961 if (TAILQ_FIRST(&txnp->kids) != NULL && 962 (ret = __txn_activekids(env, rectype, txnp)) != 0) 963 return (ret); 964 /* 965 * We need to assign begin_lsn while holding region mutex. 966 * That assignment is done inside the DbEnv->log_put call, 967 * so pass in the appropriate memory location to be filled 968 * in by the log_put code. 969 */ 970 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 971 txn_num = txnp->txnid; 972 } 973 974 DB_ASSERT(env, dbp->log_filename != NULL); 975 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 976 (ret = __dbreg_lazy_id(dbp)) != 0) 977 return (ret); 978 979 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 980 + sizeof(u_int32_t) 981 + sizeof(u_int32_t) 982 + sizeof(u_int32_t) 983 + sizeof(*pagelsn) 984 + sizeof(u_int32_t) 985 + sizeof(u_int32_t) + (olditem == NULL ? 0 : olditem->size) 986 + sizeof(u_int32_t) + (newitem == NULL ? 0 : newitem->size) 987 + sizeof(u_int32_t); 988 if (CRYPTO_ON(env)) { 989 npad = env->crypto_handle->adj_size(logrec.size); 990 logrec.size += npad; 991 } 992 993 if (is_durable || txnp == NULL) { 994 if ((ret = 995 __os_malloc(env, logrec.size, &logrec.data)) != 0) 996 return (ret); 997 } else { 998 if ((ret = __os_malloc(env, 999 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1000 return (ret); 1001#ifdef DIAGNOSTIC 1002 if ((ret = 1003 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1004 __os_free(env, lr); 1005 return (ret); 1006 } 1007#else 1008 logrec.data = lr->data; 1009#endif 1010 } 1011 if (npad > 0) 1012 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1013 1014 bp = logrec.data; 1015 1016 LOGCOPY_32(env, bp, &rectype); 1017 bp += sizeof(rectype); 1018 1019 LOGCOPY_32(env, bp, &txn_num); 1020 bp += sizeof(txn_num); 1021 1022 LOGCOPY_FROMLSN(env, bp, lsnp); 1023 bp += sizeof(DB_LSN); 1024 1025 uinttmp = (u_int32_t)dbp->log_filename->id; 1026 LOGCOPY_32(env, bp, &uinttmp); 1027 bp += sizeof(uinttmp); 1028 1029 uinttmp = (u_int32_t)pgno; 1030 LOGCOPY_32(env,bp, &uinttmp); 1031 bp += sizeof(uinttmp); 1032 1033 LOGCOPY_32(env, bp, &ndx); 1034 bp += sizeof(ndx); 1035 1036 if (pagelsn != NULL) { 1037 if (txnp != NULL) { 1038 LOG *lp = env->lg_handle->reginfo.primary; 1039 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 1040 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 1041 return (ret); 1042 } 1043 LOGCOPY_FROMLSN(env, bp, pagelsn); 1044 } else 1045 memset(bp, 0, sizeof(*pagelsn)); 1046 bp += sizeof(*pagelsn); 1047 1048 uinttmp = (u_int32_t)off; 1049 LOGCOPY_32(env,bp, &uinttmp); 1050 bp += sizeof(uinttmp); 1051 1052 if (olditem == NULL) { 1053 zero = 0; 1054 LOGCOPY_32(env, bp, &zero); 1055 bp += sizeof(u_int32_t); 1056 } else { 1057 LOGCOPY_32(env, bp, &olditem->size); 1058 bp += sizeof(olditem->size); 1059 memcpy(bp, olditem->data, olditem->size); 1060 bp += olditem->size; 1061 } 1062 1063 if (newitem == NULL) { 1064 zero = 0; 1065 LOGCOPY_32(env, bp, &zero); 1066 bp += sizeof(u_int32_t); 1067 } else { 1068 LOGCOPY_32(env, bp, &newitem->size); 1069 bp += sizeof(newitem->size); 1070 memcpy(bp, newitem->data, newitem->size); 1071 bp += newitem->size; 1072 } 1073 1074 LOGCOPY_32(env, bp, &makedup); 1075 bp += sizeof(makedup); 1076 1077 DB_ASSERT(env, 1078 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1079 1080 if (is_durable || txnp == NULL) { 1081 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1082 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1083 *lsnp = *rlsnp; 1084 if (rlsnp != ret_lsnp) 1085 *ret_lsnp = *rlsnp; 1086 } 1087 } else { 1088 ret = 0; 1089#ifdef DIAGNOSTIC 1090 /* 1091 * Set the debug bit if we are going to log non-durable 1092 * transactions so they will be ignored by recovery. 1093 */ 1094 memcpy(lr->data, logrec.data, logrec.size); 1095 rectype |= DB_debug_FLAG; 1096 LOGCOPY_32(env, logrec.data, &rectype); 1097 1098 if (!IS_REP_CLIENT(env)) 1099 ret = __log_put(env, 1100 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1101#endif 1102 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1103 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1104 LSN_NOT_LOGGED(*ret_lsnp); 1105 } 1106 1107#ifdef LOG_DIAGNOSTIC 1108 if (ret != 0) 1109 (void)__ham_replace_print(env, 1110 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1111#endif 1112 1113#ifdef DIAGNOSTIC 1114 __os_free(env, logrec.data); 1115#else 1116 if (is_durable || txnp == NULL) 1117 __os_free(env, logrec.data); 1118#endif 1119 return (ret); 1120} 1121 1122/* 1123 * PUBLIC: int __ham_copypage_read __P((ENV *, DB **, void *, 1124 * PUBLIC: void *, __ham_copypage_args **)); 1125 */ 1126int 1127__ham_copypage_read(env, dbpp, td, recbuf, argpp) 1128 ENV *env; 1129 DB **dbpp; 1130 void *td; 1131 void *recbuf; 1132 __ham_copypage_args **argpp; 1133{ 1134 __ham_copypage_args *argp; 1135 u_int32_t uinttmp; 1136 u_int8_t *bp; 1137 int ret; 1138 1139 if ((ret = __os_malloc(env, 1140 sizeof(__ham_copypage_args) + sizeof(DB_TXN), &argp)) != 0) 1141 return (ret); 1142 bp = recbuf; 1143 argp->txnp = (DB_TXN *)&argp[1]; 1144 memset(argp->txnp, 0, sizeof(DB_TXN)); 1145 1146 argp->txnp->td = td; 1147 LOGCOPY_32(env, &argp->type, bp); 1148 bp += sizeof(argp->type); 1149 1150 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1151 bp += sizeof(argp->txnp->txnid); 1152 1153 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1154 bp += sizeof(DB_LSN); 1155 1156 LOGCOPY_32(env, &uinttmp, bp); 1157 argp->fileid = (int32_t)uinttmp; 1158 bp += sizeof(uinttmp); 1159 if (dbpp != NULL) { 1160 *dbpp = NULL; 1161 ret = __dbreg_id_to_db( 1162 env, argp->txnp, dbpp, argp->fileid, 1); 1163 } 1164 1165 LOGCOPY_32(env, &uinttmp, bp); 1166 argp->pgno = (db_pgno_t)uinttmp; 1167 bp += sizeof(uinttmp); 1168 1169 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 1170 bp += sizeof(DB_LSN); 1171 1172 LOGCOPY_32(env, &uinttmp, bp); 1173 argp->next_pgno = (db_pgno_t)uinttmp; 1174 bp += sizeof(uinttmp); 1175 1176 LOGCOPY_TOLSN(env, &argp->nextlsn, bp); 1177 bp += sizeof(DB_LSN); 1178 1179 LOGCOPY_32(env, &uinttmp, bp); 1180 argp->nnext_pgno = (db_pgno_t)uinttmp; 1181 bp += sizeof(uinttmp); 1182 1183 LOGCOPY_TOLSN(env, &argp->nnextlsn, bp); 1184 bp += sizeof(DB_LSN); 1185 1186 memset(&argp->page, 0, sizeof(argp->page)); 1187 LOGCOPY_32(env,&argp->page.size, bp); 1188 bp += sizeof(u_int32_t); 1189 argp->page.data = bp; 1190 bp += argp->page.size; 1191 if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { 1192 int t_ret; 1193 if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->page.data, 1194 (size_t)argp->page.size, NULL, 1)) != 0) 1195 return (t_ret); 1196 } 1197 1198 *argpp = argp; 1199 return (ret); 1200} 1201 1202/* 1203 * PUBLIC: int __ham_copypage_log __P((DB *, DB_TXN *, DB_LSN *, 1204 * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, 1205 * PUBLIC: DB_LSN *, const DBT *)); 1206 */ 1207int 1208__ham_copypage_log(dbp, txnp, ret_lsnp, flags, pgno, pagelsn, next_pgno, nextlsn, nnext_pgno, 1209 nnextlsn, page) 1210 DB *dbp; 1211 DB_TXN *txnp; 1212 DB_LSN *ret_lsnp; 1213 u_int32_t flags; 1214 db_pgno_t pgno; 1215 DB_LSN * pagelsn; 1216 db_pgno_t next_pgno; 1217 DB_LSN * nextlsn; 1218 db_pgno_t nnext_pgno; 1219 DB_LSN * nnextlsn; 1220 const DBT *page; 1221{ 1222 DBT logrec; 1223 DB_LSN *lsnp, null_lsn, *rlsnp; 1224 DB_TXNLOGREC *lr; 1225 ENV *env; 1226 u_int32_t zero, uinttmp, rectype, txn_num; 1227 u_int npad; 1228 u_int8_t *bp; 1229 int is_durable, ret; 1230 1231 COMPQUIET(lr, NULL); 1232 1233 env = dbp->env; 1234 rlsnp = ret_lsnp; 1235 rectype = DB___ham_copypage; 1236 npad = 0; 1237 ret = 0; 1238 1239 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1240 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1241 if (txnp == NULL) 1242 return (0); 1243 is_durable = 0; 1244 } else 1245 is_durable = 1; 1246 1247 if (txnp == NULL) { 1248 txn_num = 0; 1249 lsnp = &null_lsn; 1250 null_lsn.file = null_lsn.offset = 0; 1251 } else { 1252 if (TAILQ_FIRST(&txnp->kids) != NULL && 1253 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1254 return (ret); 1255 /* 1256 * We need to assign begin_lsn while holding region mutex. 1257 * That assignment is done inside the DbEnv->log_put call, 1258 * so pass in the appropriate memory location to be filled 1259 * in by the log_put code. 1260 */ 1261 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1262 txn_num = txnp->txnid; 1263 } 1264 1265 DB_ASSERT(env, dbp->log_filename != NULL); 1266 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1267 (ret = __dbreg_lazy_id(dbp)) != 0) 1268 return (ret); 1269 1270 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1271 + sizeof(u_int32_t) 1272 + sizeof(u_int32_t) 1273 + sizeof(*pagelsn) 1274 + sizeof(u_int32_t) 1275 + sizeof(*nextlsn) 1276 + sizeof(u_int32_t) 1277 + sizeof(*nnextlsn) 1278 + sizeof(u_int32_t) + (page == NULL ? 0 : page->size); 1279 if (CRYPTO_ON(env)) { 1280 npad = env->crypto_handle->adj_size(logrec.size); 1281 logrec.size += npad; 1282 } 1283 1284 if (is_durable || txnp == NULL) { 1285 if ((ret = 1286 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1287 return (ret); 1288 } else { 1289 if ((ret = __os_malloc(env, 1290 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1291 return (ret); 1292#ifdef DIAGNOSTIC 1293 if ((ret = 1294 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1295 __os_free(env, lr); 1296 return (ret); 1297 } 1298#else 1299 logrec.data = lr->data; 1300#endif 1301 } 1302 if (npad > 0) 1303 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1304 1305 bp = logrec.data; 1306 1307 LOGCOPY_32(env, bp, &rectype); 1308 bp += sizeof(rectype); 1309 1310 LOGCOPY_32(env, bp, &txn_num); 1311 bp += sizeof(txn_num); 1312 1313 LOGCOPY_FROMLSN(env, bp, lsnp); 1314 bp += sizeof(DB_LSN); 1315 1316 uinttmp = (u_int32_t)dbp->log_filename->id; 1317 LOGCOPY_32(env, bp, &uinttmp); 1318 bp += sizeof(uinttmp); 1319 1320 uinttmp = (u_int32_t)pgno; 1321 LOGCOPY_32(env,bp, &uinttmp); 1322 bp += sizeof(uinttmp); 1323 1324 if (pagelsn != NULL) { 1325 if (txnp != NULL) { 1326 LOG *lp = env->lg_handle->reginfo.primary; 1327 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 1328 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 1329 return (ret); 1330 } 1331 LOGCOPY_FROMLSN(env, bp, pagelsn); 1332 } else 1333 memset(bp, 0, sizeof(*pagelsn)); 1334 bp += sizeof(*pagelsn); 1335 1336 uinttmp = (u_int32_t)next_pgno; 1337 LOGCOPY_32(env,bp, &uinttmp); 1338 bp += sizeof(uinttmp); 1339 1340 if (nextlsn != NULL) { 1341 if (txnp != NULL) { 1342 LOG *lp = env->lg_handle->reginfo.primary; 1343 if (LOG_COMPARE(nextlsn, &lp->lsn) >= 0 && (ret = 1344 __log_check_page_lsn(env, dbp, nextlsn) != 0)) 1345 return (ret); 1346 } 1347 LOGCOPY_FROMLSN(env, bp, nextlsn); 1348 } else 1349 memset(bp, 0, sizeof(*nextlsn)); 1350 bp += sizeof(*nextlsn); 1351 1352 uinttmp = (u_int32_t)nnext_pgno; 1353 LOGCOPY_32(env,bp, &uinttmp); 1354 bp += sizeof(uinttmp); 1355 1356 if (nnextlsn != NULL) { 1357 if (txnp != NULL) { 1358 LOG *lp = env->lg_handle->reginfo.primary; 1359 if (LOG_COMPARE(nnextlsn, &lp->lsn) >= 0 && (ret = 1360 __log_check_page_lsn(env, dbp, nnextlsn) != 0)) 1361 return (ret); 1362 } 1363 LOGCOPY_FROMLSN(env, bp, nnextlsn); 1364 } else 1365 memset(bp, 0, sizeof(*nnextlsn)); 1366 bp += sizeof(*nnextlsn); 1367 1368 if (page == NULL) { 1369 zero = 0; 1370 LOGCOPY_32(env, bp, &zero); 1371 bp += sizeof(u_int32_t); 1372 } else { 1373 LOGCOPY_32(env, bp, &page->size); 1374 bp += sizeof(page->size); 1375 memcpy(bp, page->data, page->size); 1376 if (LOG_SWAPPED(env)) 1377 if ((ret = __db_pageswap(dbp, 1378 (PAGE *)bp, (size_t)page->size, (DBT *)NULL, 0)) != 0) 1379 return (ret); 1380 bp += page->size; 1381 } 1382 1383 DB_ASSERT(env, 1384 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1385 1386 if (is_durable || txnp == NULL) { 1387 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1388 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1389 *lsnp = *rlsnp; 1390 if (rlsnp != ret_lsnp) 1391 *ret_lsnp = *rlsnp; 1392 } 1393 } else { 1394 ret = 0; 1395#ifdef DIAGNOSTIC 1396 /* 1397 * Set the debug bit if we are going to log non-durable 1398 * transactions so they will be ignored by recovery. 1399 */ 1400 memcpy(lr->data, logrec.data, logrec.size); 1401 rectype |= DB_debug_FLAG; 1402 LOGCOPY_32(env, logrec.data, &rectype); 1403 1404 if (!IS_REP_CLIENT(env)) 1405 ret = __log_put(env, 1406 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1407#endif 1408 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1409 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1410 LSN_NOT_LOGGED(*ret_lsnp); 1411 } 1412 1413#ifdef LOG_DIAGNOSTIC 1414 if (ret != 0) 1415 (void)__ham_copypage_print(env, 1416 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1417#endif 1418 1419#ifdef DIAGNOSTIC 1420 __os_free(env, logrec.data); 1421#else 1422 if (is_durable || txnp == NULL) 1423 __os_free(env, logrec.data); 1424#endif 1425 return (ret); 1426} 1427 1428/* 1429 * PUBLIC: int __ham_metagroup_42_read __P((ENV *, DB **, void *, 1430 * PUBLIC: void *, __ham_metagroup_42_args **)); 1431 */ 1432int 1433__ham_metagroup_42_read(env, dbpp, td, recbuf, argpp) 1434 ENV *env; 1435 DB **dbpp; 1436 void *td; 1437 void *recbuf; 1438 __ham_metagroup_42_args **argpp; 1439{ 1440 __ham_metagroup_42_args *argp; 1441 u_int32_t uinttmp; 1442 u_int8_t *bp; 1443 int ret; 1444 1445 if ((ret = __os_malloc(env, 1446 sizeof(__ham_metagroup_42_args) + sizeof(DB_TXN), &argp)) != 0) 1447 return (ret); 1448 bp = recbuf; 1449 argp->txnp = (DB_TXN *)&argp[1]; 1450 memset(argp->txnp, 0, sizeof(DB_TXN)); 1451 1452 argp->txnp->td = td; 1453 LOGCOPY_32(env, &argp->type, bp); 1454 bp += sizeof(argp->type); 1455 1456 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1457 bp += sizeof(argp->txnp->txnid); 1458 1459 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1460 bp += sizeof(DB_LSN); 1461 1462 LOGCOPY_32(env, &uinttmp, bp); 1463 argp->fileid = (int32_t)uinttmp; 1464 bp += sizeof(uinttmp); 1465 if (dbpp != NULL) { 1466 *dbpp = NULL; 1467 ret = __dbreg_id_to_db( 1468 env, argp->txnp, dbpp, argp->fileid, 1); 1469 } 1470 1471 LOGCOPY_32(env, &argp->bucket, bp); 1472 bp += sizeof(argp->bucket); 1473 1474 LOGCOPY_32(env, &uinttmp, bp); 1475 argp->mmpgno = (db_pgno_t)uinttmp; 1476 bp += sizeof(uinttmp); 1477 1478 LOGCOPY_TOLSN(env, &argp->mmetalsn, bp); 1479 bp += sizeof(DB_LSN); 1480 1481 LOGCOPY_32(env, &uinttmp, bp); 1482 argp->mpgno = (db_pgno_t)uinttmp; 1483 bp += sizeof(uinttmp); 1484 1485 LOGCOPY_TOLSN(env, &argp->metalsn, bp); 1486 bp += sizeof(DB_LSN); 1487 1488 LOGCOPY_32(env, &uinttmp, bp); 1489 argp->pgno = (db_pgno_t)uinttmp; 1490 bp += sizeof(uinttmp); 1491 1492 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 1493 bp += sizeof(DB_LSN); 1494 1495 LOGCOPY_32(env, &argp->newalloc, bp); 1496 bp += sizeof(argp->newalloc); 1497 1498 *argpp = argp; 1499 return (ret); 1500} 1501 1502/* 1503 * PUBLIC: int __ham_metagroup_read __P((ENV *, DB **, void *, 1504 * PUBLIC: void *, __ham_metagroup_args **)); 1505 */ 1506int 1507__ham_metagroup_read(env, dbpp, td, recbuf, argpp) 1508 ENV *env; 1509 DB **dbpp; 1510 void *td; 1511 void *recbuf; 1512 __ham_metagroup_args **argpp; 1513{ 1514 __ham_metagroup_args *argp; 1515 u_int32_t uinttmp; 1516 u_int8_t *bp; 1517 int ret; 1518 1519 if ((ret = __os_malloc(env, 1520 sizeof(__ham_metagroup_args) + sizeof(DB_TXN), &argp)) != 0) 1521 return (ret); 1522 bp = recbuf; 1523 argp->txnp = (DB_TXN *)&argp[1]; 1524 memset(argp->txnp, 0, sizeof(DB_TXN)); 1525 1526 argp->txnp->td = td; 1527 LOGCOPY_32(env, &argp->type, bp); 1528 bp += sizeof(argp->type); 1529 1530 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1531 bp += sizeof(argp->txnp->txnid); 1532 1533 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1534 bp += sizeof(DB_LSN); 1535 1536 LOGCOPY_32(env, &uinttmp, bp); 1537 argp->fileid = (int32_t)uinttmp; 1538 bp += sizeof(uinttmp); 1539 if (dbpp != NULL) { 1540 *dbpp = NULL; 1541 ret = __dbreg_id_to_db( 1542 env, argp->txnp, dbpp, argp->fileid, 1); 1543 } 1544 1545 LOGCOPY_32(env, &argp->bucket, bp); 1546 bp += sizeof(argp->bucket); 1547 1548 LOGCOPY_32(env, &uinttmp, bp); 1549 argp->mmpgno = (db_pgno_t)uinttmp; 1550 bp += sizeof(uinttmp); 1551 1552 LOGCOPY_TOLSN(env, &argp->mmetalsn, bp); 1553 bp += sizeof(DB_LSN); 1554 1555 LOGCOPY_32(env, &uinttmp, bp); 1556 argp->mpgno = (db_pgno_t)uinttmp; 1557 bp += sizeof(uinttmp); 1558 1559 LOGCOPY_TOLSN(env, &argp->metalsn, bp); 1560 bp += sizeof(DB_LSN); 1561 1562 LOGCOPY_32(env, &uinttmp, bp); 1563 argp->pgno = (db_pgno_t)uinttmp; 1564 bp += sizeof(uinttmp); 1565 1566 LOGCOPY_TOLSN(env, &argp->pagelsn, bp); 1567 bp += sizeof(DB_LSN); 1568 1569 LOGCOPY_32(env, &argp->newalloc, bp); 1570 bp += sizeof(argp->newalloc); 1571 1572 LOGCOPY_32(env, &uinttmp, bp); 1573 argp->last_pgno = (db_pgno_t)uinttmp; 1574 bp += sizeof(uinttmp); 1575 1576 *argpp = argp; 1577 return (ret); 1578} 1579 1580/* 1581 * PUBLIC: int __ham_metagroup_log __P((DB *, DB_TXN *, DB_LSN *, 1582 * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, 1583 * PUBLIC: db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t)); 1584 */ 1585int 1586__ham_metagroup_log(dbp, txnp, ret_lsnp, flags, bucket, mmpgno, mmetalsn, mpgno, metalsn, 1587 pgno, pagelsn, newalloc, last_pgno) 1588 DB *dbp; 1589 DB_TXN *txnp; 1590 DB_LSN *ret_lsnp; 1591 u_int32_t flags; 1592 u_int32_t bucket; 1593 db_pgno_t mmpgno; 1594 DB_LSN * mmetalsn; 1595 db_pgno_t mpgno; 1596 DB_LSN * metalsn; 1597 db_pgno_t pgno; 1598 DB_LSN * pagelsn; 1599 u_int32_t newalloc; 1600 db_pgno_t last_pgno; 1601{ 1602 DBT logrec; 1603 DB_LSN *lsnp, null_lsn, *rlsnp; 1604 DB_TXNLOGREC *lr; 1605 ENV *env; 1606 u_int32_t uinttmp, rectype, txn_num; 1607 u_int npad; 1608 u_int8_t *bp; 1609 int is_durable, ret; 1610 1611 COMPQUIET(lr, NULL); 1612 1613 env = dbp->env; 1614 rlsnp = ret_lsnp; 1615 rectype = DB___ham_metagroup; 1616 npad = 0; 1617 ret = 0; 1618 1619 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1620 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1621 if (txnp == NULL) 1622 return (0); 1623 is_durable = 0; 1624 } else 1625 is_durable = 1; 1626 1627 if (txnp == NULL) { 1628 txn_num = 0; 1629 lsnp = &null_lsn; 1630 null_lsn.file = null_lsn.offset = 0; 1631 } else { 1632 if (TAILQ_FIRST(&txnp->kids) != NULL && 1633 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1634 return (ret); 1635 /* 1636 * We need to assign begin_lsn while holding region mutex. 1637 * That assignment is done inside the DbEnv->log_put call, 1638 * so pass in the appropriate memory location to be filled 1639 * in by the log_put code. 1640 */ 1641 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1642 txn_num = txnp->txnid; 1643 } 1644 1645 DB_ASSERT(env, dbp->log_filename != NULL); 1646 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1647 (ret = __dbreg_lazy_id(dbp)) != 0) 1648 return (ret); 1649 1650 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1651 + sizeof(u_int32_t) 1652 + sizeof(u_int32_t) 1653 + sizeof(u_int32_t) 1654 + sizeof(*mmetalsn) 1655 + sizeof(u_int32_t) 1656 + sizeof(*metalsn) 1657 + sizeof(u_int32_t) 1658 + sizeof(*pagelsn) 1659 + sizeof(u_int32_t) 1660 + sizeof(u_int32_t); 1661 if (CRYPTO_ON(env)) { 1662 npad = env->crypto_handle->adj_size(logrec.size); 1663 logrec.size += npad; 1664 } 1665 1666 if (is_durable || txnp == NULL) { 1667 if ((ret = 1668 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1669 return (ret); 1670 } else { 1671 if ((ret = __os_malloc(env, 1672 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1673 return (ret); 1674#ifdef DIAGNOSTIC 1675 if ((ret = 1676 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1677 __os_free(env, lr); 1678 return (ret); 1679 } 1680#else 1681 logrec.data = lr->data; 1682#endif 1683 } 1684 if (npad > 0) 1685 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1686 1687 bp = logrec.data; 1688 1689 LOGCOPY_32(env, bp, &rectype); 1690 bp += sizeof(rectype); 1691 1692 LOGCOPY_32(env, bp, &txn_num); 1693 bp += sizeof(txn_num); 1694 1695 LOGCOPY_FROMLSN(env, bp, lsnp); 1696 bp += sizeof(DB_LSN); 1697 1698 uinttmp = (u_int32_t)dbp->log_filename->id; 1699 LOGCOPY_32(env, bp, &uinttmp); 1700 bp += sizeof(uinttmp); 1701 1702 LOGCOPY_32(env, bp, &bucket); 1703 bp += sizeof(bucket); 1704 1705 uinttmp = (u_int32_t)mmpgno; 1706 LOGCOPY_32(env,bp, &uinttmp); 1707 bp += sizeof(uinttmp); 1708 1709 if (mmetalsn != NULL) { 1710 if (txnp != NULL) { 1711 LOG *lp = env->lg_handle->reginfo.primary; 1712 if (LOG_COMPARE(mmetalsn, &lp->lsn) >= 0 && (ret = 1713 __log_check_page_lsn(env, dbp, mmetalsn) != 0)) 1714 return (ret); 1715 } 1716 LOGCOPY_FROMLSN(env, bp, mmetalsn); 1717 } else 1718 memset(bp, 0, sizeof(*mmetalsn)); 1719 bp += sizeof(*mmetalsn); 1720 1721 uinttmp = (u_int32_t)mpgno; 1722 LOGCOPY_32(env,bp, &uinttmp); 1723 bp += sizeof(uinttmp); 1724 1725 if (metalsn != NULL) { 1726 if (txnp != NULL) { 1727 LOG *lp = env->lg_handle->reginfo.primary; 1728 if (LOG_COMPARE(metalsn, &lp->lsn) >= 0 && (ret = 1729 __log_check_page_lsn(env, dbp, metalsn) != 0)) 1730 return (ret); 1731 } 1732 LOGCOPY_FROMLSN(env, bp, metalsn); 1733 } else 1734 memset(bp, 0, sizeof(*metalsn)); 1735 bp += sizeof(*metalsn); 1736 1737 uinttmp = (u_int32_t)pgno; 1738 LOGCOPY_32(env,bp, &uinttmp); 1739 bp += sizeof(uinttmp); 1740 1741 if (pagelsn != NULL) { 1742 if (txnp != NULL) { 1743 LOG *lp = env->lg_handle->reginfo.primary; 1744 if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = 1745 __log_check_page_lsn(env, dbp, pagelsn) != 0)) 1746 return (ret); 1747 } 1748 LOGCOPY_FROMLSN(env, bp, pagelsn); 1749 } else 1750 memset(bp, 0, sizeof(*pagelsn)); 1751 bp += sizeof(*pagelsn); 1752 1753 LOGCOPY_32(env, bp, &newalloc); 1754 bp += sizeof(newalloc); 1755 1756 uinttmp = (u_int32_t)last_pgno; 1757 LOGCOPY_32(env,bp, &uinttmp); 1758 bp += sizeof(uinttmp); 1759 1760 DB_ASSERT(env, 1761 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1762 1763 if (is_durable || txnp == NULL) { 1764 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1765 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1766 *lsnp = *rlsnp; 1767 if (rlsnp != ret_lsnp) 1768 *ret_lsnp = *rlsnp; 1769 } 1770 } else { 1771 ret = 0; 1772#ifdef DIAGNOSTIC 1773 /* 1774 * Set the debug bit if we are going to log non-durable 1775 * transactions so they will be ignored by recovery. 1776 */ 1777 memcpy(lr->data, logrec.data, logrec.size); 1778 rectype |= DB_debug_FLAG; 1779 LOGCOPY_32(env, logrec.data, &rectype); 1780 1781 if (!IS_REP_CLIENT(env)) 1782 ret = __log_put(env, 1783 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1784#endif 1785 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1786 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1787 LSN_NOT_LOGGED(*ret_lsnp); 1788 } 1789 1790#ifdef LOG_DIAGNOSTIC 1791 if (ret != 0) 1792 (void)__ham_metagroup_print(env, 1793 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1794#endif 1795 1796#ifdef DIAGNOSTIC 1797 __os_free(env, logrec.data); 1798#else 1799 if (is_durable || txnp == NULL) 1800 __os_free(env, logrec.data); 1801#endif 1802 return (ret); 1803} 1804 1805/* 1806 * PUBLIC: int __ham_groupalloc_42_read __P((ENV *, DB **, void *, 1807 * PUBLIC: void *, __ham_groupalloc_42_args **)); 1808 */ 1809int 1810__ham_groupalloc_42_read(env, dbpp, td, recbuf, argpp) 1811 ENV *env; 1812 DB **dbpp; 1813 void *td; 1814 void *recbuf; 1815 __ham_groupalloc_42_args **argpp; 1816{ 1817 __ham_groupalloc_42_args *argp; 1818 u_int32_t uinttmp; 1819 u_int8_t *bp; 1820 int ret; 1821 1822 if ((ret = __os_malloc(env, 1823 sizeof(__ham_groupalloc_42_args) + sizeof(DB_TXN), &argp)) != 0) 1824 return (ret); 1825 bp = recbuf; 1826 argp->txnp = (DB_TXN *)&argp[1]; 1827 memset(argp->txnp, 0, sizeof(DB_TXN)); 1828 1829 argp->txnp->td = td; 1830 LOGCOPY_32(env, &argp->type, bp); 1831 bp += sizeof(argp->type); 1832 1833 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1834 bp += sizeof(argp->txnp->txnid); 1835 1836 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1837 bp += sizeof(DB_LSN); 1838 1839 LOGCOPY_32(env, &uinttmp, bp); 1840 argp->fileid = (int32_t)uinttmp; 1841 bp += sizeof(uinttmp); 1842 if (dbpp != NULL) { 1843 *dbpp = NULL; 1844 ret = __dbreg_id_to_db( 1845 env, argp->txnp, dbpp, argp->fileid, 1); 1846 } 1847 1848 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1849 bp += sizeof(DB_LSN); 1850 1851 LOGCOPY_32(env, &uinttmp, bp); 1852 argp->start_pgno = (db_pgno_t)uinttmp; 1853 bp += sizeof(uinttmp); 1854 1855 LOGCOPY_32(env, &argp->num, bp); 1856 bp += sizeof(argp->num); 1857 1858 LOGCOPY_32(env, &uinttmp, bp); 1859 argp->free = (db_pgno_t)uinttmp; 1860 bp += sizeof(uinttmp); 1861 1862 *argpp = argp; 1863 return (ret); 1864} 1865 1866/* 1867 * PUBLIC: int __ham_groupalloc_read __P((ENV *, DB **, void *, 1868 * PUBLIC: void *, __ham_groupalloc_args **)); 1869 */ 1870int 1871__ham_groupalloc_read(env, dbpp, td, recbuf, argpp) 1872 ENV *env; 1873 DB **dbpp; 1874 void *td; 1875 void *recbuf; 1876 __ham_groupalloc_args **argpp; 1877{ 1878 __ham_groupalloc_args *argp; 1879 u_int32_t uinttmp; 1880 u_int8_t *bp; 1881 int ret; 1882 1883 if ((ret = __os_malloc(env, 1884 sizeof(__ham_groupalloc_args) + sizeof(DB_TXN), &argp)) != 0) 1885 return (ret); 1886 bp = recbuf; 1887 argp->txnp = (DB_TXN *)&argp[1]; 1888 memset(argp->txnp, 0, sizeof(DB_TXN)); 1889 1890 argp->txnp->td = td; 1891 LOGCOPY_32(env, &argp->type, bp); 1892 bp += sizeof(argp->type); 1893 1894 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1895 bp += sizeof(argp->txnp->txnid); 1896 1897 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1898 bp += sizeof(DB_LSN); 1899 1900 LOGCOPY_32(env, &uinttmp, bp); 1901 argp->fileid = (int32_t)uinttmp; 1902 bp += sizeof(uinttmp); 1903 if (dbpp != NULL) { 1904 *dbpp = NULL; 1905 ret = __dbreg_id_to_db( 1906 env, argp->txnp, dbpp, argp->fileid, 1); 1907 } 1908 1909 LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); 1910 bp += sizeof(DB_LSN); 1911 1912 LOGCOPY_32(env, &uinttmp, bp); 1913 argp->start_pgno = (db_pgno_t)uinttmp; 1914 bp += sizeof(uinttmp); 1915 1916 LOGCOPY_32(env, &argp->num, bp); 1917 bp += sizeof(argp->num); 1918 1919 LOGCOPY_32(env, &uinttmp, bp); 1920 argp->unused = (db_pgno_t)uinttmp; 1921 bp += sizeof(uinttmp); 1922 1923 LOGCOPY_32(env, &uinttmp, bp); 1924 argp->last_pgno = (db_pgno_t)uinttmp; 1925 bp += sizeof(uinttmp); 1926 1927 *argpp = argp; 1928 return (ret); 1929} 1930 1931/* 1932 * PUBLIC: int __ham_groupalloc_log __P((DB *, DB_TXN *, DB_LSN *, 1933 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_pgno_t, 1934 * PUBLIC: db_pgno_t)); 1935 */ 1936int 1937__ham_groupalloc_log(dbp, txnp, ret_lsnp, flags, meta_lsn, start_pgno, num, unused, last_pgno) 1938 DB *dbp; 1939 DB_TXN *txnp; 1940 DB_LSN *ret_lsnp; 1941 u_int32_t flags; 1942 DB_LSN * meta_lsn; 1943 db_pgno_t start_pgno; 1944 u_int32_t num; 1945 db_pgno_t unused; 1946 db_pgno_t last_pgno; 1947{ 1948 DBT logrec; 1949 DB_LSN *lsnp, null_lsn, *rlsnp; 1950 DB_TXNLOGREC *lr; 1951 ENV *env; 1952 u_int32_t uinttmp, rectype, txn_num; 1953 u_int npad; 1954 u_int8_t *bp; 1955 int is_durable, ret; 1956 1957 COMPQUIET(lr, NULL); 1958 1959 env = dbp->env; 1960 rlsnp = ret_lsnp; 1961 rectype = DB___ham_groupalloc; 1962 npad = 0; 1963 ret = 0; 1964 1965 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1966 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1967 if (txnp == NULL) 1968 return (0); 1969 is_durable = 0; 1970 } else 1971 is_durable = 1; 1972 1973 if (txnp == NULL) { 1974 txn_num = 0; 1975 lsnp = &null_lsn; 1976 null_lsn.file = null_lsn.offset = 0; 1977 } else { 1978 if (TAILQ_FIRST(&txnp->kids) != NULL && 1979 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1980 return (ret); 1981 /* 1982 * We need to assign begin_lsn while holding region mutex. 1983 * That assignment is done inside the DbEnv->log_put call, 1984 * so pass in the appropriate memory location to be filled 1985 * in by the log_put code. 1986 */ 1987 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1988 txn_num = txnp->txnid; 1989 } 1990 1991 DB_ASSERT(env, dbp->log_filename != NULL); 1992 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1993 (ret = __dbreg_lazy_id(dbp)) != 0) 1994 return (ret); 1995 1996 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1997 + sizeof(u_int32_t) 1998 + sizeof(*meta_lsn) 1999 + sizeof(u_int32_t) 2000 + sizeof(u_int32_t) 2001 + sizeof(u_int32_t) 2002 + sizeof(u_int32_t); 2003 if (CRYPTO_ON(env)) { 2004 npad = env->crypto_handle->adj_size(logrec.size); 2005 logrec.size += npad; 2006 } 2007 2008 if (is_durable || txnp == NULL) { 2009 if ((ret = 2010 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2011 return (ret); 2012 } else { 2013 if ((ret = __os_malloc(env, 2014 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2015 return (ret); 2016#ifdef DIAGNOSTIC 2017 if ((ret = 2018 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2019 __os_free(env, lr); 2020 return (ret); 2021 } 2022#else 2023 logrec.data = lr->data; 2024#endif 2025 } 2026 if (npad > 0) 2027 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2028 2029 bp = logrec.data; 2030 2031 LOGCOPY_32(env, bp, &rectype); 2032 bp += sizeof(rectype); 2033 2034 LOGCOPY_32(env, bp, &txn_num); 2035 bp += sizeof(txn_num); 2036 2037 LOGCOPY_FROMLSN(env, bp, lsnp); 2038 bp += sizeof(DB_LSN); 2039 2040 uinttmp = (u_int32_t)dbp->log_filename->id; 2041 LOGCOPY_32(env, bp, &uinttmp); 2042 bp += sizeof(uinttmp); 2043 2044 if (meta_lsn != NULL) { 2045 if (txnp != NULL) { 2046 LOG *lp = env->lg_handle->reginfo.primary; 2047 if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = 2048 __log_check_page_lsn(env, dbp, meta_lsn) != 0)) 2049 return (ret); 2050 } 2051 LOGCOPY_FROMLSN(env, bp, meta_lsn); 2052 } else 2053 memset(bp, 0, sizeof(*meta_lsn)); 2054 bp += sizeof(*meta_lsn); 2055 2056 uinttmp = (u_int32_t)start_pgno; 2057 LOGCOPY_32(env,bp, &uinttmp); 2058 bp += sizeof(uinttmp); 2059 2060 LOGCOPY_32(env, bp, &num); 2061 bp += sizeof(num); 2062 2063 uinttmp = (u_int32_t)unused; 2064 LOGCOPY_32(env,bp, &uinttmp); 2065 bp += sizeof(uinttmp); 2066 2067 uinttmp = (u_int32_t)last_pgno; 2068 LOGCOPY_32(env,bp, &uinttmp); 2069 bp += sizeof(uinttmp); 2070 2071 DB_ASSERT(env, 2072 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2073 2074 if (is_durable || txnp == NULL) { 2075 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2076 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2077 *lsnp = *rlsnp; 2078 if (rlsnp != ret_lsnp) 2079 *ret_lsnp = *rlsnp; 2080 } 2081 } else { 2082 ret = 0; 2083#ifdef DIAGNOSTIC 2084 /* 2085 * Set the debug bit if we are going to log non-durable 2086 * transactions so they will be ignored by recovery. 2087 */ 2088 memcpy(lr->data, logrec.data, logrec.size); 2089 rectype |= DB_debug_FLAG; 2090 LOGCOPY_32(env, logrec.data, &rectype); 2091 2092 if (!IS_REP_CLIENT(env)) 2093 ret = __log_put(env, 2094 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2095#endif 2096 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2097 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2098 LSN_NOT_LOGGED(*ret_lsnp); 2099 } 2100 2101#ifdef LOG_DIAGNOSTIC 2102 if (ret != 0) 2103 (void)__ham_groupalloc_print(env, 2104 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2105#endif 2106 2107#ifdef DIAGNOSTIC 2108 __os_free(env, logrec.data); 2109#else 2110 if (is_durable || txnp == NULL) 2111 __os_free(env, logrec.data); 2112#endif 2113 return (ret); 2114} 2115 2116/* 2117 * PUBLIC: int __ham_curadj_read __P((ENV *, DB **, void *, void *, 2118 * PUBLIC: __ham_curadj_args **)); 2119 */ 2120int 2121__ham_curadj_read(env, dbpp, td, recbuf, argpp) 2122 ENV *env; 2123 DB **dbpp; 2124 void *td; 2125 void *recbuf; 2126 __ham_curadj_args **argpp; 2127{ 2128 __ham_curadj_args *argp; 2129 u_int32_t uinttmp; 2130 u_int8_t *bp; 2131 int ret; 2132 2133 if ((ret = __os_malloc(env, 2134 sizeof(__ham_curadj_args) + sizeof(DB_TXN), &argp)) != 0) 2135 return (ret); 2136 bp = recbuf; 2137 argp->txnp = (DB_TXN *)&argp[1]; 2138 memset(argp->txnp, 0, sizeof(DB_TXN)); 2139 2140 argp->txnp->td = td; 2141 LOGCOPY_32(env, &argp->type, bp); 2142 bp += sizeof(argp->type); 2143 2144 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2145 bp += sizeof(argp->txnp->txnid); 2146 2147 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2148 bp += sizeof(DB_LSN); 2149 2150 LOGCOPY_32(env, &uinttmp, bp); 2151 argp->fileid = (int32_t)uinttmp; 2152 bp += sizeof(uinttmp); 2153 if (dbpp != NULL) { 2154 *dbpp = NULL; 2155 ret = __dbreg_id_to_db( 2156 env, argp->txnp, dbpp, argp->fileid, 1); 2157 } 2158 2159 LOGCOPY_32(env, &uinttmp, bp); 2160 argp->pgno = (db_pgno_t)uinttmp; 2161 bp += sizeof(uinttmp); 2162 2163 LOGCOPY_32(env, &argp->indx, bp); 2164 bp += sizeof(argp->indx); 2165 2166 LOGCOPY_32(env, &argp->len, bp); 2167 bp += sizeof(argp->len); 2168 2169 LOGCOPY_32(env, &argp->dup_off, bp); 2170 bp += sizeof(argp->dup_off); 2171 2172 LOGCOPY_32(env, &uinttmp, bp); 2173 argp->add = (int)uinttmp; 2174 bp += sizeof(uinttmp); 2175 2176 LOGCOPY_32(env, &uinttmp, bp); 2177 argp->is_dup = (int)uinttmp; 2178 bp += sizeof(uinttmp); 2179 2180 LOGCOPY_32(env, &argp->order, bp); 2181 bp += sizeof(argp->order); 2182 2183 *argpp = argp; 2184 return (ret); 2185} 2186 2187/* 2188 * PUBLIC: int __ham_curadj_log __P((DB *, DB_TXN *, DB_LSN *, 2189 * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, u_int32_t, u_int32_t, int, int, 2190 * PUBLIC: u_int32_t)); 2191 */ 2192int 2193__ham_curadj_log(dbp, txnp, ret_lsnp, flags, pgno, indx, len, dup_off, add, 2194 is_dup, order) 2195 DB *dbp; 2196 DB_TXN *txnp; 2197 DB_LSN *ret_lsnp; 2198 u_int32_t flags; 2199 db_pgno_t pgno; 2200 u_int32_t indx; 2201 u_int32_t len; 2202 u_int32_t dup_off; 2203 int add; 2204 int is_dup; 2205 u_int32_t order; 2206{ 2207 DBT logrec; 2208 DB_LSN *lsnp, null_lsn, *rlsnp; 2209 DB_TXNLOGREC *lr; 2210 ENV *env; 2211 u_int32_t uinttmp, rectype, txn_num; 2212 u_int npad; 2213 u_int8_t *bp; 2214 int is_durable, ret; 2215 2216 COMPQUIET(lr, NULL); 2217 2218 env = dbp->env; 2219 rlsnp = ret_lsnp; 2220 rectype = DB___ham_curadj; 2221 npad = 0; 2222 ret = 0; 2223 2224 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2225 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2226 if (txnp == NULL) 2227 return (0); 2228 is_durable = 0; 2229 } else 2230 is_durable = 1; 2231 2232 if (txnp == NULL) { 2233 txn_num = 0; 2234 lsnp = &null_lsn; 2235 null_lsn.file = null_lsn.offset = 0; 2236 } else { 2237 if (TAILQ_FIRST(&txnp->kids) != NULL && 2238 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2239 return (ret); 2240 /* 2241 * We need to assign begin_lsn while holding region mutex. 2242 * That assignment is done inside the DbEnv->log_put call, 2243 * so pass in the appropriate memory location to be filled 2244 * in by the log_put code. 2245 */ 2246 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2247 txn_num = txnp->txnid; 2248 } 2249 2250 DB_ASSERT(env, dbp->log_filename != NULL); 2251 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2252 (ret = __dbreg_lazy_id(dbp)) != 0) 2253 return (ret); 2254 2255 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2256 + sizeof(u_int32_t) 2257 + sizeof(u_int32_t) 2258 + sizeof(u_int32_t) 2259 + sizeof(u_int32_t) 2260 + sizeof(u_int32_t) 2261 + sizeof(u_int32_t) 2262 + sizeof(u_int32_t) 2263 + sizeof(u_int32_t); 2264 if (CRYPTO_ON(env)) { 2265 npad = env->crypto_handle->adj_size(logrec.size); 2266 logrec.size += npad; 2267 } 2268 2269 if (is_durable || txnp == NULL) { 2270 if ((ret = 2271 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2272 return (ret); 2273 } else { 2274 if ((ret = __os_malloc(env, 2275 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2276 return (ret); 2277#ifdef DIAGNOSTIC 2278 if ((ret = 2279 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2280 __os_free(env, lr); 2281 return (ret); 2282 } 2283#else 2284 logrec.data = lr->data; 2285#endif 2286 } 2287 if (npad > 0) 2288 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2289 2290 bp = logrec.data; 2291 2292 LOGCOPY_32(env, bp, &rectype); 2293 bp += sizeof(rectype); 2294 2295 LOGCOPY_32(env, bp, &txn_num); 2296 bp += sizeof(txn_num); 2297 2298 LOGCOPY_FROMLSN(env, bp, lsnp); 2299 bp += sizeof(DB_LSN); 2300 2301 uinttmp = (u_int32_t)dbp->log_filename->id; 2302 LOGCOPY_32(env, bp, &uinttmp); 2303 bp += sizeof(uinttmp); 2304 2305 uinttmp = (u_int32_t)pgno; 2306 LOGCOPY_32(env,bp, &uinttmp); 2307 bp += sizeof(uinttmp); 2308 2309 LOGCOPY_32(env, bp, &indx); 2310 bp += sizeof(indx); 2311 2312 LOGCOPY_32(env, bp, &len); 2313 bp += sizeof(len); 2314 2315 LOGCOPY_32(env, bp, &dup_off); 2316 bp += sizeof(dup_off); 2317 2318 uinttmp = (u_int32_t)add; 2319 LOGCOPY_32(env,bp, &uinttmp); 2320 bp += sizeof(uinttmp); 2321 2322 uinttmp = (u_int32_t)is_dup; 2323 LOGCOPY_32(env,bp, &uinttmp); 2324 bp += sizeof(uinttmp); 2325 2326 LOGCOPY_32(env, bp, &order); 2327 bp += sizeof(order); 2328 2329 DB_ASSERT(env, 2330 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2331 2332 if (is_durable || txnp == NULL) { 2333 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2334 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2335 *lsnp = *rlsnp; 2336 if (rlsnp != ret_lsnp) 2337 *ret_lsnp = *rlsnp; 2338 } 2339 } else { 2340 ret = 0; 2341#ifdef DIAGNOSTIC 2342 /* 2343 * Set the debug bit if we are going to log non-durable 2344 * transactions so they will be ignored by recovery. 2345 */ 2346 memcpy(lr->data, logrec.data, logrec.size); 2347 rectype |= DB_debug_FLAG; 2348 LOGCOPY_32(env, logrec.data, &rectype); 2349 2350 if (!IS_REP_CLIENT(env)) 2351 ret = __log_put(env, 2352 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2353#endif 2354 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2355 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2356 LSN_NOT_LOGGED(*ret_lsnp); 2357 } 2358 2359#ifdef LOG_DIAGNOSTIC 2360 if (ret != 0) 2361 (void)__ham_curadj_print(env, 2362 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2363#endif 2364 2365#ifdef DIAGNOSTIC 2366 __os_free(env, logrec.data); 2367#else 2368 if (is_durable || txnp == NULL) 2369 __os_free(env, logrec.data); 2370#endif 2371 return (ret); 2372} 2373 2374/* 2375 * PUBLIC: int __ham_chgpg_read __P((ENV *, DB **, void *, void *, 2376 * PUBLIC: __ham_chgpg_args **)); 2377 */ 2378int 2379__ham_chgpg_read(env, dbpp, td, recbuf, argpp) 2380 ENV *env; 2381 DB **dbpp; 2382 void *td; 2383 void *recbuf; 2384 __ham_chgpg_args **argpp; 2385{ 2386 __ham_chgpg_args *argp; 2387 u_int32_t uinttmp; 2388 u_int8_t *bp; 2389 int ret; 2390 2391 if ((ret = __os_malloc(env, 2392 sizeof(__ham_chgpg_args) + sizeof(DB_TXN), &argp)) != 0) 2393 return (ret); 2394 bp = recbuf; 2395 argp->txnp = (DB_TXN *)&argp[1]; 2396 memset(argp->txnp, 0, sizeof(DB_TXN)); 2397 2398 argp->txnp->td = td; 2399 LOGCOPY_32(env, &argp->type, bp); 2400 bp += sizeof(argp->type); 2401 2402 LOGCOPY_32(env, &argp->txnp->txnid, bp); 2403 bp += sizeof(argp->txnp->txnid); 2404 2405 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 2406 bp += sizeof(DB_LSN); 2407 2408 LOGCOPY_32(env, &uinttmp, bp); 2409 argp->fileid = (int32_t)uinttmp; 2410 bp += sizeof(uinttmp); 2411 if (dbpp != NULL) { 2412 *dbpp = NULL; 2413 ret = __dbreg_id_to_db( 2414 env, argp->txnp, dbpp, argp->fileid, 1); 2415 } 2416 2417 LOGCOPY_32(env, &uinttmp, bp); 2418 argp->mode = (db_ham_mode)uinttmp; 2419 bp += sizeof(uinttmp); 2420 2421 LOGCOPY_32(env, &uinttmp, bp); 2422 argp->old_pgno = (db_pgno_t)uinttmp; 2423 bp += sizeof(uinttmp); 2424 2425 LOGCOPY_32(env, &uinttmp, bp); 2426 argp->new_pgno = (db_pgno_t)uinttmp; 2427 bp += sizeof(uinttmp); 2428 2429 LOGCOPY_32(env, &argp->old_indx, bp); 2430 bp += sizeof(argp->old_indx); 2431 2432 LOGCOPY_32(env, &argp->new_indx, bp); 2433 bp += sizeof(argp->new_indx); 2434 2435 *argpp = argp; 2436 return (ret); 2437} 2438 2439/* 2440 * PUBLIC: int __ham_chgpg_log __P((DB *, DB_TXN *, DB_LSN *, 2441 * PUBLIC: u_int32_t, db_ham_mode, db_pgno_t, db_pgno_t, u_int32_t, 2442 * PUBLIC: u_int32_t)); 2443 */ 2444int 2445__ham_chgpg_log(dbp, txnp, ret_lsnp, flags, mode, old_pgno, new_pgno, old_indx, new_indx) 2446 DB *dbp; 2447 DB_TXN *txnp; 2448 DB_LSN *ret_lsnp; 2449 u_int32_t flags; 2450 db_ham_mode mode; 2451 db_pgno_t old_pgno; 2452 db_pgno_t new_pgno; 2453 u_int32_t old_indx; 2454 u_int32_t new_indx; 2455{ 2456 DBT logrec; 2457 DB_LSN *lsnp, null_lsn, *rlsnp; 2458 DB_TXNLOGREC *lr; 2459 ENV *env; 2460 u_int32_t uinttmp, rectype, txn_num; 2461 u_int npad; 2462 u_int8_t *bp; 2463 int is_durable, ret; 2464 2465 COMPQUIET(lr, NULL); 2466 2467 env = dbp->env; 2468 rlsnp = ret_lsnp; 2469 rectype = DB___ham_chgpg; 2470 npad = 0; 2471 ret = 0; 2472 2473 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 2474 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 2475 if (txnp == NULL) 2476 return (0); 2477 is_durable = 0; 2478 } else 2479 is_durable = 1; 2480 2481 if (txnp == NULL) { 2482 txn_num = 0; 2483 lsnp = &null_lsn; 2484 null_lsn.file = null_lsn.offset = 0; 2485 } else { 2486 if (TAILQ_FIRST(&txnp->kids) != NULL && 2487 (ret = __txn_activekids(env, rectype, txnp)) != 0) 2488 return (ret); 2489 /* 2490 * We need to assign begin_lsn while holding region mutex. 2491 * That assignment is done inside the DbEnv->log_put call, 2492 * so pass in the appropriate memory location to be filled 2493 * in by the log_put code. 2494 */ 2495 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 2496 txn_num = txnp->txnid; 2497 } 2498 2499 DB_ASSERT(env, dbp->log_filename != NULL); 2500 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 2501 (ret = __dbreg_lazy_id(dbp)) != 0) 2502 return (ret); 2503 2504 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 2505 + sizeof(u_int32_t) 2506 + sizeof(u_int32_t) 2507 + sizeof(u_int32_t) 2508 + sizeof(u_int32_t) 2509 + sizeof(u_int32_t) 2510 + sizeof(u_int32_t); 2511 if (CRYPTO_ON(env)) { 2512 npad = env->crypto_handle->adj_size(logrec.size); 2513 logrec.size += npad; 2514 } 2515 2516 if (is_durable || txnp == NULL) { 2517 if ((ret = 2518 __os_malloc(env, logrec.size, &logrec.data)) != 0) 2519 return (ret); 2520 } else { 2521 if ((ret = __os_malloc(env, 2522 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 2523 return (ret); 2524#ifdef DIAGNOSTIC 2525 if ((ret = 2526 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 2527 __os_free(env, lr); 2528 return (ret); 2529 } 2530#else 2531 logrec.data = lr->data; 2532#endif 2533 } 2534 if (npad > 0) 2535 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 2536 2537 bp = logrec.data; 2538 2539 LOGCOPY_32(env, bp, &rectype); 2540 bp += sizeof(rectype); 2541 2542 LOGCOPY_32(env, bp, &txn_num); 2543 bp += sizeof(txn_num); 2544 2545 LOGCOPY_FROMLSN(env, bp, lsnp); 2546 bp += sizeof(DB_LSN); 2547 2548 uinttmp = (u_int32_t)dbp->log_filename->id; 2549 LOGCOPY_32(env, bp, &uinttmp); 2550 bp += sizeof(uinttmp); 2551 2552 uinttmp = (u_int32_t)mode; 2553 LOGCOPY_32(env,bp, &uinttmp); 2554 bp += sizeof(uinttmp); 2555 2556 uinttmp = (u_int32_t)old_pgno; 2557 LOGCOPY_32(env,bp, &uinttmp); 2558 bp += sizeof(uinttmp); 2559 2560 uinttmp = (u_int32_t)new_pgno; 2561 LOGCOPY_32(env,bp, &uinttmp); 2562 bp += sizeof(uinttmp); 2563 2564 LOGCOPY_32(env, bp, &old_indx); 2565 bp += sizeof(old_indx); 2566 2567 LOGCOPY_32(env, bp, &new_indx); 2568 bp += sizeof(new_indx); 2569 2570 DB_ASSERT(env, 2571 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 2572 2573 if (is_durable || txnp == NULL) { 2574 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 2575 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 2576 *lsnp = *rlsnp; 2577 if (rlsnp != ret_lsnp) 2578 *ret_lsnp = *rlsnp; 2579 } 2580 } else { 2581 ret = 0; 2582#ifdef DIAGNOSTIC 2583 /* 2584 * Set the debug bit if we are going to log non-durable 2585 * transactions so they will be ignored by recovery. 2586 */ 2587 memcpy(lr->data, logrec.data, logrec.size); 2588 rectype |= DB_debug_FLAG; 2589 LOGCOPY_32(env, logrec.data, &rectype); 2590 2591 if (!IS_REP_CLIENT(env)) 2592 ret = __log_put(env, 2593 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 2594#endif 2595 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 2596 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 2597 LSN_NOT_LOGGED(*ret_lsnp); 2598 } 2599 2600#ifdef LOG_DIAGNOSTIC 2601 if (ret != 0) 2602 (void)__ham_chgpg_print(env, 2603 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 2604#endif 2605 2606#ifdef DIAGNOSTIC 2607 __os_free(env, logrec.data); 2608#else 2609 if (is_durable || txnp == NULL) 2610 __os_free(env, logrec.data); 2611#endif 2612 return (ret); 2613} 2614 2615/* 2616 * PUBLIC: int __ham_init_recover __P((ENV *, DB_DISTAB *)); 2617 */ 2618int 2619__ham_init_recover(env, dtabp) 2620 ENV *env; 2621 DB_DISTAB *dtabp; 2622{ 2623 int ret; 2624 2625 if ((ret = __db_add_recovery_int(env, dtabp, 2626 __ham_insdel_recover, DB___ham_insdel)) != 0) 2627 return (ret); 2628 if ((ret = __db_add_recovery_int(env, dtabp, 2629 __ham_newpage_recover, DB___ham_newpage)) != 0) 2630 return (ret); 2631 if ((ret = __db_add_recovery_int(env, dtabp, 2632 __ham_splitdata_recover, DB___ham_splitdata)) != 0) 2633 return (ret); 2634 if ((ret = __db_add_recovery_int(env, dtabp, 2635 __ham_replace_recover, DB___ham_replace)) != 0) 2636 return (ret); 2637 if ((ret = __db_add_recovery_int(env, dtabp, 2638 __ham_copypage_recover, DB___ham_copypage)) != 0) 2639 return (ret); 2640 if ((ret = __db_add_recovery_int(env, dtabp, 2641 __ham_metagroup_recover, DB___ham_metagroup)) != 0) 2642 return (ret); 2643 if ((ret = __db_add_recovery_int(env, dtabp, 2644 __ham_groupalloc_recover, DB___ham_groupalloc)) != 0) 2645 return (ret); 2646 if ((ret = __db_add_recovery_int(env, dtabp, 2647 __ham_curadj_recover, DB___ham_curadj)) != 0) 2648 return (ret); 2649 if ((ret = __db_add_recovery_int(env, dtabp, 2650 __ham_chgpg_recover, DB___ham_chgpg)) != 0) 2651 return (ret); 2652 return (0); 2653} 2654