1/* Do not edit: automatically built by gen_rec.awk. */ 2 3#include "db_config.h" 4#include "db_int.h" 5#include "dbinc/crypto.h" 6#include "dbinc/db_page.h" 7#include "dbinc/db_dispatch.h" 8#include "dbinc/db_am.h" 9#include "dbinc/log.h" 10#include "dbinc/qam.h" 11#include "dbinc/txn.h" 12 13/* 14 * PUBLIC: int __qam_incfirst_read __P((ENV *, DB **, void *, 15 * PUBLIC: void *, __qam_incfirst_args **)); 16 */ 17int 18__qam_incfirst_read(env, dbpp, td, recbuf, argpp) 19 ENV *env; 20 DB **dbpp; 21 void *td; 22 void *recbuf; 23 __qam_incfirst_args **argpp; 24{ 25 __qam_incfirst_args *argp; 26 u_int32_t uinttmp; 27 u_int8_t *bp; 28 int ret; 29 30 if ((ret = __os_malloc(env, 31 sizeof(__qam_incfirst_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, &uinttmp, bp); 48 argp->fileid = (int32_t)uinttmp; 49 bp += sizeof(uinttmp); 50 if (dbpp != NULL) { 51 *dbpp = NULL; 52 ret = __dbreg_id_to_db( 53 env, argp->txnp, dbpp, argp->fileid, 1); 54 } 55 56 LOGCOPY_32(env, &uinttmp, bp); 57 argp->recno = (db_recno_t)uinttmp; 58 bp += sizeof(uinttmp); 59 60 LOGCOPY_32(env, &uinttmp, bp); 61 argp->meta_pgno = (db_pgno_t)uinttmp; 62 bp += sizeof(uinttmp); 63 64 *argpp = argp; 65 return (ret); 66} 67 68/* 69 * PUBLIC: int __qam_incfirst_log __P((DB *, DB_TXN *, DB_LSN *, 70 * PUBLIC: u_int32_t, db_recno_t, db_pgno_t)); 71 */ 72int 73__qam_incfirst_log(dbp, txnp, ret_lsnp, flags, recno, meta_pgno) 74 DB *dbp; 75 DB_TXN *txnp; 76 DB_LSN *ret_lsnp; 77 u_int32_t flags; 78 db_recno_t recno; 79 db_pgno_t meta_pgno; 80{ 81 DBT logrec; 82 DB_LSN *lsnp, null_lsn, *rlsnp; 83 DB_TXNLOGREC *lr; 84 ENV *env; 85 u_int32_t uinttmp, rectype, txn_num; 86 u_int npad; 87 u_int8_t *bp; 88 int is_durable, ret; 89 90 COMPQUIET(lr, NULL); 91 92 env = dbp->env; 93 rlsnp = ret_lsnp; 94 rectype = DB___qam_incfirst; 95 npad = 0; 96 ret = 0; 97 98 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 99 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 100 if (txnp == NULL) 101 return (0); 102 is_durable = 0; 103 } else 104 is_durable = 1; 105 106 if (txnp == NULL) { 107 txn_num = 0; 108 lsnp = &null_lsn; 109 null_lsn.file = null_lsn.offset = 0; 110 } else { 111 if (TAILQ_FIRST(&txnp->kids) != NULL && 112 (ret = __txn_activekids(env, rectype, txnp)) != 0) 113 return (ret); 114 /* 115 * We need to assign begin_lsn while holding region mutex. 116 * That assignment is done inside the DbEnv->log_put call, 117 * so pass in the appropriate memory location to be filled 118 * in by the log_put code. 119 */ 120 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 121 txn_num = txnp->txnid; 122 } 123 124 DB_ASSERT(env, dbp->log_filename != NULL); 125 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 126 (ret = __dbreg_lazy_id(dbp)) != 0) 127 return (ret); 128 129 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 130 + sizeof(u_int32_t) 131 + sizeof(u_int32_t) 132 + sizeof(u_int32_t); 133 if (CRYPTO_ON(env)) { 134 npad = env->crypto_handle->adj_size(logrec.size); 135 logrec.size += npad; 136 } 137 138 if (is_durable || txnp == NULL) { 139 if ((ret = 140 __os_malloc(env, logrec.size, &logrec.data)) != 0) 141 return (ret); 142 } else { 143 if ((ret = __os_malloc(env, 144 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 145 return (ret); 146#ifdef DIAGNOSTIC 147 if ((ret = 148 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 149 __os_free(env, lr); 150 return (ret); 151 } 152#else 153 logrec.data = lr->data; 154#endif 155 } 156 if (npad > 0) 157 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 158 159 bp = logrec.data; 160 161 LOGCOPY_32(env, bp, &rectype); 162 bp += sizeof(rectype); 163 164 LOGCOPY_32(env, bp, &txn_num); 165 bp += sizeof(txn_num); 166 167 LOGCOPY_FROMLSN(env, bp, lsnp); 168 bp += sizeof(DB_LSN); 169 170 uinttmp = (u_int32_t)dbp->log_filename->id; 171 LOGCOPY_32(env, bp, &uinttmp); 172 bp += sizeof(uinttmp); 173 174 uinttmp = (u_int32_t)recno; 175 LOGCOPY_32(env,bp, &uinttmp); 176 bp += sizeof(uinttmp); 177 178 uinttmp = (u_int32_t)meta_pgno; 179 LOGCOPY_32(env,bp, &uinttmp); 180 bp += sizeof(uinttmp); 181 182 DB_ASSERT(env, 183 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 184 185 if (is_durable || txnp == NULL) { 186 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 187 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 188 *lsnp = *rlsnp; 189 if (rlsnp != ret_lsnp) 190 *ret_lsnp = *rlsnp; 191 } 192 } else { 193 ret = 0; 194#ifdef DIAGNOSTIC 195 /* 196 * Set the debug bit if we are going to log non-durable 197 * transactions so they will be ignored by recovery. 198 */ 199 memcpy(lr->data, logrec.data, logrec.size); 200 rectype |= DB_debug_FLAG; 201 LOGCOPY_32(env, logrec.data, &rectype); 202 203 if (!IS_REP_CLIENT(env)) 204 ret = __log_put(env, 205 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 206#endif 207 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 208 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 209 LSN_NOT_LOGGED(*ret_lsnp); 210 } 211 212#ifdef LOG_DIAGNOSTIC 213 if (ret != 0) 214 (void)__qam_incfirst_print(env, 215 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 216#endif 217 218#ifdef DIAGNOSTIC 219 __os_free(env, logrec.data); 220#else 221 if (is_durable || txnp == NULL) 222 __os_free(env, logrec.data); 223#endif 224 return (ret); 225} 226 227/* 228 * PUBLIC: int __qam_mvptr_read __P((ENV *, DB **, void *, void *, 229 * PUBLIC: __qam_mvptr_args **)); 230 */ 231int 232__qam_mvptr_read(env, dbpp, td, recbuf, argpp) 233 ENV *env; 234 DB **dbpp; 235 void *td; 236 void *recbuf; 237 __qam_mvptr_args **argpp; 238{ 239 __qam_mvptr_args *argp; 240 u_int32_t uinttmp; 241 u_int8_t *bp; 242 int ret; 243 244 if ((ret = __os_malloc(env, 245 sizeof(__qam_mvptr_args) + sizeof(DB_TXN), &argp)) != 0) 246 return (ret); 247 bp = recbuf; 248 argp->txnp = (DB_TXN *)&argp[1]; 249 memset(argp->txnp, 0, sizeof(DB_TXN)); 250 251 argp->txnp->td = td; 252 LOGCOPY_32(env, &argp->type, bp); 253 bp += sizeof(argp->type); 254 255 LOGCOPY_32(env, &argp->txnp->txnid, bp); 256 bp += sizeof(argp->txnp->txnid); 257 258 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 259 bp += sizeof(DB_LSN); 260 261 LOGCOPY_32(env, &argp->opcode, bp); 262 bp += sizeof(argp->opcode); 263 264 LOGCOPY_32(env, &uinttmp, bp); 265 argp->fileid = (int32_t)uinttmp; 266 bp += sizeof(uinttmp); 267 if (dbpp != NULL) { 268 *dbpp = NULL; 269 ret = __dbreg_id_to_db( 270 env, argp->txnp, dbpp, argp->fileid, 1); 271 } 272 273 LOGCOPY_32(env, &uinttmp, bp); 274 argp->old_first = (db_recno_t)uinttmp; 275 bp += sizeof(uinttmp); 276 277 LOGCOPY_32(env, &uinttmp, bp); 278 argp->new_first = (db_recno_t)uinttmp; 279 bp += sizeof(uinttmp); 280 281 LOGCOPY_32(env, &uinttmp, bp); 282 argp->old_cur = (db_recno_t)uinttmp; 283 bp += sizeof(uinttmp); 284 285 LOGCOPY_32(env, &uinttmp, bp); 286 argp->new_cur = (db_recno_t)uinttmp; 287 bp += sizeof(uinttmp); 288 289 LOGCOPY_TOLSN(env, &argp->metalsn, bp); 290 bp += sizeof(DB_LSN); 291 292 LOGCOPY_32(env, &uinttmp, bp); 293 argp->meta_pgno = (db_pgno_t)uinttmp; 294 bp += sizeof(uinttmp); 295 296 *argpp = argp; 297 return (ret); 298} 299 300/* 301 * PUBLIC: int __qam_mvptr_log __P((DB *, DB_TXN *, DB_LSN *, 302 * PUBLIC: u_int32_t, u_int32_t, db_recno_t, db_recno_t, db_recno_t, 303 * PUBLIC: db_recno_t, DB_LSN *, db_pgno_t)); 304 */ 305int 306__qam_mvptr_log(dbp, txnp, ret_lsnp, flags, 307 opcode, old_first, new_first, old_cur, new_cur, 308 metalsn, meta_pgno) 309 DB *dbp; 310 DB_TXN *txnp; 311 DB_LSN *ret_lsnp; 312 u_int32_t flags; 313 u_int32_t opcode; 314 db_recno_t old_first; 315 db_recno_t new_first; 316 db_recno_t old_cur; 317 db_recno_t new_cur; 318 DB_LSN * metalsn; 319 db_pgno_t meta_pgno; 320{ 321 DBT logrec; 322 DB_LSN *lsnp, null_lsn, *rlsnp; 323 DB_TXNLOGREC *lr; 324 ENV *env; 325 u_int32_t uinttmp, rectype, txn_num; 326 u_int npad; 327 u_int8_t *bp; 328 int is_durable, ret; 329 330 COMPQUIET(lr, NULL); 331 332 env = dbp->env; 333 rlsnp = ret_lsnp; 334 rectype = DB___qam_mvptr; 335 npad = 0; 336 ret = 0; 337 338 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 339 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 340 if (txnp == NULL) 341 return (0); 342 is_durable = 0; 343 } else 344 is_durable = 1; 345 346 if (txnp == NULL) { 347 txn_num = 0; 348 lsnp = &null_lsn; 349 null_lsn.file = null_lsn.offset = 0; 350 } else { 351 if (TAILQ_FIRST(&txnp->kids) != NULL && 352 (ret = __txn_activekids(env, rectype, txnp)) != 0) 353 return (ret); 354 /* 355 * We need to assign begin_lsn while holding region mutex. 356 * That assignment is done inside the DbEnv->log_put call, 357 * so pass in the appropriate memory location to be filled 358 * in by the log_put code. 359 */ 360 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 361 txn_num = txnp->txnid; 362 } 363 364 DB_ASSERT(env, dbp->log_filename != NULL); 365 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 366 (ret = __dbreg_lazy_id(dbp)) != 0) 367 return (ret); 368 369 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 370 + sizeof(u_int32_t) 371 + sizeof(u_int32_t) 372 + sizeof(u_int32_t) 373 + sizeof(u_int32_t) 374 + sizeof(u_int32_t) 375 + sizeof(u_int32_t) 376 + sizeof(*metalsn) 377 + sizeof(u_int32_t); 378 if (CRYPTO_ON(env)) { 379 npad = env->crypto_handle->adj_size(logrec.size); 380 logrec.size += npad; 381 } 382 383 if (is_durable || txnp == NULL) { 384 if ((ret = 385 __os_malloc(env, logrec.size, &logrec.data)) != 0) 386 return (ret); 387 } else { 388 if ((ret = __os_malloc(env, 389 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 390 return (ret); 391#ifdef DIAGNOSTIC 392 if ((ret = 393 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 394 __os_free(env, lr); 395 return (ret); 396 } 397#else 398 logrec.data = lr->data; 399#endif 400 } 401 if (npad > 0) 402 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 403 404 bp = logrec.data; 405 406 LOGCOPY_32(env, bp, &rectype); 407 bp += sizeof(rectype); 408 409 LOGCOPY_32(env, bp, &txn_num); 410 bp += sizeof(txn_num); 411 412 LOGCOPY_FROMLSN(env, bp, lsnp); 413 bp += sizeof(DB_LSN); 414 415 LOGCOPY_32(env, bp, &opcode); 416 bp += sizeof(opcode); 417 418 uinttmp = (u_int32_t)dbp->log_filename->id; 419 LOGCOPY_32(env, bp, &uinttmp); 420 bp += sizeof(uinttmp); 421 422 uinttmp = (u_int32_t)old_first; 423 LOGCOPY_32(env,bp, &uinttmp); 424 bp += sizeof(uinttmp); 425 426 uinttmp = (u_int32_t)new_first; 427 LOGCOPY_32(env,bp, &uinttmp); 428 bp += sizeof(uinttmp); 429 430 uinttmp = (u_int32_t)old_cur; 431 LOGCOPY_32(env,bp, &uinttmp); 432 bp += sizeof(uinttmp); 433 434 uinttmp = (u_int32_t)new_cur; 435 LOGCOPY_32(env,bp, &uinttmp); 436 bp += sizeof(uinttmp); 437 438 if (metalsn != NULL) { 439 if (txnp != NULL) { 440 LOG *lp = env->lg_handle->reginfo.primary; 441 if (LOG_COMPARE(metalsn, &lp->lsn) >= 0 && (ret = 442 __log_check_page_lsn(env, dbp, metalsn)) != 0) 443 return (ret); 444 } 445 LOGCOPY_FROMLSN(env, bp, metalsn); 446 } else 447 memset(bp, 0, sizeof(*metalsn)); 448 bp += sizeof(*metalsn); 449 450 uinttmp = (u_int32_t)meta_pgno; 451 LOGCOPY_32(env,bp, &uinttmp); 452 bp += sizeof(uinttmp); 453 454 DB_ASSERT(env, 455 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 456 457 if (is_durable || txnp == NULL) { 458 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 459 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 460 *lsnp = *rlsnp; 461 if (rlsnp != ret_lsnp) 462 *ret_lsnp = *rlsnp; 463 } 464 } else { 465 ret = 0; 466#ifdef DIAGNOSTIC 467 /* 468 * Set the debug bit if we are going to log non-durable 469 * transactions so they will be ignored by recovery. 470 */ 471 memcpy(lr->data, logrec.data, logrec.size); 472 rectype |= DB_debug_FLAG; 473 LOGCOPY_32(env, logrec.data, &rectype); 474 475 if (!IS_REP_CLIENT(env)) 476 ret = __log_put(env, 477 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 478#endif 479 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 480 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 481 LSN_NOT_LOGGED(*ret_lsnp); 482 } 483 484#ifdef LOG_DIAGNOSTIC 485 if (ret != 0) 486 (void)__qam_mvptr_print(env, 487 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 488#endif 489 490#ifdef DIAGNOSTIC 491 __os_free(env, logrec.data); 492#else 493 if (is_durable || txnp == NULL) 494 __os_free(env, logrec.data); 495#endif 496 return (ret); 497} 498 499/* 500 * PUBLIC: int __qam_del_read __P((ENV *, DB **, void *, void *, 501 * PUBLIC: __qam_del_args **)); 502 */ 503int 504__qam_del_read(env, dbpp, td, recbuf, argpp) 505 ENV *env; 506 DB **dbpp; 507 void *td; 508 void *recbuf; 509 __qam_del_args **argpp; 510{ 511 __qam_del_args *argp; 512 u_int32_t uinttmp; 513 u_int8_t *bp; 514 int ret; 515 516 if ((ret = __os_malloc(env, 517 sizeof(__qam_del_args) + sizeof(DB_TXN), &argp)) != 0) 518 return (ret); 519 bp = recbuf; 520 argp->txnp = (DB_TXN *)&argp[1]; 521 memset(argp->txnp, 0, sizeof(DB_TXN)); 522 523 argp->txnp->td = td; 524 LOGCOPY_32(env, &argp->type, bp); 525 bp += sizeof(argp->type); 526 527 LOGCOPY_32(env, &argp->txnp->txnid, bp); 528 bp += sizeof(argp->txnp->txnid); 529 530 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 531 bp += sizeof(DB_LSN); 532 533 LOGCOPY_32(env, &uinttmp, bp); 534 argp->fileid = (int32_t)uinttmp; 535 bp += sizeof(uinttmp); 536 if (dbpp != NULL) { 537 *dbpp = NULL; 538 ret = __dbreg_id_to_db( 539 env, argp->txnp, dbpp, argp->fileid, 1); 540 } 541 542 LOGCOPY_TOLSN(env, &argp->lsn, bp); 543 bp += sizeof(DB_LSN); 544 545 LOGCOPY_32(env, &uinttmp, bp); 546 argp->pgno = (db_pgno_t)uinttmp; 547 bp += sizeof(uinttmp); 548 549 LOGCOPY_32(env, &argp->indx, bp); 550 bp += sizeof(argp->indx); 551 552 LOGCOPY_32(env, &uinttmp, bp); 553 argp->recno = (db_recno_t)uinttmp; 554 bp += sizeof(uinttmp); 555 556 *argpp = argp; 557 return (ret); 558} 559 560/* 561 * PUBLIC: int __qam_del_log __P((DB *, DB_TXN *, DB_LSN *, 562 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t)); 563 */ 564int 565__qam_del_log(dbp, txnp, ret_lsnp, flags, lsn, pgno, indx, recno) 566 DB *dbp; 567 DB_TXN *txnp; 568 DB_LSN *ret_lsnp; 569 u_int32_t flags; 570 DB_LSN * lsn; 571 db_pgno_t pgno; 572 u_int32_t indx; 573 db_recno_t recno; 574{ 575 DBT logrec; 576 DB_LSN *lsnp, null_lsn, *rlsnp; 577 DB_TXNLOGREC *lr; 578 ENV *env; 579 u_int32_t uinttmp, rectype, txn_num; 580 u_int npad; 581 u_int8_t *bp; 582 int is_durable, ret; 583 584 COMPQUIET(lr, NULL); 585 586 env = dbp->env; 587 rlsnp = ret_lsnp; 588 rectype = DB___qam_del; 589 npad = 0; 590 ret = 0; 591 592 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 593 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 594 if (txnp == NULL) 595 return (0); 596 is_durable = 0; 597 } else 598 is_durable = 1; 599 600 if (txnp == NULL) { 601 txn_num = 0; 602 lsnp = &null_lsn; 603 null_lsn.file = null_lsn.offset = 0; 604 } else { 605 if (TAILQ_FIRST(&txnp->kids) != NULL && 606 (ret = __txn_activekids(env, rectype, txnp)) != 0) 607 return (ret); 608 /* 609 * We need to assign begin_lsn while holding region mutex. 610 * That assignment is done inside the DbEnv->log_put call, 611 * so pass in the appropriate memory location to be filled 612 * in by the log_put code. 613 */ 614 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 615 txn_num = txnp->txnid; 616 } 617 618 DB_ASSERT(env, dbp->log_filename != NULL); 619 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 620 (ret = __dbreg_lazy_id(dbp)) != 0) 621 return (ret); 622 623 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 624 + sizeof(u_int32_t) 625 + sizeof(*lsn) 626 + sizeof(u_int32_t) 627 + sizeof(u_int32_t) 628 + sizeof(u_int32_t); 629 if (CRYPTO_ON(env)) { 630 npad = env->crypto_handle->adj_size(logrec.size); 631 logrec.size += npad; 632 } 633 634 if (is_durable || txnp == NULL) { 635 if ((ret = 636 __os_malloc(env, logrec.size, &logrec.data)) != 0) 637 return (ret); 638 } else { 639 if ((ret = __os_malloc(env, 640 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 641 return (ret); 642#ifdef DIAGNOSTIC 643 if ((ret = 644 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 645 __os_free(env, lr); 646 return (ret); 647 } 648#else 649 logrec.data = lr->data; 650#endif 651 } 652 if (npad > 0) 653 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 654 655 bp = logrec.data; 656 657 LOGCOPY_32(env, bp, &rectype); 658 bp += sizeof(rectype); 659 660 LOGCOPY_32(env, bp, &txn_num); 661 bp += sizeof(txn_num); 662 663 LOGCOPY_FROMLSN(env, bp, lsnp); 664 bp += sizeof(DB_LSN); 665 666 uinttmp = (u_int32_t)dbp->log_filename->id; 667 LOGCOPY_32(env, bp, &uinttmp); 668 bp += sizeof(uinttmp); 669 670 if (lsn != NULL) { 671 if (txnp != NULL) { 672 LOG *lp = env->lg_handle->reginfo.primary; 673 if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = 674 __log_check_page_lsn(env, dbp, lsn)) != 0) 675 return (ret); 676 } 677 LOGCOPY_FROMLSN(env, bp, lsn); 678 } else 679 memset(bp, 0, sizeof(*lsn)); 680 bp += sizeof(*lsn); 681 682 uinttmp = (u_int32_t)pgno; 683 LOGCOPY_32(env,bp, &uinttmp); 684 bp += sizeof(uinttmp); 685 686 LOGCOPY_32(env, bp, &indx); 687 bp += sizeof(indx); 688 689 uinttmp = (u_int32_t)recno; 690 LOGCOPY_32(env,bp, &uinttmp); 691 bp += sizeof(uinttmp); 692 693 DB_ASSERT(env, 694 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 695 696 if (is_durable || txnp == NULL) { 697 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 698 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 699 *lsnp = *rlsnp; 700 if (rlsnp != ret_lsnp) 701 *ret_lsnp = *rlsnp; 702 } 703 } else { 704 ret = 0; 705#ifdef DIAGNOSTIC 706 /* 707 * Set the debug bit if we are going to log non-durable 708 * transactions so they will be ignored by recovery. 709 */ 710 memcpy(lr->data, logrec.data, logrec.size); 711 rectype |= DB_debug_FLAG; 712 LOGCOPY_32(env, logrec.data, &rectype); 713 714 if (!IS_REP_CLIENT(env)) 715 ret = __log_put(env, 716 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 717#endif 718 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 719 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 720 LSN_NOT_LOGGED(*ret_lsnp); 721 } 722 723#ifdef LOG_DIAGNOSTIC 724 if (ret != 0) 725 (void)__qam_del_print(env, 726 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 727#endif 728 729#ifdef DIAGNOSTIC 730 __os_free(env, logrec.data); 731#else 732 if (is_durable || txnp == NULL) 733 __os_free(env, logrec.data); 734#endif 735 return (ret); 736} 737 738/* 739 * PUBLIC: int __qam_add_read __P((ENV *, DB **, void *, void *, 740 * PUBLIC: __qam_add_args **)); 741 */ 742int 743__qam_add_read(env, dbpp, td, recbuf, argpp) 744 ENV *env; 745 DB **dbpp; 746 void *td; 747 void *recbuf; 748 __qam_add_args **argpp; 749{ 750 __qam_add_args *argp; 751 u_int32_t uinttmp; 752 u_int8_t *bp; 753 int ret; 754 755 if ((ret = __os_malloc(env, 756 sizeof(__qam_add_args) + sizeof(DB_TXN), &argp)) != 0) 757 return (ret); 758 bp = recbuf; 759 argp->txnp = (DB_TXN *)&argp[1]; 760 memset(argp->txnp, 0, sizeof(DB_TXN)); 761 762 argp->txnp->td = td; 763 LOGCOPY_32(env, &argp->type, bp); 764 bp += sizeof(argp->type); 765 766 LOGCOPY_32(env, &argp->txnp->txnid, bp); 767 bp += sizeof(argp->txnp->txnid); 768 769 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 770 bp += sizeof(DB_LSN); 771 772 LOGCOPY_32(env, &uinttmp, bp); 773 argp->fileid = (int32_t)uinttmp; 774 bp += sizeof(uinttmp); 775 if (dbpp != NULL) { 776 *dbpp = NULL; 777 ret = __dbreg_id_to_db( 778 env, argp->txnp, dbpp, argp->fileid, 1); 779 } 780 781 LOGCOPY_TOLSN(env, &argp->lsn, bp); 782 bp += sizeof(DB_LSN); 783 784 LOGCOPY_32(env, &uinttmp, bp); 785 argp->pgno = (db_pgno_t)uinttmp; 786 bp += sizeof(uinttmp); 787 788 LOGCOPY_32(env, &argp->indx, bp); 789 bp += sizeof(argp->indx); 790 791 LOGCOPY_32(env, &uinttmp, bp); 792 argp->recno = (db_recno_t)uinttmp; 793 bp += sizeof(uinttmp); 794 795 memset(&argp->data, 0, sizeof(argp->data)); 796 LOGCOPY_32(env,&argp->data.size, bp); 797 bp += sizeof(u_int32_t); 798 argp->data.data = bp; 799 bp += argp->data.size; 800 801 LOGCOPY_32(env, &argp->vflag, bp); 802 bp += sizeof(argp->vflag); 803 804 memset(&argp->olddata, 0, sizeof(argp->olddata)); 805 LOGCOPY_32(env,&argp->olddata.size, bp); 806 bp += sizeof(u_int32_t); 807 argp->olddata.data = bp; 808 bp += argp->olddata.size; 809 810 *argpp = argp; 811 return (ret); 812} 813 814/* 815 * PUBLIC: int __qam_add_log __P((DB *, DB_TXN *, DB_LSN *, 816 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t, 817 * PUBLIC: const DBT *, u_int32_t, const DBT *)); 818 */ 819int 820__qam_add_log(dbp, txnp, ret_lsnp, flags, lsn, pgno, indx, recno, data, 821 vflag, olddata) 822 DB *dbp; 823 DB_TXN *txnp; 824 DB_LSN *ret_lsnp; 825 u_int32_t flags; 826 DB_LSN * lsn; 827 db_pgno_t pgno; 828 u_int32_t indx; 829 db_recno_t recno; 830 const DBT *data; 831 u_int32_t vflag; 832 const DBT *olddata; 833{ 834 DBT logrec; 835 DB_LSN *lsnp, null_lsn, *rlsnp; 836 DB_TXNLOGREC *lr; 837 ENV *env; 838 u_int32_t zero, uinttmp, rectype, txn_num; 839 u_int npad; 840 u_int8_t *bp; 841 int is_durable, ret; 842 843 COMPQUIET(lr, NULL); 844 845 env = dbp->env; 846 rlsnp = ret_lsnp; 847 rectype = DB___qam_add; 848 npad = 0; 849 ret = 0; 850 851 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 852 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 853 if (txnp == NULL) 854 return (0); 855 is_durable = 0; 856 } else 857 is_durable = 1; 858 859 if (txnp == NULL) { 860 txn_num = 0; 861 lsnp = &null_lsn; 862 null_lsn.file = null_lsn.offset = 0; 863 } else { 864 if (TAILQ_FIRST(&txnp->kids) != NULL && 865 (ret = __txn_activekids(env, rectype, txnp)) != 0) 866 return (ret); 867 /* 868 * We need to assign begin_lsn while holding region mutex. 869 * That assignment is done inside the DbEnv->log_put call, 870 * so pass in the appropriate memory location to be filled 871 * in by the log_put code. 872 */ 873 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 874 txn_num = txnp->txnid; 875 } 876 877 DB_ASSERT(env, dbp->log_filename != NULL); 878 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 879 (ret = __dbreg_lazy_id(dbp)) != 0) 880 return (ret); 881 882 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 883 + sizeof(u_int32_t) 884 + sizeof(*lsn) 885 + sizeof(u_int32_t) 886 + sizeof(u_int32_t) 887 + sizeof(u_int32_t) 888 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size) 889 + sizeof(u_int32_t) 890 + sizeof(u_int32_t) + (olddata == NULL ? 0 : olddata->size); 891 if (CRYPTO_ON(env)) { 892 npad = env->crypto_handle->adj_size(logrec.size); 893 logrec.size += npad; 894 } 895 896 if (is_durable || txnp == NULL) { 897 if ((ret = 898 __os_malloc(env, logrec.size, &logrec.data)) != 0) 899 return (ret); 900 } else { 901 if ((ret = __os_malloc(env, 902 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 903 return (ret); 904#ifdef DIAGNOSTIC 905 if ((ret = 906 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 907 __os_free(env, lr); 908 return (ret); 909 } 910#else 911 logrec.data = lr->data; 912#endif 913 } 914 if (npad > 0) 915 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 916 917 bp = logrec.data; 918 919 LOGCOPY_32(env, bp, &rectype); 920 bp += sizeof(rectype); 921 922 LOGCOPY_32(env, bp, &txn_num); 923 bp += sizeof(txn_num); 924 925 LOGCOPY_FROMLSN(env, bp, lsnp); 926 bp += sizeof(DB_LSN); 927 928 uinttmp = (u_int32_t)dbp->log_filename->id; 929 LOGCOPY_32(env, bp, &uinttmp); 930 bp += sizeof(uinttmp); 931 932 if (lsn != NULL) { 933 if (txnp != NULL) { 934 LOG *lp = env->lg_handle->reginfo.primary; 935 if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = 936 __log_check_page_lsn(env, dbp, lsn)) != 0) 937 return (ret); 938 } 939 LOGCOPY_FROMLSN(env, bp, lsn); 940 } else 941 memset(bp, 0, sizeof(*lsn)); 942 bp += sizeof(*lsn); 943 944 uinttmp = (u_int32_t)pgno; 945 LOGCOPY_32(env,bp, &uinttmp); 946 bp += sizeof(uinttmp); 947 948 LOGCOPY_32(env, bp, &indx); 949 bp += sizeof(indx); 950 951 uinttmp = (u_int32_t)recno; 952 LOGCOPY_32(env,bp, &uinttmp); 953 bp += sizeof(uinttmp); 954 955 if (data == NULL) { 956 zero = 0; 957 LOGCOPY_32(env, bp, &zero); 958 bp += sizeof(u_int32_t); 959 } else { 960 LOGCOPY_32(env, bp, &data->size); 961 bp += sizeof(data->size); 962 memcpy(bp, data->data, data->size); 963 bp += data->size; 964 } 965 966 LOGCOPY_32(env, bp, &vflag); 967 bp += sizeof(vflag); 968 969 if (olddata == NULL) { 970 zero = 0; 971 LOGCOPY_32(env, bp, &zero); 972 bp += sizeof(u_int32_t); 973 } else { 974 LOGCOPY_32(env, bp, &olddata->size); 975 bp += sizeof(olddata->size); 976 memcpy(bp, olddata->data, olddata->size); 977 bp += olddata->size; 978 } 979 980 DB_ASSERT(env, 981 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 982 983 if (is_durable || txnp == NULL) { 984 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 985 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 986 *lsnp = *rlsnp; 987 if (rlsnp != ret_lsnp) 988 *ret_lsnp = *rlsnp; 989 } 990 } else { 991 ret = 0; 992#ifdef DIAGNOSTIC 993 /* 994 * Set the debug bit if we are going to log non-durable 995 * transactions so they will be ignored by recovery. 996 */ 997 memcpy(lr->data, logrec.data, logrec.size); 998 rectype |= DB_debug_FLAG; 999 LOGCOPY_32(env, logrec.data, &rectype); 1000 1001 if (!IS_REP_CLIENT(env)) 1002 ret = __log_put(env, 1003 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1004#endif 1005 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1006 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1007 LSN_NOT_LOGGED(*ret_lsnp); 1008 } 1009 1010#ifdef LOG_DIAGNOSTIC 1011 if (ret != 0) 1012 (void)__qam_add_print(env, 1013 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1014#endif 1015 1016#ifdef DIAGNOSTIC 1017 __os_free(env, logrec.data); 1018#else 1019 if (is_durable || txnp == NULL) 1020 __os_free(env, logrec.data); 1021#endif 1022 return (ret); 1023} 1024 1025/* 1026 * PUBLIC: int __qam_delext_read __P((ENV *, DB **, void *, void *, 1027 * PUBLIC: __qam_delext_args **)); 1028 */ 1029int 1030__qam_delext_read(env, dbpp, td, recbuf, argpp) 1031 ENV *env; 1032 DB **dbpp; 1033 void *td; 1034 void *recbuf; 1035 __qam_delext_args **argpp; 1036{ 1037 __qam_delext_args *argp; 1038 u_int32_t uinttmp; 1039 u_int8_t *bp; 1040 int ret; 1041 1042 if ((ret = __os_malloc(env, 1043 sizeof(__qam_delext_args) + sizeof(DB_TXN), &argp)) != 0) 1044 return (ret); 1045 bp = recbuf; 1046 argp->txnp = (DB_TXN *)&argp[1]; 1047 memset(argp->txnp, 0, sizeof(DB_TXN)); 1048 1049 argp->txnp->td = td; 1050 LOGCOPY_32(env, &argp->type, bp); 1051 bp += sizeof(argp->type); 1052 1053 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1054 bp += sizeof(argp->txnp->txnid); 1055 1056 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1057 bp += sizeof(DB_LSN); 1058 1059 LOGCOPY_32(env, &uinttmp, bp); 1060 argp->fileid = (int32_t)uinttmp; 1061 bp += sizeof(uinttmp); 1062 if (dbpp != NULL) { 1063 *dbpp = NULL; 1064 ret = __dbreg_id_to_db( 1065 env, argp->txnp, dbpp, argp->fileid, 1); 1066 } 1067 1068 LOGCOPY_TOLSN(env, &argp->lsn, bp); 1069 bp += sizeof(DB_LSN); 1070 1071 LOGCOPY_32(env, &uinttmp, bp); 1072 argp->pgno = (db_pgno_t)uinttmp; 1073 bp += sizeof(uinttmp); 1074 1075 LOGCOPY_32(env, &argp->indx, bp); 1076 bp += sizeof(argp->indx); 1077 1078 LOGCOPY_32(env, &uinttmp, bp); 1079 argp->recno = (db_recno_t)uinttmp; 1080 bp += sizeof(uinttmp); 1081 1082 memset(&argp->data, 0, sizeof(argp->data)); 1083 LOGCOPY_32(env,&argp->data.size, bp); 1084 bp += sizeof(u_int32_t); 1085 argp->data.data = bp; 1086 bp += argp->data.size; 1087 1088 *argpp = argp; 1089 return (ret); 1090} 1091 1092/* 1093 * PUBLIC: int __qam_delext_log __P((DB *, DB_TXN *, DB_LSN *, 1094 * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t, 1095 * PUBLIC: const DBT *)); 1096 */ 1097int 1098__qam_delext_log(dbp, txnp, ret_lsnp, flags, lsn, pgno, indx, recno, data) 1099 DB *dbp; 1100 DB_TXN *txnp; 1101 DB_LSN *ret_lsnp; 1102 u_int32_t flags; 1103 DB_LSN * lsn; 1104 db_pgno_t pgno; 1105 u_int32_t indx; 1106 db_recno_t recno; 1107 const DBT *data; 1108{ 1109 DBT logrec; 1110 DB_LSN *lsnp, null_lsn, *rlsnp; 1111 DB_TXNLOGREC *lr; 1112 ENV *env; 1113 u_int32_t zero, uinttmp, rectype, txn_num; 1114 u_int npad; 1115 u_int8_t *bp; 1116 int is_durable, ret; 1117 1118 COMPQUIET(lr, NULL); 1119 1120 env = dbp->env; 1121 rlsnp = ret_lsnp; 1122 rectype = DB___qam_delext; 1123 npad = 0; 1124 ret = 0; 1125 1126 if (LF_ISSET(DB_LOG_NOT_DURABLE) || 1127 F_ISSET(dbp, DB_AM_NOT_DURABLE)) { 1128 if (txnp == NULL) 1129 return (0); 1130 is_durable = 0; 1131 } else 1132 is_durable = 1; 1133 1134 if (txnp == NULL) { 1135 txn_num = 0; 1136 lsnp = &null_lsn; 1137 null_lsn.file = null_lsn.offset = 0; 1138 } else { 1139 if (TAILQ_FIRST(&txnp->kids) != NULL && 1140 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1141 return (ret); 1142 /* 1143 * We need to assign begin_lsn while holding region mutex. 1144 * That assignment is done inside the DbEnv->log_put call, 1145 * so pass in the appropriate memory location to be filled 1146 * in by the log_put code. 1147 */ 1148 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1149 txn_num = txnp->txnid; 1150 } 1151 1152 DB_ASSERT(env, dbp->log_filename != NULL); 1153 if (dbp->log_filename->id == DB_LOGFILEID_INVALID && 1154 (ret = __dbreg_lazy_id(dbp)) != 0) 1155 return (ret); 1156 1157 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1158 + sizeof(u_int32_t) 1159 + sizeof(*lsn) 1160 + sizeof(u_int32_t) 1161 + sizeof(u_int32_t) 1162 + sizeof(u_int32_t) 1163 + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); 1164 if (CRYPTO_ON(env)) { 1165 npad = env->crypto_handle->adj_size(logrec.size); 1166 logrec.size += npad; 1167 } 1168 1169 if (is_durable || txnp == NULL) { 1170 if ((ret = 1171 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1172 return (ret); 1173 } else { 1174 if ((ret = __os_malloc(env, 1175 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1176 return (ret); 1177#ifdef DIAGNOSTIC 1178 if ((ret = 1179 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1180 __os_free(env, lr); 1181 return (ret); 1182 } 1183#else 1184 logrec.data = lr->data; 1185#endif 1186 } 1187 if (npad > 0) 1188 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1189 1190 bp = logrec.data; 1191 1192 LOGCOPY_32(env, bp, &rectype); 1193 bp += sizeof(rectype); 1194 1195 LOGCOPY_32(env, bp, &txn_num); 1196 bp += sizeof(txn_num); 1197 1198 LOGCOPY_FROMLSN(env, bp, lsnp); 1199 bp += sizeof(DB_LSN); 1200 1201 uinttmp = (u_int32_t)dbp->log_filename->id; 1202 LOGCOPY_32(env, bp, &uinttmp); 1203 bp += sizeof(uinttmp); 1204 1205 if (lsn != NULL) { 1206 if (txnp != NULL) { 1207 LOG *lp = env->lg_handle->reginfo.primary; 1208 if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = 1209 __log_check_page_lsn(env, dbp, lsn)) != 0) 1210 return (ret); 1211 } 1212 LOGCOPY_FROMLSN(env, bp, lsn); 1213 } else 1214 memset(bp, 0, sizeof(*lsn)); 1215 bp += sizeof(*lsn); 1216 1217 uinttmp = (u_int32_t)pgno; 1218 LOGCOPY_32(env,bp, &uinttmp); 1219 bp += sizeof(uinttmp); 1220 1221 LOGCOPY_32(env, bp, &indx); 1222 bp += sizeof(indx); 1223 1224 uinttmp = (u_int32_t)recno; 1225 LOGCOPY_32(env,bp, &uinttmp); 1226 bp += sizeof(uinttmp); 1227 1228 if (data == NULL) { 1229 zero = 0; 1230 LOGCOPY_32(env, bp, &zero); 1231 bp += sizeof(u_int32_t); 1232 } else { 1233 LOGCOPY_32(env, bp, &data->size); 1234 bp += sizeof(data->size); 1235 memcpy(bp, data->data, data->size); 1236 bp += data->size; 1237 } 1238 1239 DB_ASSERT(env, 1240 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1241 1242 if (is_durable || txnp == NULL) { 1243 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1244 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1245 *lsnp = *rlsnp; 1246 if (rlsnp != ret_lsnp) 1247 *ret_lsnp = *rlsnp; 1248 } 1249 } else { 1250 ret = 0; 1251#ifdef DIAGNOSTIC 1252 /* 1253 * Set the debug bit if we are going to log non-durable 1254 * transactions so they will be ignored by recovery. 1255 */ 1256 memcpy(lr->data, logrec.data, logrec.size); 1257 rectype |= DB_debug_FLAG; 1258 LOGCOPY_32(env, logrec.data, &rectype); 1259 1260 if (!IS_REP_CLIENT(env)) 1261 ret = __log_put(env, 1262 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1263#endif 1264 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1265 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1266 LSN_NOT_LOGGED(*ret_lsnp); 1267 } 1268 1269#ifdef LOG_DIAGNOSTIC 1270 if (ret != 0) 1271 (void)__qam_delext_print(env, 1272 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1273#endif 1274 1275#ifdef DIAGNOSTIC 1276 __os_free(env, logrec.data); 1277#else 1278 if (is_durable || txnp == NULL) 1279 __os_free(env, logrec.data); 1280#endif 1281 return (ret); 1282} 1283 1284/* 1285 * PUBLIC: int __qam_init_recover __P((ENV *, DB_DISTAB *)); 1286 */ 1287int 1288__qam_init_recover(env, dtabp) 1289 ENV *env; 1290 DB_DISTAB *dtabp; 1291{ 1292 int ret; 1293 1294 if ((ret = __db_add_recovery_int(env, dtabp, 1295 __qam_incfirst_recover, DB___qam_incfirst)) != 0) 1296 return (ret); 1297 if ((ret = __db_add_recovery_int(env, dtabp, 1298 __qam_mvptr_recover, DB___qam_mvptr)) != 0) 1299 return (ret); 1300 if ((ret = __db_add_recovery_int(env, dtabp, 1301 __qam_del_recover, DB___qam_del)) != 0) 1302 return (ret); 1303 if ((ret = __db_add_recovery_int(env, dtabp, 1304 __qam_add_recover, DB___qam_add)) != 0) 1305 return (ret); 1306 if ((ret = __db_add_recovery_int(env, dtabp, 1307 __qam_delext_recover, DB___qam_delext)) != 0) 1308 return (ret); 1309 return (0); 1310} 1311