Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

db_auto.c

00001 /* Do not edit: automatically built by gen_rec.awk. */
00002 
00003 #include "db_config.h"
00004 
00005 #ifndef NO_SYSTEM_INCLUDES
00006 #include <sys/types.h>
00007 
00008 #include <ctype.h>
00009 #include <string.h>
00010 #endif
00011 
00012 #include "db_int.h"
00013 #include "dbinc/crypto.h"
00014 #include "dbinc/db_page.h"
00015 #include "dbinc/db_dispatch.h"
00016 #include "dbinc/db_am.h"
00017 #include "dbinc/log.h"
00018 #include "dbinc/txn.h"
00019 
00020 /*
00021  * PUBLIC: int __db_addrem_log __P((DB *, DB_TXN *, DB_LSN *,
00022  * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, u_int32_t, u_int32_t,
00023  * PUBLIC:     const DBT *, const DBT *, DB_LSN *));
00024  */
00025 int
00026 __db_addrem_log(dbp, txnid, ret_lsnp, flags,
00027     opcode, pgno, indx, nbytes, hdr,
00028     dbt, pagelsn)
00029         DB *dbp;
00030         DB_TXN *txnid;
00031         DB_LSN *ret_lsnp;
00032         u_int32_t flags;
00033         u_int32_t opcode;
00034         db_pgno_t pgno;
00035         u_int32_t indx;
00036         u_int32_t nbytes;
00037         const DBT *hdr;
00038         const DBT *dbt;
00039         DB_LSN * pagelsn;
00040 {
00041         DBT logrec;
00042         DB_ENV *dbenv;
00043         DB_TXNLOGREC *lr;
00044         DB_LSN *lsnp, null_lsn, *rlsnp;
00045         u_int32_t zero, uinttmp, rectype, txn_num;
00046         u_int npad;
00047         u_int8_t *bp;
00048         int is_durable, ret;
00049 
00050         dbenv = dbp->dbenv;
00051         COMPQUIET(lr, NULL);
00052 
00053         rectype = DB___db_addrem;
00054         npad = 0;
00055         rlsnp = ret_lsnp;
00056 
00057         ret = 0;
00058 
00059         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
00060             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
00061                 is_durable = 0;
00062         } else
00063                 is_durable = 1;
00064 
00065         if (txnid == NULL) {
00066                 txn_num = 0;
00067                 lsnp = &null_lsn;
00068                 null_lsn.file = null_lsn.offset = 0;
00069         } else {
00070                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00071                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00072                         return (ret);
00073                 /*
00074                  * We need to assign begin_lsn while holding region mutex.
00075                  * That assignment is done inside the DbEnv->log_put call,
00076                  * so pass in the appropriate memory location to be filled
00077                  * in by the log_put code.
00078                  */
00079                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00080                 txn_num = txnid->txnid;
00081         }
00082 
00083         DB_ASSERT(dbp->log_filename != NULL);
00084         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
00085             (ret = __dbreg_lazy_id(dbp)) != 0)
00086                 return (ret);
00087 
00088         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00089             + sizeof(u_int32_t)
00090             + sizeof(u_int32_t)
00091             + sizeof(u_int32_t)
00092             + sizeof(u_int32_t)
00093             + sizeof(u_int32_t)
00094             + sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size)
00095             + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size)
00096             + sizeof(*pagelsn);
00097         if (CRYPTO_ON(dbenv)) {
00098                 npad =
00099                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00100                 logrec.size += npad;
00101         }
00102 
00103         if (is_durable || txnid == NULL) {
00104                 if ((ret =
00105                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00106                         return (ret);
00107         } else {
00108                 if ((ret = __os_malloc(dbenv,
00109                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00110                         return (ret);
00111 #ifdef DIAGNOSTIC
00112                 if ((ret =
00113                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00114                         __os_free(dbenv, lr);
00115                         return (ret);
00116                 }
00117 #else
00118                 logrec.data = lr->data;
00119 #endif
00120         }
00121         if (npad > 0)
00122                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00123 
00124         bp = logrec.data;
00125 
00126         memcpy(bp, &rectype, sizeof(rectype));
00127         bp += sizeof(rectype);
00128 
00129         memcpy(bp, &txn_num, sizeof(txn_num));
00130         bp += sizeof(txn_num);
00131 
00132         memcpy(bp, lsnp, sizeof(DB_LSN));
00133         bp += sizeof(DB_LSN);
00134 
00135         uinttmp = (u_int32_t)opcode;
00136         memcpy(bp, &uinttmp, sizeof(uinttmp));
00137         bp += sizeof(uinttmp);
00138 
00139         uinttmp = (u_int32_t)dbp->log_filename->id;
00140         memcpy(bp, &uinttmp, sizeof(uinttmp));
00141         bp += sizeof(uinttmp);
00142 
00143         uinttmp = (u_int32_t)pgno;
00144         memcpy(bp, &uinttmp, sizeof(uinttmp));
00145         bp += sizeof(uinttmp);
00146 
00147         uinttmp = (u_int32_t)indx;
00148         memcpy(bp, &uinttmp, sizeof(uinttmp));
00149         bp += sizeof(uinttmp);
00150 
00151         uinttmp = (u_int32_t)nbytes;
00152         memcpy(bp, &uinttmp, sizeof(uinttmp));
00153         bp += sizeof(uinttmp);
00154 
00155         if (hdr == NULL) {
00156                 zero = 0;
00157                 memcpy(bp, &zero, sizeof(u_int32_t));
00158                 bp += sizeof(u_int32_t);
00159         } else {
00160                 memcpy(bp, &hdr->size, sizeof(hdr->size));
00161                 bp += sizeof(hdr->size);
00162                 memcpy(bp, hdr->data, hdr->size);
00163                 bp += hdr->size;
00164         }
00165 
00166         if (dbt == NULL) {
00167                 zero = 0;
00168                 memcpy(bp, &zero, sizeof(u_int32_t));
00169                 bp += sizeof(u_int32_t);
00170         } else {
00171                 memcpy(bp, &dbt->size, sizeof(dbt->size));
00172                 bp += sizeof(dbt->size);
00173                 memcpy(bp, dbt->data, dbt->size);
00174                 bp += dbt->size;
00175         }
00176 
00177         if (pagelsn != NULL)
00178                 memcpy(bp, pagelsn, sizeof(*pagelsn));
00179         else
00180                 memset(bp, 0, sizeof(*pagelsn));
00181         bp += sizeof(*pagelsn);
00182 
00183         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00184 
00185         if (is_durable || txnid == NULL) {
00186                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00187                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00188                         *lsnp = *rlsnp;
00189                         if (rlsnp != ret_lsnp)
00190                                  *ret_lsnp = *rlsnp;
00191                 }
00192         } else {
00193 #ifdef DIAGNOSTIC
00194                 /*
00195                  * Set the debug bit if we are going to log non-durable
00196                  * transactions so they will be ignored by recovery.
00197                  */
00198                 memcpy(lr->data, logrec.data, logrec.size);
00199                 rectype |= DB_debug_FLAG;
00200                 memcpy(logrec.data, &rectype, sizeof(rectype));
00201 
00202                 ret = __log_put(dbenv,
00203                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00204 #else
00205                 ret = 0;
00206 #endif
00207                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00208                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00209                 LSN_NOT_LOGGED(*ret_lsnp);
00210         }
00211 
00212 #ifdef LOG_DIAGNOSTIC
00213         if (ret != 0)
00214                 (void)__db_addrem_print(dbenv,
00215                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00216 #endif
00217 
00218 #ifdef DIAGNOSTIC
00219         __os_free(dbenv, logrec.data);
00220 #else
00221         if (is_durable || txnid == NULL)
00222                 __os_free(dbenv, logrec.data);
00223 #endif
00224         return (ret);
00225 }
00226 
00227 /*
00228  * PUBLIC: int __db_addrem_read __P((DB_ENV *, void *, __db_addrem_args **));
00229  */
00230 int
00231 __db_addrem_read(dbenv, recbuf, argpp)
00232         DB_ENV *dbenv;
00233         void *recbuf;
00234         __db_addrem_args **argpp;
00235 {
00236         __db_addrem_args *argp;
00237         u_int32_t uinttmp;
00238         u_int8_t *bp;
00239         int ret;
00240 
00241         if ((ret = __os_malloc(dbenv,
00242             sizeof(__db_addrem_args) + sizeof(DB_TXN), &argp)) != 0)
00243                 return (ret);
00244         bp = recbuf;
00245         argp->txnid = (DB_TXN *)&argp[1];
00246 
00247         memcpy(&argp->type, bp, sizeof(argp->type));
00248         bp += sizeof(argp->type);
00249 
00250         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
00251         bp += sizeof(argp->txnid->txnid);
00252 
00253         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00254         bp += sizeof(DB_LSN);
00255 
00256         memcpy(&uinttmp, bp, sizeof(uinttmp));
00257         argp->opcode = (u_int32_t)uinttmp;
00258         bp += sizeof(uinttmp);
00259 
00260         memcpy(&uinttmp, bp, sizeof(uinttmp));
00261         argp->fileid = (int32_t)uinttmp;
00262         bp += sizeof(uinttmp);
00263 
00264         memcpy(&uinttmp, bp, sizeof(uinttmp));
00265         argp->pgno = (db_pgno_t)uinttmp;
00266         bp += sizeof(uinttmp);
00267 
00268         memcpy(&uinttmp, bp, sizeof(uinttmp));
00269         argp->indx = (u_int32_t)uinttmp;
00270         bp += sizeof(uinttmp);
00271 
00272         memcpy(&uinttmp, bp, sizeof(uinttmp));
00273         argp->nbytes = (u_int32_t)uinttmp;
00274         bp += sizeof(uinttmp);
00275 
00276         memset(&argp->hdr, 0, sizeof(argp->hdr));
00277         memcpy(&argp->hdr.size, bp, sizeof(u_int32_t));
00278         bp += sizeof(u_int32_t);
00279         argp->hdr.data = bp;
00280         bp += argp->hdr.size;
00281 
00282         memset(&argp->dbt, 0, sizeof(argp->dbt));
00283         memcpy(&argp->dbt.size, bp, sizeof(u_int32_t));
00284         bp += sizeof(u_int32_t);
00285         argp->dbt.data = bp;
00286         bp += argp->dbt.size;
00287 
00288         memcpy(&argp->pagelsn, bp,  sizeof(argp->pagelsn));
00289         bp += sizeof(argp->pagelsn);
00290 
00291         *argpp = argp;
00292         return (0);
00293 }
00294 
00295 /*
00296  * PUBLIC: int __db_big_log __P((DB *, DB_TXN *, DB_LSN *,
00297  * PUBLIC:     u_int32_t, u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t,
00298  * PUBLIC:     const DBT *, DB_LSN *, DB_LSN *, DB_LSN *));
00299  */
00300 int
00301 __db_big_log(dbp, txnid, ret_lsnp, flags,
00302     opcode, pgno, prev_pgno, next_pgno, dbt,
00303     pagelsn, prevlsn, nextlsn)
00304         DB *dbp;
00305         DB_TXN *txnid;
00306         DB_LSN *ret_lsnp;
00307         u_int32_t flags;
00308         u_int32_t opcode;
00309         db_pgno_t pgno;
00310         db_pgno_t prev_pgno;
00311         db_pgno_t next_pgno;
00312         const DBT *dbt;
00313         DB_LSN * pagelsn;
00314         DB_LSN * prevlsn;
00315         DB_LSN * nextlsn;
00316 {
00317         DBT logrec;
00318         DB_ENV *dbenv;
00319         DB_TXNLOGREC *lr;
00320         DB_LSN *lsnp, null_lsn, *rlsnp;
00321         u_int32_t zero, uinttmp, rectype, txn_num;
00322         u_int npad;
00323         u_int8_t *bp;
00324         int is_durable, ret;
00325 
00326         dbenv = dbp->dbenv;
00327         COMPQUIET(lr, NULL);
00328 
00329         rectype = DB___db_big;
00330         npad = 0;
00331         rlsnp = ret_lsnp;
00332 
00333         ret = 0;
00334 
00335         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
00336             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
00337                 is_durable = 0;
00338         } else
00339                 is_durable = 1;
00340 
00341         if (txnid == NULL) {
00342                 txn_num = 0;
00343                 lsnp = &null_lsn;
00344                 null_lsn.file = null_lsn.offset = 0;
00345         } else {
00346                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00347                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00348                         return (ret);
00349                 /*
00350                  * We need to assign begin_lsn while holding region mutex.
00351                  * That assignment is done inside the DbEnv->log_put call,
00352                  * so pass in the appropriate memory location to be filled
00353                  * in by the log_put code.
00354                  */
00355                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00356                 txn_num = txnid->txnid;
00357         }
00358 
00359         DB_ASSERT(dbp->log_filename != NULL);
00360         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
00361             (ret = __dbreg_lazy_id(dbp)) != 0)
00362                 return (ret);
00363 
00364         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00365             + sizeof(u_int32_t)
00366             + sizeof(u_int32_t)
00367             + sizeof(u_int32_t)
00368             + sizeof(u_int32_t)
00369             + sizeof(u_int32_t)
00370             + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size)
00371             + sizeof(*pagelsn)
00372             + sizeof(*prevlsn)
00373             + sizeof(*nextlsn);
00374         if (CRYPTO_ON(dbenv)) {
00375                 npad =
00376                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00377                 logrec.size += npad;
00378         }
00379 
00380         if (is_durable || txnid == NULL) {
00381                 if ((ret =
00382                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00383                         return (ret);
00384         } else {
00385                 if ((ret = __os_malloc(dbenv,
00386                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00387                         return (ret);
00388 #ifdef DIAGNOSTIC
00389                 if ((ret =
00390                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00391                         __os_free(dbenv, lr);
00392                         return (ret);
00393                 }
00394 #else
00395                 logrec.data = lr->data;
00396 #endif
00397         }
00398         if (npad > 0)
00399                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00400 
00401         bp = logrec.data;
00402 
00403         memcpy(bp, &rectype, sizeof(rectype));
00404         bp += sizeof(rectype);
00405 
00406         memcpy(bp, &txn_num, sizeof(txn_num));
00407         bp += sizeof(txn_num);
00408 
00409         memcpy(bp, lsnp, sizeof(DB_LSN));
00410         bp += sizeof(DB_LSN);
00411 
00412         uinttmp = (u_int32_t)opcode;
00413         memcpy(bp, &uinttmp, sizeof(uinttmp));
00414         bp += sizeof(uinttmp);
00415 
00416         uinttmp = (u_int32_t)dbp->log_filename->id;
00417         memcpy(bp, &uinttmp, sizeof(uinttmp));
00418         bp += sizeof(uinttmp);
00419 
00420         uinttmp = (u_int32_t)pgno;
00421         memcpy(bp, &uinttmp, sizeof(uinttmp));
00422         bp += sizeof(uinttmp);
00423 
00424         uinttmp = (u_int32_t)prev_pgno;
00425         memcpy(bp, &uinttmp, sizeof(uinttmp));
00426         bp += sizeof(uinttmp);
00427 
00428         uinttmp = (u_int32_t)next_pgno;
00429         memcpy(bp, &uinttmp, sizeof(uinttmp));
00430         bp += sizeof(uinttmp);
00431 
00432         if (dbt == NULL) {
00433                 zero = 0;
00434                 memcpy(bp, &zero, sizeof(u_int32_t));
00435                 bp += sizeof(u_int32_t);
00436         } else {
00437                 memcpy(bp, &dbt->size, sizeof(dbt->size));
00438                 bp += sizeof(dbt->size);
00439                 memcpy(bp, dbt->data, dbt->size);
00440                 bp += dbt->size;
00441         }
00442 
00443         if (pagelsn != NULL)
00444                 memcpy(bp, pagelsn, sizeof(*pagelsn));
00445         else
00446                 memset(bp, 0, sizeof(*pagelsn));
00447         bp += sizeof(*pagelsn);
00448 
00449         if (prevlsn != NULL)
00450                 memcpy(bp, prevlsn, sizeof(*prevlsn));
00451         else
00452                 memset(bp, 0, sizeof(*prevlsn));
00453         bp += sizeof(*prevlsn);
00454 
00455         if (nextlsn != NULL)
00456                 memcpy(bp, nextlsn, sizeof(*nextlsn));
00457         else
00458                 memset(bp, 0, sizeof(*nextlsn));
00459         bp += sizeof(*nextlsn);
00460 
00461         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00462 
00463         if (is_durable || txnid == NULL) {
00464                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00465                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00466                         *lsnp = *rlsnp;
00467                         if (rlsnp != ret_lsnp)
00468                                  *ret_lsnp = *rlsnp;
00469                 }
00470         } else {
00471 #ifdef DIAGNOSTIC
00472                 /*
00473                  * Set the debug bit if we are going to log non-durable
00474                  * transactions so they will be ignored by recovery.
00475                  */
00476                 memcpy(lr->data, logrec.data, logrec.size);
00477                 rectype |= DB_debug_FLAG;
00478                 memcpy(logrec.data, &rectype, sizeof(rectype));
00479 
00480                 ret = __log_put(dbenv,
00481                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00482 #else
00483                 ret = 0;
00484 #endif
00485                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00486                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00487                 LSN_NOT_LOGGED(*ret_lsnp);
00488         }
00489 
00490 #ifdef LOG_DIAGNOSTIC
00491         if (ret != 0)
00492                 (void)__db_big_print(dbenv,
00493                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00494 #endif
00495 
00496 #ifdef DIAGNOSTIC
00497         __os_free(dbenv, logrec.data);
00498 #else
00499         if (is_durable || txnid == NULL)
00500                 __os_free(dbenv, logrec.data);
00501 #endif
00502         return (ret);
00503 }
00504 
00505 /*
00506  * PUBLIC: int __db_big_read __P((DB_ENV *, void *, __db_big_args **));
00507  */
00508 int
00509 __db_big_read(dbenv, recbuf, argpp)
00510         DB_ENV *dbenv;
00511         void *recbuf;
00512         __db_big_args **argpp;
00513 {
00514         __db_big_args *argp;
00515         u_int32_t uinttmp;
00516         u_int8_t *bp;
00517         int ret;
00518 
00519         if ((ret = __os_malloc(dbenv,
00520             sizeof(__db_big_args) + sizeof(DB_TXN), &argp)) != 0)
00521                 return (ret);
00522         bp = recbuf;
00523         argp->txnid = (DB_TXN *)&argp[1];
00524 
00525         memcpy(&argp->type, bp, sizeof(argp->type));
00526         bp += sizeof(argp->type);
00527 
00528         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
00529         bp += sizeof(argp->txnid->txnid);
00530 
00531         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00532         bp += sizeof(DB_LSN);
00533 
00534         memcpy(&uinttmp, bp, sizeof(uinttmp));
00535         argp->opcode = (u_int32_t)uinttmp;
00536         bp += sizeof(uinttmp);
00537 
00538         memcpy(&uinttmp, bp, sizeof(uinttmp));
00539         argp->fileid = (int32_t)uinttmp;
00540         bp += sizeof(uinttmp);
00541 
00542         memcpy(&uinttmp, bp, sizeof(uinttmp));
00543         argp->pgno = (db_pgno_t)uinttmp;
00544         bp += sizeof(uinttmp);
00545 
00546         memcpy(&uinttmp, bp, sizeof(uinttmp));
00547         argp->prev_pgno = (db_pgno_t)uinttmp;
00548         bp += sizeof(uinttmp);
00549 
00550         memcpy(&uinttmp, bp, sizeof(uinttmp));
00551         argp->next_pgno = (db_pgno_t)uinttmp;
00552         bp += sizeof(uinttmp);
00553 
00554         memset(&argp->dbt, 0, sizeof(argp->dbt));
00555         memcpy(&argp->dbt.size, bp, sizeof(u_int32_t));
00556         bp += sizeof(u_int32_t);
00557         argp->dbt.data = bp;
00558         bp += argp->dbt.size;
00559 
00560         memcpy(&argp->pagelsn, bp,  sizeof(argp->pagelsn));
00561         bp += sizeof(argp->pagelsn);
00562 
00563         memcpy(&argp->prevlsn, bp,  sizeof(argp->prevlsn));
00564         bp += sizeof(argp->prevlsn);
00565 
00566         memcpy(&argp->nextlsn, bp,  sizeof(argp->nextlsn));
00567         bp += sizeof(argp->nextlsn);
00568 
00569         *argpp = argp;
00570         return (0);
00571 }
00572 
00573 /*
00574  * PUBLIC: int __db_ovref_log __P((DB *, DB_TXN *, DB_LSN *,
00575  * PUBLIC:     u_int32_t, db_pgno_t, int32_t, DB_LSN *));
00576  */
00577 int
00578 __db_ovref_log(dbp, txnid, ret_lsnp, flags, pgno, adjust, lsn)
00579         DB *dbp;
00580         DB_TXN *txnid;
00581         DB_LSN *ret_lsnp;
00582         u_int32_t flags;
00583         db_pgno_t pgno;
00584         int32_t adjust;
00585         DB_LSN * lsn;
00586 {
00587         DBT logrec;
00588         DB_ENV *dbenv;
00589         DB_TXNLOGREC *lr;
00590         DB_LSN *lsnp, null_lsn, *rlsnp;
00591         u_int32_t uinttmp, rectype, txn_num;
00592         u_int npad;
00593         u_int8_t *bp;
00594         int is_durable, ret;
00595 
00596         dbenv = dbp->dbenv;
00597         COMPQUIET(lr, NULL);
00598 
00599         rectype = DB___db_ovref;
00600         npad = 0;
00601         rlsnp = ret_lsnp;
00602 
00603         ret = 0;
00604 
00605         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
00606             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
00607                 is_durable = 0;
00608         } else
00609                 is_durable = 1;
00610 
00611         if (txnid == NULL) {
00612                 txn_num = 0;
00613                 lsnp = &null_lsn;
00614                 null_lsn.file = null_lsn.offset = 0;
00615         } else {
00616                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00617                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00618                         return (ret);
00619                 /*
00620                  * We need to assign begin_lsn while holding region mutex.
00621                  * That assignment is done inside the DbEnv->log_put call,
00622                  * so pass in the appropriate memory location to be filled
00623                  * in by the log_put code.
00624                  */
00625                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00626                 txn_num = txnid->txnid;
00627         }
00628 
00629         DB_ASSERT(dbp->log_filename != NULL);
00630         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
00631             (ret = __dbreg_lazy_id(dbp)) != 0)
00632                 return (ret);
00633 
00634         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00635             + sizeof(u_int32_t)
00636             + sizeof(u_int32_t)
00637             + sizeof(u_int32_t)
00638             + sizeof(*lsn);
00639         if (CRYPTO_ON(dbenv)) {
00640                 npad =
00641                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00642                 logrec.size += npad;
00643         }
00644 
00645         if (is_durable || txnid == NULL) {
00646                 if ((ret =
00647                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00648                         return (ret);
00649         } else {
00650                 if ((ret = __os_malloc(dbenv,
00651                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00652                         return (ret);
00653 #ifdef DIAGNOSTIC
00654                 if ((ret =
00655                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00656                         __os_free(dbenv, lr);
00657                         return (ret);
00658                 }
00659 #else
00660                 logrec.data = lr->data;
00661 #endif
00662         }
00663         if (npad > 0)
00664                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00665 
00666         bp = logrec.data;
00667 
00668         memcpy(bp, &rectype, sizeof(rectype));
00669         bp += sizeof(rectype);
00670 
00671         memcpy(bp, &txn_num, sizeof(txn_num));
00672         bp += sizeof(txn_num);
00673 
00674         memcpy(bp, lsnp, sizeof(DB_LSN));
00675         bp += sizeof(DB_LSN);
00676 
00677         uinttmp = (u_int32_t)dbp->log_filename->id;
00678         memcpy(bp, &uinttmp, sizeof(uinttmp));
00679         bp += sizeof(uinttmp);
00680 
00681         uinttmp = (u_int32_t)pgno;
00682         memcpy(bp, &uinttmp, sizeof(uinttmp));
00683         bp += sizeof(uinttmp);
00684 
00685         uinttmp = (u_int32_t)adjust;
00686         memcpy(bp, &uinttmp, sizeof(uinttmp));
00687         bp += sizeof(uinttmp);
00688 
00689         if (lsn != NULL)
00690                 memcpy(bp, lsn, sizeof(*lsn));
00691         else
00692                 memset(bp, 0, sizeof(*lsn));
00693         bp += sizeof(*lsn);
00694 
00695         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00696 
00697         if (is_durable || txnid == NULL) {
00698                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00699                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00700                         *lsnp = *rlsnp;
00701                         if (rlsnp != ret_lsnp)
00702                                  *ret_lsnp = *rlsnp;
00703                 }
00704         } else {
00705 #ifdef DIAGNOSTIC
00706                 /*
00707                  * Set the debug bit if we are going to log non-durable
00708                  * transactions so they will be ignored by recovery.
00709                  */
00710                 memcpy(lr->data, logrec.data, logrec.size);
00711                 rectype |= DB_debug_FLAG;
00712                 memcpy(logrec.data, &rectype, sizeof(rectype));
00713 
00714                 ret = __log_put(dbenv,
00715                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00716 #else
00717                 ret = 0;
00718 #endif
00719                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00720                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00721                 LSN_NOT_LOGGED(*ret_lsnp);
00722         }
00723 
00724 #ifdef LOG_DIAGNOSTIC
00725         if (ret != 0)
00726                 (void)__db_ovref_print(dbenv,
00727                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00728 #endif
00729 
00730 #ifdef DIAGNOSTIC
00731         __os_free(dbenv, logrec.data);
00732 #else
00733         if (is_durable || txnid == NULL)
00734                 __os_free(dbenv, logrec.data);
00735 #endif
00736         return (ret);
00737 }
00738 
00739 /*
00740  * PUBLIC: int __db_ovref_read __P((DB_ENV *, void *, __db_ovref_args **));
00741  */
00742 int
00743 __db_ovref_read(dbenv, recbuf, argpp)
00744         DB_ENV *dbenv;
00745         void *recbuf;
00746         __db_ovref_args **argpp;
00747 {
00748         __db_ovref_args *argp;
00749         u_int32_t uinttmp;
00750         u_int8_t *bp;
00751         int ret;
00752 
00753         if ((ret = __os_malloc(dbenv,
00754             sizeof(__db_ovref_args) + sizeof(DB_TXN), &argp)) != 0)
00755                 return (ret);
00756         bp = recbuf;
00757         argp->txnid = (DB_TXN *)&argp[1];
00758 
00759         memcpy(&argp->type, bp, sizeof(argp->type));
00760         bp += sizeof(argp->type);
00761 
00762         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
00763         bp += sizeof(argp->txnid->txnid);
00764 
00765         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00766         bp += sizeof(DB_LSN);
00767 
00768         memcpy(&uinttmp, bp, sizeof(uinttmp));
00769         argp->fileid = (int32_t)uinttmp;
00770         bp += sizeof(uinttmp);
00771 
00772         memcpy(&uinttmp, bp, sizeof(uinttmp));
00773         argp->pgno = (db_pgno_t)uinttmp;
00774         bp += sizeof(uinttmp);
00775 
00776         memcpy(&uinttmp, bp, sizeof(uinttmp));
00777         argp->adjust = (int32_t)uinttmp;
00778         bp += sizeof(uinttmp);
00779 
00780         memcpy(&argp->lsn, bp,  sizeof(argp->lsn));
00781         bp += sizeof(argp->lsn);
00782 
00783         *argpp = argp;
00784         return (0);
00785 }
00786 
00787 /*
00788  * PUBLIC: int __db_debug_log __P((DB_ENV *, DB_TXN *, DB_LSN *,
00789  * PUBLIC:     u_int32_t, const DBT *, int32_t, const DBT *, const DBT *,
00790  * PUBLIC:     u_int32_t));
00791  */
00792 int
00793 __db_debug_log(dbenv, txnid, ret_lsnp, flags,
00794     op, fileid, key, data, arg_flags)
00795         DB_ENV *dbenv;
00796         DB_TXN *txnid;
00797         DB_LSN *ret_lsnp;
00798         u_int32_t flags;
00799         const DBT *op;
00800         int32_t fileid;
00801         const DBT *key;
00802         const DBT *data;
00803         u_int32_t arg_flags;
00804 {
00805         DBT logrec;
00806         DB_TXNLOGREC *lr;
00807         DB_LSN *lsnp, null_lsn, *rlsnp;
00808         u_int32_t zero, uinttmp, rectype, txn_num;
00809         u_int npad;
00810         u_int8_t *bp;
00811         int is_durable, ret;
00812 
00813         COMPQUIET(lr, NULL);
00814 
00815         rectype = DB___db_debug;
00816         npad = 0;
00817         rlsnp = ret_lsnp;
00818 
00819         ret = 0;
00820 
00821         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00822                 if (txnid == NULL)
00823                         return (0);
00824                 is_durable = 0;
00825         } else
00826                 is_durable = 1;
00827 
00828         if (txnid == NULL) {
00829                 txn_num = 0;
00830                 lsnp = &null_lsn;
00831                 null_lsn.file = null_lsn.offset = 0;
00832         } else {
00833                 /*
00834                  * We need to assign begin_lsn while holding region mutex.
00835                  * That assignment is done inside the DbEnv->log_put call,
00836                  * so pass in the appropriate memory location to be filled
00837                  * in by the log_put code.
00838                  */
00839                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00840                 txn_num = txnid->txnid;
00841         }
00842 
00843         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00844             + sizeof(u_int32_t) + (op == NULL ? 0 : op->size)
00845             + sizeof(u_int32_t)
00846             + sizeof(u_int32_t) + (key == NULL ? 0 : key->size)
00847             + sizeof(u_int32_t) + (data == NULL ? 0 : data->size)
00848             + sizeof(u_int32_t);
00849         if (CRYPTO_ON(dbenv)) {
00850                 npad =
00851                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00852                 logrec.size += npad;
00853         }
00854 
00855         if (is_durable || txnid == NULL) {
00856                 if ((ret =
00857                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00858                         return (ret);
00859         } else {
00860                 if ((ret = __os_malloc(dbenv,
00861                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00862                         return (ret);
00863 #ifdef DIAGNOSTIC
00864                 if ((ret =
00865                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00866                         __os_free(dbenv, lr);
00867                         return (ret);
00868                 }
00869 #else
00870                 logrec.data = lr->data;
00871 #endif
00872         }
00873         if (npad > 0)
00874                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00875 
00876         bp = logrec.data;
00877 
00878         memcpy(bp, &rectype, sizeof(rectype));
00879         bp += sizeof(rectype);
00880 
00881         memcpy(bp, &txn_num, sizeof(txn_num));
00882         bp += sizeof(txn_num);
00883 
00884         memcpy(bp, lsnp, sizeof(DB_LSN));
00885         bp += sizeof(DB_LSN);
00886 
00887         if (op == NULL) {
00888                 zero = 0;
00889                 memcpy(bp, &zero, sizeof(u_int32_t));
00890                 bp += sizeof(u_int32_t);
00891         } else {
00892                 memcpy(bp, &op->size, sizeof(op->size));
00893                 bp += sizeof(op->size);
00894                 memcpy(bp, op->data, op->size);
00895                 bp += op->size;
00896         }
00897 
00898         uinttmp = (u_int32_t)fileid;
00899         memcpy(bp, &uinttmp, sizeof(uinttmp));
00900         bp += sizeof(uinttmp);
00901 
00902         if (key == NULL) {
00903                 zero = 0;
00904                 memcpy(bp, &zero, sizeof(u_int32_t));
00905                 bp += sizeof(u_int32_t);
00906         } else {
00907                 memcpy(bp, &key->size, sizeof(key->size));
00908                 bp += sizeof(key->size);
00909                 memcpy(bp, key->data, key->size);
00910                 bp += key->size;
00911         }
00912 
00913         if (data == NULL) {
00914                 zero = 0;
00915                 memcpy(bp, &zero, sizeof(u_int32_t));
00916                 bp += sizeof(u_int32_t);
00917         } else {
00918                 memcpy(bp, &data->size, sizeof(data->size));
00919                 bp += sizeof(data->size);
00920                 memcpy(bp, data->data, data->size);
00921                 bp += data->size;
00922         }
00923 
00924         uinttmp = (u_int32_t)arg_flags;
00925         memcpy(bp, &uinttmp, sizeof(uinttmp));
00926         bp += sizeof(uinttmp);
00927 
00928         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00929 
00930         if (is_durable || txnid == NULL) {
00931                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00932                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00933                         *lsnp = *rlsnp;
00934                         if (rlsnp != ret_lsnp)
00935                                  *ret_lsnp = *rlsnp;
00936                 }
00937         } else {
00938 #ifdef DIAGNOSTIC
00939                 /*
00940                  * Set the debug bit if we are going to log non-durable
00941                  * transactions so they will be ignored by recovery.
00942                  */
00943                 memcpy(lr->data, logrec.data, logrec.size);
00944                 rectype |= DB_debug_FLAG;
00945                 memcpy(logrec.data, &rectype, sizeof(rectype));
00946 
00947                 ret = __log_put(dbenv,
00948                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00949 #else
00950                 ret = 0;
00951 #endif
00952                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00953                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00954                 LSN_NOT_LOGGED(*ret_lsnp);
00955         }
00956 
00957 #ifdef LOG_DIAGNOSTIC
00958         if (ret != 0)
00959                 (void)__db_debug_print(dbenv,
00960                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00961 #endif
00962 
00963 #ifdef DIAGNOSTIC
00964         __os_free(dbenv, logrec.data);
00965 #else
00966         if (is_durable || txnid == NULL)
00967                 __os_free(dbenv, logrec.data);
00968 #endif
00969         return (ret);
00970 }
00971 
00972 /*
00973  * PUBLIC: int __db_debug_read __P((DB_ENV *, void *, __db_debug_args **));
00974  */
00975 int
00976 __db_debug_read(dbenv, recbuf, argpp)
00977         DB_ENV *dbenv;
00978         void *recbuf;
00979         __db_debug_args **argpp;
00980 {
00981         __db_debug_args *argp;
00982         u_int32_t uinttmp;
00983         u_int8_t *bp;
00984         int ret;
00985 
00986         if ((ret = __os_malloc(dbenv,
00987             sizeof(__db_debug_args) + sizeof(DB_TXN), &argp)) != 0)
00988                 return (ret);
00989         bp = recbuf;
00990         argp->txnid = (DB_TXN *)&argp[1];
00991 
00992         memcpy(&argp->type, bp, sizeof(argp->type));
00993         bp += sizeof(argp->type);
00994 
00995         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
00996         bp += sizeof(argp->txnid->txnid);
00997 
00998         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00999         bp += sizeof(DB_LSN);
01000 
01001         memset(&argp->op, 0, sizeof(argp->op));
01002         memcpy(&argp->op.size, bp, sizeof(u_int32_t));
01003         bp += sizeof(u_int32_t);
01004         argp->op.data = bp;
01005         bp += argp->op.size;
01006 
01007         memcpy(&uinttmp, bp, sizeof(uinttmp));
01008         argp->fileid = (int32_t)uinttmp;
01009         bp += sizeof(uinttmp);
01010 
01011         memset(&argp->key, 0, sizeof(argp->key));
01012         memcpy(&argp->key.size, bp, sizeof(u_int32_t));
01013         bp += sizeof(u_int32_t);
01014         argp->key.data = bp;
01015         bp += argp->key.size;
01016 
01017         memset(&argp->data, 0, sizeof(argp->data));
01018         memcpy(&argp->data.size, bp, sizeof(u_int32_t));
01019         bp += sizeof(u_int32_t);
01020         argp->data.data = bp;
01021         bp += argp->data.size;
01022 
01023         memcpy(&uinttmp, bp, sizeof(uinttmp));
01024         argp->arg_flags = (u_int32_t)uinttmp;
01025         bp += sizeof(uinttmp);
01026 
01027         *argpp = argp;
01028         return (0);
01029 }
01030 
01031 /*
01032  * PUBLIC: int __db_noop_log __P((DB *, DB_TXN *, DB_LSN *,
01033  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *));
01034  */
01035 int
01036 __db_noop_log(dbp, txnid, ret_lsnp, flags, pgno, prevlsn)
01037         DB *dbp;
01038         DB_TXN *txnid;
01039         DB_LSN *ret_lsnp;
01040         u_int32_t flags;
01041         db_pgno_t pgno;
01042         DB_LSN * prevlsn;
01043 {
01044         DBT logrec;
01045         DB_ENV *dbenv;
01046         DB_TXNLOGREC *lr;
01047         DB_LSN *lsnp, null_lsn, *rlsnp;
01048         u_int32_t uinttmp, rectype, txn_num;
01049         u_int npad;
01050         u_int8_t *bp;
01051         int is_durable, ret;
01052 
01053         dbenv = dbp->dbenv;
01054         COMPQUIET(lr, NULL);
01055 
01056         rectype = DB___db_noop;
01057         npad = 0;
01058         rlsnp = ret_lsnp;
01059 
01060         ret = 0;
01061 
01062         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
01063             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
01064                 is_durable = 0;
01065         } else
01066                 is_durable = 1;
01067 
01068         if (txnid == NULL) {
01069                 txn_num = 0;
01070                 lsnp = &null_lsn;
01071                 null_lsn.file = null_lsn.offset = 0;
01072         } else {
01073                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
01074                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
01075                         return (ret);
01076                 /*
01077                  * We need to assign begin_lsn while holding region mutex.
01078                  * That assignment is done inside the DbEnv->log_put call,
01079                  * so pass in the appropriate memory location to be filled
01080                  * in by the log_put code.
01081                  */
01082                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
01083                 txn_num = txnid->txnid;
01084         }
01085 
01086         DB_ASSERT(dbp->log_filename != NULL);
01087         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
01088             (ret = __dbreg_lazy_id(dbp)) != 0)
01089                 return (ret);
01090 
01091         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
01092             + sizeof(u_int32_t)
01093             + sizeof(u_int32_t)
01094             + sizeof(*prevlsn);
01095         if (CRYPTO_ON(dbenv)) {
01096                 npad =
01097                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
01098                 logrec.size += npad;
01099         }
01100 
01101         if (is_durable || txnid == NULL) {
01102                 if ((ret =
01103                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
01104                         return (ret);
01105         } else {
01106                 if ((ret = __os_malloc(dbenv,
01107                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
01108                         return (ret);
01109 #ifdef DIAGNOSTIC
01110                 if ((ret =
01111                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
01112                         __os_free(dbenv, lr);
01113                         return (ret);
01114                 }
01115 #else
01116                 logrec.data = lr->data;
01117 #endif
01118         }
01119         if (npad > 0)
01120                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
01121 
01122         bp = logrec.data;
01123 
01124         memcpy(bp, &rectype, sizeof(rectype));
01125         bp += sizeof(rectype);
01126 
01127         memcpy(bp, &txn_num, sizeof(txn_num));
01128         bp += sizeof(txn_num);
01129 
01130         memcpy(bp, lsnp, sizeof(DB_LSN));
01131         bp += sizeof(DB_LSN);
01132 
01133         uinttmp = (u_int32_t)dbp->log_filename->id;
01134         memcpy(bp, &uinttmp, sizeof(uinttmp));
01135         bp += sizeof(uinttmp);
01136 
01137         uinttmp = (u_int32_t)pgno;
01138         memcpy(bp, &uinttmp, sizeof(uinttmp));
01139         bp += sizeof(uinttmp);
01140 
01141         if (prevlsn != NULL)
01142                 memcpy(bp, prevlsn, sizeof(*prevlsn));
01143         else
01144                 memset(bp, 0, sizeof(*prevlsn));
01145         bp += sizeof(*prevlsn);
01146 
01147         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
01148 
01149         if (is_durable || txnid == NULL) {
01150                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
01151                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
01152                         *lsnp = *rlsnp;
01153                         if (rlsnp != ret_lsnp)
01154                                  *ret_lsnp = *rlsnp;
01155                 }
01156         } else {
01157 #ifdef DIAGNOSTIC
01158                 /*
01159                  * Set the debug bit if we are going to log non-durable
01160                  * transactions so they will be ignored by recovery.
01161                  */
01162                 memcpy(lr->data, logrec.data, logrec.size);
01163                 rectype |= DB_debug_FLAG;
01164                 memcpy(logrec.data, &rectype, sizeof(rectype));
01165 
01166                 ret = __log_put(dbenv,
01167                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
01168 #else
01169                 ret = 0;
01170 #endif
01171                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
01172                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
01173                 LSN_NOT_LOGGED(*ret_lsnp);
01174         }
01175 
01176 #ifdef LOG_DIAGNOSTIC
01177         if (ret != 0)
01178                 (void)__db_noop_print(dbenv,
01179                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
01180 #endif
01181 
01182 #ifdef DIAGNOSTIC
01183         __os_free(dbenv, logrec.data);
01184 #else
01185         if (is_durable || txnid == NULL)
01186                 __os_free(dbenv, logrec.data);
01187 #endif
01188         return (ret);
01189 }
01190 
01191 /*
01192  * PUBLIC: int __db_noop_read __P((DB_ENV *, void *, __db_noop_args **));
01193  */
01194 int
01195 __db_noop_read(dbenv, recbuf, argpp)
01196         DB_ENV *dbenv;
01197         void *recbuf;
01198         __db_noop_args **argpp;
01199 {
01200         __db_noop_args *argp;
01201         u_int32_t uinttmp;
01202         u_int8_t *bp;
01203         int ret;
01204 
01205         if ((ret = __os_malloc(dbenv,
01206             sizeof(__db_noop_args) + sizeof(DB_TXN), &argp)) != 0)
01207                 return (ret);
01208         bp = recbuf;
01209         argp->txnid = (DB_TXN *)&argp[1];
01210 
01211         memcpy(&argp->type, bp, sizeof(argp->type));
01212         bp += sizeof(argp->type);
01213 
01214         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
01215         bp += sizeof(argp->txnid->txnid);
01216 
01217         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
01218         bp += sizeof(DB_LSN);
01219 
01220         memcpy(&uinttmp, bp, sizeof(uinttmp));
01221         argp->fileid = (int32_t)uinttmp;
01222         bp += sizeof(uinttmp);
01223 
01224         memcpy(&uinttmp, bp, sizeof(uinttmp));
01225         argp->pgno = (db_pgno_t)uinttmp;
01226         bp += sizeof(uinttmp);
01227 
01228         memcpy(&argp->prevlsn, bp,  sizeof(argp->prevlsn));
01229         bp += sizeof(argp->prevlsn);
01230 
01231         *argpp = argp;
01232         return (0);
01233 }
01234 
01235 /*
01236  * PUBLIC: int __db_pg_alloc_log __P((DB *, DB_TXN *, DB_LSN *,
01237  * PUBLIC:     u_int32_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, u_int32_t,
01238  * PUBLIC:     db_pgno_t, db_pgno_t));
01239  */
01240 int
01241 __db_pg_alloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, meta_pgno, page_lsn, pgno, ptype,
01242     next, last_pgno)
01243         DB *dbp;
01244         DB_TXN *txnid;
01245         DB_LSN *ret_lsnp;
01246         u_int32_t flags;
01247         DB_LSN * meta_lsn;
01248         db_pgno_t meta_pgno;
01249         DB_LSN * page_lsn;
01250         db_pgno_t pgno;
01251         u_int32_t ptype;
01252         db_pgno_t next;
01253         db_pgno_t last_pgno;
01254 {
01255         DBT logrec;
01256         DB_ENV *dbenv;
01257         DB_TXNLOGREC *lr;
01258         DB_LSN *lsnp, null_lsn, *rlsnp;
01259         u_int32_t uinttmp, rectype, txn_num;
01260         u_int npad;
01261         u_int8_t *bp;
01262         int is_durable, ret;
01263 
01264         dbenv = dbp->dbenv;
01265         COMPQUIET(lr, NULL);
01266 
01267         rectype = DB___db_pg_alloc;
01268         npad = 0;
01269         rlsnp = ret_lsnp;
01270 
01271         ret = 0;
01272 
01273         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
01274             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
01275                 is_durable = 0;
01276         } else
01277                 is_durable = 1;
01278 
01279         if (txnid == NULL) {
01280                 txn_num = 0;
01281                 lsnp = &null_lsn;
01282                 null_lsn.file = null_lsn.offset = 0;
01283         } else {
01284                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
01285                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
01286                         return (ret);
01287                 /*
01288                  * We need to assign begin_lsn while holding region mutex.
01289                  * That assignment is done inside the DbEnv->log_put call,
01290                  * so pass in the appropriate memory location to be filled
01291                  * in by the log_put code.
01292                  */
01293                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
01294                 txn_num = txnid->txnid;
01295         }
01296 
01297         DB_ASSERT(dbp->log_filename != NULL);
01298         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
01299             (ret = __dbreg_lazy_id(dbp)) != 0)
01300                 return (ret);
01301 
01302         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
01303             + sizeof(u_int32_t)
01304             + sizeof(*meta_lsn)
01305             + sizeof(u_int32_t)
01306             + sizeof(*page_lsn)
01307             + sizeof(u_int32_t)
01308             + sizeof(u_int32_t)
01309             + sizeof(u_int32_t)
01310             + sizeof(u_int32_t);
01311         if (CRYPTO_ON(dbenv)) {
01312                 npad =
01313                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
01314                 logrec.size += npad;
01315         }
01316 
01317         if (is_durable || txnid == NULL) {
01318                 if ((ret =
01319                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
01320                         return (ret);
01321         } else {
01322                 if ((ret = __os_malloc(dbenv,
01323                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
01324                         return (ret);
01325 #ifdef DIAGNOSTIC
01326                 if ((ret =
01327                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
01328                         __os_free(dbenv, lr);
01329                         return (ret);
01330                 }
01331 #else
01332                 logrec.data = lr->data;
01333 #endif
01334         }
01335         if (npad > 0)
01336                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
01337 
01338         bp = logrec.data;
01339 
01340         memcpy(bp, &rectype, sizeof(rectype));
01341         bp += sizeof(rectype);
01342 
01343         memcpy(bp, &txn_num, sizeof(txn_num));
01344         bp += sizeof(txn_num);
01345 
01346         memcpy(bp, lsnp, sizeof(DB_LSN));
01347         bp += sizeof(DB_LSN);
01348 
01349         uinttmp = (u_int32_t)dbp->log_filename->id;
01350         memcpy(bp, &uinttmp, sizeof(uinttmp));
01351         bp += sizeof(uinttmp);
01352 
01353         if (meta_lsn != NULL)
01354                 memcpy(bp, meta_lsn, sizeof(*meta_lsn));
01355         else
01356                 memset(bp, 0, sizeof(*meta_lsn));
01357         bp += sizeof(*meta_lsn);
01358 
01359         uinttmp = (u_int32_t)meta_pgno;
01360         memcpy(bp, &uinttmp, sizeof(uinttmp));
01361         bp += sizeof(uinttmp);
01362 
01363         if (page_lsn != NULL)
01364                 memcpy(bp, page_lsn, sizeof(*page_lsn));
01365         else
01366                 memset(bp, 0, sizeof(*page_lsn));
01367         bp += sizeof(*page_lsn);
01368 
01369         uinttmp = (u_int32_t)pgno;
01370         memcpy(bp, &uinttmp, sizeof(uinttmp));
01371         bp += sizeof(uinttmp);
01372 
01373         uinttmp = (u_int32_t)ptype;
01374         memcpy(bp, &uinttmp, sizeof(uinttmp));
01375         bp += sizeof(uinttmp);
01376 
01377         uinttmp = (u_int32_t)next;
01378         memcpy(bp, &uinttmp, sizeof(uinttmp));
01379         bp += sizeof(uinttmp);
01380 
01381         uinttmp = (u_int32_t)last_pgno;
01382         memcpy(bp, &uinttmp, sizeof(uinttmp));
01383         bp += sizeof(uinttmp);
01384 
01385         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
01386 
01387         if (is_durable || txnid == NULL) {
01388                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
01389                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
01390                         *lsnp = *rlsnp;
01391                         if (rlsnp != ret_lsnp)
01392                                  *ret_lsnp = *rlsnp;
01393                 }
01394         } else {
01395 #ifdef DIAGNOSTIC
01396                 /*
01397                  * Set the debug bit if we are going to log non-durable
01398                  * transactions so they will be ignored by recovery.
01399                  */
01400                 memcpy(lr->data, logrec.data, logrec.size);
01401                 rectype |= DB_debug_FLAG;
01402                 memcpy(logrec.data, &rectype, sizeof(rectype));
01403 
01404                 ret = __log_put(dbenv,
01405                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
01406 #else
01407                 ret = 0;
01408 #endif
01409                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
01410                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
01411                 LSN_NOT_LOGGED(*ret_lsnp);
01412         }
01413 
01414 #ifdef LOG_DIAGNOSTIC
01415         if (ret != 0)
01416                 (void)__db_pg_alloc_print(dbenv,
01417                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
01418 #endif
01419 
01420 #ifdef DIAGNOSTIC
01421         __os_free(dbenv, logrec.data);
01422 #else
01423         if (is_durable || txnid == NULL)
01424                 __os_free(dbenv, logrec.data);
01425 #endif
01426         return (ret);
01427 }
01428 
01429 /*
01430  * PUBLIC: int __db_pg_alloc_read __P((DB_ENV *, void *,
01431  * PUBLIC:     __db_pg_alloc_args **));
01432  */
01433 int
01434 __db_pg_alloc_read(dbenv, recbuf, argpp)
01435         DB_ENV *dbenv;
01436         void *recbuf;
01437         __db_pg_alloc_args **argpp;
01438 {
01439         __db_pg_alloc_args *argp;
01440         u_int32_t uinttmp;
01441         u_int8_t *bp;
01442         int ret;
01443 
01444         if ((ret = __os_malloc(dbenv,
01445             sizeof(__db_pg_alloc_args) + sizeof(DB_TXN), &argp)) != 0)
01446                 return (ret);
01447         bp = recbuf;
01448         argp->txnid = (DB_TXN *)&argp[1];
01449 
01450         memcpy(&argp->type, bp, sizeof(argp->type));
01451         bp += sizeof(argp->type);
01452 
01453         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
01454         bp += sizeof(argp->txnid->txnid);
01455 
01456         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
01457         bp += sizeof(DB_LSN);
01458 
01459         memcpy(&uinttmp, bp, sizeof(uinttmp));
01460         argp->fileid = (int32_t)uinttmp;
01461         bp += sizeof(uinttmp);
01462 
01463         memcpy(&argp->meta_lsn, bp,  sizeof(argp->meta_lsn));
01464         bp += sizeof(argp->meta_lsn);
01465 
01466         memcpy(&uinttmp, bp, sizeof(uinttmp));
01467         argp->meta_pgno = (db_pgno_t)uinttmp;
01468         bp += sizeof(uinttmp);
01469 
01470         memcpy(&argp->page_lsn, bp,  sizeof(argp->page_lsn));
01471         bp += sizeof(argp->page_lsn);
01472 
01473         memcpy(&uinttmp, bp, sizeof(uinttmp));
01474         argp->pgno = (db_pgno_t)uinttmp;
01475         bp += sizeof(uinttmp);
01476 
01477         memcpy(&uinttmp, bp, sizeof(uinttmp));
01478         argp->ptype = (u_int32_t)uinttmp;
01479         bp += sizeof(uinttmp);
01480 
01481         memcpy(&uinttmp, bp, sizeof(uinttmp));
01482         argp->next = (db_pgno_t)uinttmp;
01483         bp += sizeof(uinttmp);
01484 
01485         memcpy(&uinttmp, bp, sizeof(uinttmp));
01486         argp->last_pgno = (db_pgno_t)uinttmp;
01487         bp += sizeof(uinttmp);
01488 
01489         *argpp = argp;
01490         return (0);
01491 }
01492 
01493 /*
01494  * PUBLIC: int __db_pg_free_log __P((DB *, DB_TXN *, DB_LSN *,
01495  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *,
01496  * PUBLIC:     db_pgno_t, db_pgno_t));
01497  */
01498 int
01499 __db_pg_free_log(dbp, txnid, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next,
01500     last_pgno)
01501         DB *dbp;
01502         DB_TXN *txnid;
01503         DB_LSN *ret_lsnp;
01504         u_int32_t flags;
01505         db_pgno_t pgno;
01506         DB_LSN * meta_lsn;
01507         db_pgno_t meta_pgno;
01508         const DBT *header;
01509         db_pgno_t next;
01510         db_pgno_t last_pgno;
01511 {
01512         DBT logrec;
01513         DB_ENV *dbenv;
01514         DB_TXNLOGREC *lr;
01515         DB_LSN *lsnp, null_lsn, *rlsnp;
01516         u_int32_t zero, uinttmp, rectype, txn_num;
01517         u_int npad;
01518         u_int8_t *bp;
01519         int is_durable, ret;
01520 
01521         dbenv = dbp->dbenv;
01522         COMPQUIET(lr, NULL);
01523 
01524         rectype = DB___db_pg_free;
01525         npad = 0;
01526         rlsnp = ret_lsnp;
01527 
01528         ret = 0;
01529 
01530         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
01531             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
01532                 is_durable = 0;
01533         } else
01534                 is_durable = 1;
01535 
01536         if (txnid == NULL) {
01537                 txn_num = 0;
01538                 lsnp = &null_lsn;
01539                 null_lsn.file = null_lsn.offset = 0;
01540         } else {
01541                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
01542                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
01543                         return (ret);
01544                 /*
01545                  * We need to assign begin_lsn while holding region mutex.
01546                  * That assignment is done inside the DbEnv->log_put call,
01547                  * so pass in the appropriate memory location to be filled
01548                  * in by the log_put code.
01549                  */
01550                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
01551                 txn_num = txnid->txnid;
01552         }
01553 
01554         DB_ASSERT(dbp->log_filename != NULL);
01555         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
01556             (ret = __dbreg_lazy_id(dbp)) != 0)
01557                 return (ret);
01558 
01559         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
01560             + sizeof(u_int32_t)
01561             + sizeof(u_int32_t)
01562             + sizeof(*meta_lsn)
01563             + sizeof(u_int32_t)
01564             + sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
01565             + sizeof(u_int32_t)
01566             + sizeof(u_int32_t);
01567         if (CRYPTO_ON(dbenv)) {
01568                 npad =
01569                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
01570                 logrec.size += npad;
01571         }
01572 
01573         if (is_durable || txnid == NULL) {
01574                 if ((ret =
01575                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
01576                         return (ret);
01577         } else {
01578                 if ((ret = __os_malloc(dbenv,
01579                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
01580                         return (ret);
01581 #ifdef DIAGNOSTIC
01582                 if ((ret =
01583                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
01584                         __os_free(dbenv, lr);
01585                         return (ret);
01586                 }
01587 #else
01588                 logrec.data = lr->data;
01589 #endif
01590         }
01591         if (npad > 0)
01592                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
01593 
01594         bp = logrec.data;
01595 
01596         memcpy(bp, &rectype, sizeof(rectype));
01597         bp += sizeof(rectype);
01598 
01599         memcpy(bp, &txn_num, sizeof(txn_num));
01600         bp += sizeof(txn_num);
01601 
01602         memcpy(bp, lsnp, sizeof(DB_LSN));
01603         bp += sizeof(DB_LSN);
01604 
01605         uinttmp = (u_int32_t)dbp->log_filename->id;
01606         memcpy(bp, &uinttmp, sizeof(uinttmp));
01607         bp += sizeof(uinttmp);
01608 
01609         uinttmp = (u_int32_t)pgno;
01610         memcpy(bp, &uinttmp, sizeof(uinttmp));
01611         bp += sizeof(uinttmp);
01612 
01613         if (meta_lsn != NULL)
01614                 memcpy(bp, meta_lsn, sizeof(*meta_lsn));
01615         else
01616                 memset(bp, 0, sizeof(*meta_lsn));
01617         bp += sizeof(*meta_lsn);
01618 
01619         uinttmp = (u_int32_t)meta_pgno;
01620         memcpy(bp, &uinttmp, sizeof(uinttmp));
01621         bp += sizeof(uinttmp);
01622 
01623         if (header == NULL) {
01624                 zero = 0;
01625                 memcpy(bp, &zero, sizeof(u_int32_t));
01626                 bp += sizeof(u_int32_t);
01627         } else {
01628                 memcpy(bp, &header->size, sizeof(header->size));
01629                 bp += sizeof(header->size);
01630                 memcpy(bp, header->data, header->size);
01631                 bp += header->size;
01632         }
01633 
01634         uinttmp = (u_int32_t)next;
01635         memcpy(bp, &uinttmp, sizeof(uinttmp));
01636         bp += sizeof(uinttmp);
01637 
01638         uinttmp = (u_int32_t)last_pgno;
01639         memcpy(bp, &uinttmp, sizeof(uinttmp));
01640         bp += sizeof(uinttmp);
01641 
01642         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
01643 
01644         if (is_durable || txnid == NULL) {
01645                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
01646                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
01647                         *lsnp = *rlsnp;
01648                         if (rlsnp != ret_lsnp)
01649                                  *ret_lsnp = *rlsnp;
01650                 }
01651         } else {
01652 #ifdef DIAGNOSTIC
01653                 /*
01654                  * Set the debug bit if we are going to log non-durable
01655                  * transactions so they will be ignored by recovery.
01656                  */
01657                 memcpy(lr->data, logrec.data, logrec.size);
01658                 rectype |= DB_debug_FLAG;
01659                 memcpy(logrec.data, &rectype, sizeof(rectype));
01660 
01661                 ret = __log_put(dbenv,
01662                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
01663 #else
01664                 ret = 0;
01665 #endif
01666                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
01667                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
01668                 LSN_NOT_LOGGED(*ret_lsnp);
01669         }
01670 
01671 #ifdef LOG_DIAGNOSTIC
01672         if (ret != 0)
01673                 (void)__db_pg_free_print(dbenv,
01674                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
01675 #endif
01676 
01677 #ifdef DIAGNOSTIC
01678         __os_free(dbenv, logrec.data);
01679 #else
01680         if (is_durable || txnid == NULL)
01681                 __os_free(dbenv, logrec.data);
01682 #endif
01683         return (ret);
01684 }
01685 
01686 /*
01687  * PUBLIC: int __db_pg_free_read __P((DB_ENV *, void *, __db_pg_free_args **));
01688  */
01689 int
01690 __db_pg_free_read(dbenv, recbuf, argpp)
01691         DB_ENV *dbenv;
01692         void *recbuf;
01693         __db_pg_free_args **argpp;
01694 {
01695         __db_pg_free_args *argp;
01696         u_int32_t uinttmp;
01697         u_int8_t *bp;
01698         int ret;
01699 
01700         if ((ret = __os_malloc(dbenv,
01701             sizeof(__db_pg_free_args) + sizeof(DB_TXN), &argp)) != 0)
01702                 return (ret);
01703         bp = recbuf;
01704         argp->txnid = (DB_TXN *)&argp[1];
01705 
01706         memcpy(&argp->type, bp, sizeof(argp->type));
01707         bp += sizeof(argp->type);
01708 
01709         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
01710         bp += sizeof(argp->txnid->txnid);
01711 
01712         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
01713         bp += sizeof(DB_LSN);
01714 
01715         memcpy(&uinttmp, bp, sizeof(uinttmp));
01716         argp->fileid = (int32_t)uinttmp;
01717         bp += sizeof(uinttmp);
01718 
01719         memcpy(&uinttmp, bp, sizeof(uinttmp));
01720         argp->pgno = (db_pgno_t)uinttmp;
01721         bp += sizeof(uinttmp);
01722 
01723         memcpy(&argp->meta_lsn, bp,  sizeof(argp->meta_lsn));
01724         bp += sizeof(argp->meta_lsn);
01725 
01726         memcpy(&uinttmp, bp, sizeof(uinttmp));
01727         argp->meta_pgno = (db_pgno_t)uinttmp;
01728         bp += sizeof(uinttmp);
01729 
01730         memset(&argp->header, 0, sizeof(argp->header));
01731         memcpy(&argp->header.size, bp, sizeof(u_int32_t));
01732         bp += sizeof(u_int32_t);
01733         argp->header.data = bp;
01734         bp += argp->header.size;
01735 
01736         memcpy(&uinttmp, bp, sizeof(uinttmp));
01737         argp->next = (db_pgno_t)uinttmp;
01738         bp += sizeof(uinttmp);
01739 
01740         memcpy(&uinttmp, bp, sizeof(uinttmp));
01741         argp->last_pgno = (db_pgno_t)uinttmp;
01742         bp += sizeof(uinttmp);
01743 
01744         *argpp = argp;
01745         return (0);
01746 }
01747 
01748 /*
01749  * PUBLIC: int __db_cksum_log __P((DB_ENV *, DB_TXN *, DB_LSN *, u_int32_t));
01750  */
01751 int
01752 __db_cksum_log(dbenv, txnid, ret_lsnp, flags)
01753         DB_ENV *dbenv;
01754         DB_TXN *txnid;
01755         DB_LSN *ret_lsnp;
01756         u_int32_t flags;
01757 {
01758         DBT logrec;
01759         DB_TXNLOGREC *lr;
01760         DB_LSN *lsnp, null_lsn, *rlsnp;
01761         u_int32_t rectype, txn_num;
01762         u_int npad;
01763         u_int8_t *bp;
01764         int is_durable, ret;
01765 
01766         COMPQUIET(lr, NULL);
01767 
01768         rectype = DB___db_cksum;
01769         npad = 0;
01770         rlsnp = ret_lsnp;
01771 
01772         ret = 0;
01773 
01774         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
01775                 if (txnid == NULL)
01776                         return (0);
01777                 is_durable = 0;
01778         } else
01779                 is_durable = 1;
01780 
01781         if (txnid == NULL) {
01782                 txn_num = 0;
01783                 lsnp = &null_lsn;
01784                 null_lsn.file = null_lsn.offset = 0;
01785         } else {
01786                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
01787                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
01788                         return (ret);
01789                 /*
01790                  * We need to assign begin_lsn while holding region mutex.
01791                  * That assignment is done inside the DbEnv->log_put call,
01792                  * so pass in the appropriate memory location to be filled
01793                  * in by the log_put code.
01794                  */
01795                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
01796                 txn_num = txnid->txnid;
01797         }
01798 
01799         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN);
01800         if (CRYPTO_ON(dbenv)) {
01801                 npad =
01802                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
01803                 logrec.size += npad;
01804         }
01805 
01806         if (is_durable || txnid == NULL) {
01807                 if ((ret =
01808                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
01809                         return (ret);
01810         } else {
01811                 if ((ret = __os_malloc(dbenv,
01812                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
01813                         return (ret);
01814 #ifdef DIAGNOSTIC
01815                 if ((ret =
01816                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
01817                         __os_free(dbenv, lr);
01818                         return (ret);
01819                 }
01820 #else
01821                 logrec.data = lr->data;
01822 #endif
01823         }
01824         if (npad > 0)
01825                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
01826 
01827         bp = logrec.data;
01828 
01829         memcpy(bp, &rectype, sizeof(rectype));
01830         bp += sizeof(rectype);
01831 
01832         memcpy(bp, &txn_num, sizeof(txn_num));
01833         bp += sizeof(txn_num);
01834 
01835         memcpy(bp, lsnp, sizeof(DB_LSN));
01836         bp += sizeof(DB_LSN);
01837 
01838         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
01839 
01840         if (is_durable || txnid == NULL) {
01841                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
01842                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
01843                         *lsnp = *rlsnp;
01844                         if (rlsnp != ret_lsnp)
01845                                  *ret_lsnp = *rlsnp;
01846                 }
01847         } else {
01848 #ifdef DIAGNOSTIC
01849                 /*
01850                  * Set the debug bit if we are going to log non-durable
01851                  * transactions so they will be ignored by recovery.
01852                  */
01853                 memcpy(lr->data, logrec.data, logrec.size);
01854                 rectype |= DB_debug_FLAG;
01855                 memcpy(logrec.data, &rectype, sizeof(rectype));
01856 
01857                 ret = __log_put(dbenv,
01858                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
01859 #else
01860                 ret = 0;
01861 #endif
01862                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
01863                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
01864                 LSN_NOT_LOGGED(*ret_lsnp);
01865         }
01866 
01867 #ifdef LOG_DIAGNOSTIC
01868         if (ret != 0)
01869                 (void)__db_cksum_print(dbenv,
01870                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
01871 #endif
01872 
01873 #ifdef DIAGNOSTIC
01874         __os_free(dbenv, logrec.data);
01875 #else
01876         if (is_durable || txnid == NULL)
01877                 __os_free(dbenv, logrec.data);
01878 #endif
01879         return (ret);
01880 }
01881 
01882 /*
01883  * PUBLIC: int __db_cksum_read __P((DB_ENV *, void *, __db_cksum_args **));
01884  */
01885 int
01886 __db_cksum_read(dbenv, recbuf, argpp)
01887         DB_ENV *dbenv;
01888         void *recbuf;
01889         __db_cksum_args **argpp;
01890 {
01891         __db_cksum_args *argp;
01892         u_int8_t *bp;
01893         int ret;
01894 
01895         if ((ret = __os_malloc(dbenv,
01896             sizeof(__db_cksum_args) + sizeof(DB_TXN), &argp)) != 0)
01897                 return (ret);
01898         bp = recbuf;
01899         argp->txnid = (DB_TXN *)&argp[1];
01900 
01901         memcpy(&argp->type, bp, sizeof(argp->type));
01902         bp += sizeof(argp->type);
01903 
01904         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
01905         bp += sizeof(argp->txnid->txnid);
01906 
01907         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
01908         bp += sizeof(DB_LSN);
01909 
01910         *argpp = argp;
01911         return (0);
01912 }
01913 
01914 /*
01915  * PUBLIC: int __db_pg_freedata_log __P((DB *, DB_TXN *, DB_LSN *,
01916  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *,
01917  * PUBLIC:     db_pgno_t, db_pgno_t, const DBT *));
01918  */
01919 int
01920 __db_pg_freedata_log(dbp, txnid, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next,
01921     last_pgno, data)
01922         DB *dbp;
01923         DB_TXN *txnid;
01924         DB_LSN *ret_lsnp;
01925         u_int32_t flags;
01926         db_pgno_t pgno;
01927         DB_LSN * meta_lsn;
01928         db_pgno_t meta_pgno;
01929         const DBT *header;
01930         db_pgno_t next;
01931         db_pgno_t last_pgno;
01932         const DBT *data;
01933 {
01934         DBT logrec;
01935         DB_ENV *dbenv;
01936         DB_TXNLOGREC *lr;
01937         DB_LSN *lsnp, null_lsn, *rlsnp;
01938         u_int32_t zero, uinttmp, rectype, txn_num;
01939         u_int npad;
01940         u_int8_t *bp;
01941         int is_durable, ret;
01942 
01943         dbenv = dbp->dbenv;
01944         COMPQUIET(lr, NULL);
01945 
01946         rectype = DB___db_pg_freedata;
01947         npad = 0;
01948         rlsnp = ret_lsnp;
01949 
01950         ret = 0;
01951 
01952         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
01953             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
01954                 is_durable = 0;
01955         } else
01956                 is_durable = 1;
01957 
01958         if (txnid == NULL) {
01959                 txn_num = 0;
01960                 lsnp = &null_lsn;
01961                 null_lsn.file = null_lsn.offset = 0;
01962         } else {
01963                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
01964                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
01965                         return (ret);
01966                 /*
01967                  * We need to assign begin_lsn while holding region mutex.
01968                  * That assignment is done inside the DbEnv->log_put call,
01969                  * so pass in the appropriate memory location to be filled
01970                  * in by the log_put code.
01971                  */
01972                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
01973                 txn_num = txnid->txnid;
01974         }
01975 
01976         DB_ASSERT(dbp->log_filename != NULL);
01977         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
01978             (ret = __dbreg_lazy_id(dbp)) != 0)
01979                 return (ret);
01980 
01981         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
01982             + sizeof(u_int32_t)
01983             + sizeof(u_int32_t)
01984             + sizeof(*meta_lsn)
01985             + sizeof(u_int32_t)
01986             + sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
01987             + sizeof(u_int32_t)
01988             + sizeof(u_int32_t)
01989             + sizeof(u_int32_t) + (data == NULL ? 0 : data->size);
01990         if (CRYPTO_ON(dbenv)) {
01991                 npad =
01992                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
01993                 logrec.size += npad;
01994         }
01995 
01996         if (is_durable || txnid == NULL) {
01997                 if ((ret =
01998                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
01999                         return (ret);
02000         } else {
02001                 if ((ret = __os_malloc(dbenv,
02002                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
02003                         return (ret);
02004 #ifdef DIAGNOSTIC
02005                 if ((ret =
02006                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
02007                         __os_free(dbenv, lr);
02008                         return (ret);
02009                 }
02010 #else
02011                 logrec.data = lr->data;
02012 #endif
02013         }
02014         if (npad > 0)
02015                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
02016 
02017         bp = logrec.data;
02018 
02019         memcpy(bp, &rectype, sizeof(rectype));
02020         bp += sizeof(rectype);
02021 
02022         memcpy(bp, &txn_num, sizeof(txn_num));
02023         bp += sizeof(txn_num);
02024 
02025         memcpy(bp, lsnp, sizeof(DB_LSN));
02026         bp += sizeof(DB_LSN);
02027 
02028         uinttmp = (u_int32_t)dbp->log_filename->id;
02029         memcpy(bp, &uinttmp, sizeof(uinttmp));
02030         bp += sizeof(uinttmp);
02031 
02032         uinttmp = (u_int32_t)pgno;
02033         memcpy(bp, &uinttmp, sizeof(uinttmp));
02034         bp += sizeof(uinttmp);
02035 
02036         if (meta_lsn != NULL)
02037                 memcpy(bp, meta_lsn, sizeof(*meta_lsn));
02038         else
02039                 memset(bp, 0, sizeof(*meta_lsn));
02040         bp += sizeof(*meta_lsn);
02041 
02042         uinttmp = (u_int32_t)meta_pgno;
02043         memcpy(bp, &uinttmp, sizeof(uinttmp));
02044         bp += sizeof(uinttmp);
02045 
02046         if (header == NULL) {
02047                 zero = 0;
02048                 memcpy(bp, &zero, sizeof(u_int32_t));
02049                 bp += sizeof(u_int32_t);
02050         } else {
02051                 memcpy(bp, &header->size, sizeof(header->size));
02052                 bp += sizeof(header->size);
02053                 memcpy(bp, header->data, header->size);
02054                 bp += header->size;
02055         }
02056 
02057         uinttmp = (u_int32_t)next;
02058         memcpy(bp, &uinttmp, sizeof(uinttmp));
02059         bp += sizeof(uinttmp);
02060 
02061         uinttmp = (u_int32_t)last_pgno;
02062         memcpy(bp, &uinttmp, sizeof(uinttmp));
02063         bp += sizeof(uinttmp);
02064 
02065         if (data == NULL) {
02066                 zero = 0;
02067                 memcpy(bp, &zero, sizeof(u_int32_t));
02068                 bp += sizeof(u_int32_t);
02069         } else {
02070                 memcpy(bp, &data->size, sizeof(data->size));
02071                 bp += sizeof(data->size);
02072                 memcpy(bp, data->data, data->size);
02073                 bp += data->size;
02074         }
02075 
02076         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
02077 
02078         if (is_durable || txnid == NULL) {
02079                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
02080                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
02081                         *lsnp = *rlsnp;
02082                         if (rlsnp != ret_lsnp)
02083                                  *ret_lsnp = *rlsnp;
02084                 }
02085         } else {
02086 #ifdef DIAGNOSTIC
02087                 /*
02088                  * Set the debug bit if we are going to log non-durable
02089                  * transactions so they will be ignored by recovery.
02090                  */
02091                 memcpy(lr->data, logrec.data, logrec.size);
02092                 rectype |= DB_debug_FLAG;
02093                 memcpy(logrec.data, &rectype, sizeof(rectype));
02094 
02095                 ret = __log_put(dbenv,
02096                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
02097 #else
02098                 ret = 0;
02099 #endif
02100                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
02101                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
02102                 LSN_NOT_LOGGED(*ret_lsnp);
02103         }
02104 
02105 #ifdef LOG_DIAGNOSTIC
02106         if (ret != 0)
02107                 (void)__db_pg_freedata_print(dbenv,
02108                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
02109 #endif
02110 
02111 #ifdef DIAGNOSTIC
02112         __os_free(dbenv, logrec.data);
02113 #else
02114         if (is_durable || txnid == NULL)
02115                 __os_free(dbenv, logrec.data);
02116 #endif
02117         return (ret);
02118 }
02119 
02120 /*
02121  * PUBLIC: int __db_pg_freedata_read __P((DB_ENV *, void *,
02122  * PUBLIC:     __db_pg_freedata_args **));
02123  */
02124 int
02125 __db_pg_freedata_read(dbenv, recbuf, argpp)
02126         DB_ENV *dbenv;
02127         void *recbuf;
02128         __db_pg_freedata_args **argpp;
02129 {
02130         __db_pg_freedata_args *argp;
02131         u_int32_t uinttmp;
02132         u_int8_t *bp;
02133         int ret;
02134 
02135         if ((ret = __os_malloc(dbenv,
02136             sizeof(__db_pg_freedata_args) + sizeof(DB_TXN), &argp)) != 0)
02137                 return (ret);
02138         bp = recbuf;
02139         argp->txnid = (DB_TXN *)&argp[1];
02140 
02141         memcpy(&argp->type, bp, sizeof(argp->type));
02142         bp += sizeof(argp->type);
02143 
02144         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
02145         bp += sizeof(argp->txnid->txnid);
02146 
02147         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
02148         bp += sizeof(DB_LSN);
02149 
02150         memcpy(&uinttmp, bp, sizeof(uinttmp));
02151         argp->fileid = (int32_t)uinttmp;
02152         bp += sizeof(uinttmp);
02153 
02154         memcpy(&uinttmp, bp, sizeof(uinttmp));
02155         argp->pgno = (db_pgno_t)uinttmp;
02156         bp += sizeof(uinttmp);
02157 
02158         memcpy(&argp->meta_lsn, bp,  sizeof(argp->meta_lsn));
02159         bp += sizeof(argp->meta_lsn);
02160 
02161         memcpy(&uinttmp, bp, sizeof(uinttmp));
02162         argp->meta_pgno = (db_pgno_t)uinttmp;
02163         bp += sizeof(uinttmp);
02164 
02165         memset(&argp->header, 0, sizeof(argp->header));
02166         memcpy(&argp->header.size, bp, sizeof(u_int32_t));
02167         bp += sizeof(u_int32_t);
02168         argp->header.data = bp;
02169         bp += argp->header.size;
02170 
02171         memcpy(&uinttmp, bp, sizeof(uinttmp));
02172         argp->next = (db_pgno_t)uinttmp;
02173         bp += sizeof(uinttmp);
02174 
02175         memcpy(&uinttmp, bp, sizeof(uinttmp));
02176         argp->last_pgno = (db_pgno_t)uinttmp;
02177         bp += sizeof(uinttmp);
02178 
02179         memset(&argp->data, 0, sizeof(argp->data));
02180         memcpy(&argp->data.size, bp, sizeof(u_int32_t));
02181         bp += sizeof(u_int32_t);
02182         argp->data.data = bp;
02183         bp += argp->data.size;
02184 
02185         *argpp = argp;
02186         return (0);
02187 }
02188 
02189 /*
02190  * PUBLIC: int __db_pg_prepare_log __P((DB *, DB_TXN *, DB_LSN *,
02191  * PUBLIC:     u_int32_t, db_pgno_t));
02192  */
02193 int
02194 __db_pg_prepare_log(dbp, txnid, ret_lsnp, flags, pgno)
02195         DB *dbp;
02196         DB_TXN *txnid;
02197         DB_LSN *ret_lsnp;
02198         u_int32_t flags;
02199         db_pgno_t pgno;
02200 {
02201         DBT logrec;
02202         DB_ENV *dbenv;
02203         DB_TXNLOGREC *lr;
02204         DB_LSN *lsnp, null_lsn, *rlsnp;
02205         u_int32_t uinttmp, rectype, txn_num;
02206         u_int npad;
02207         u_int8_t *bp;
02208         int is_durable, ret;
02209 
02210         dbenv = dbp->dbenv;
02211         COMPQUIET(lr, NULL);
02212 
02213         rectype = DB___db_pg_prepare;
02214         npad = 0;
02215         rlsnp = ret_lsnp;
02216 
02217         ret = 0;
02218 
02219         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
02220             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
02221                 is_durable = 0;
02222         } else
02223                 is_durable = 1;
02224 
02225         if (txnid == NULL) {
02226                 txn_num = 0;
02227                 lsnp = &null_lsn;
02228                 null_lsn.file = null_lsn.offset = 0;
02229         } else {
02230                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
02231                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
02232                         return (ret);
02233                 /*
02234                  * We need to assign begin_lsn while holding region mutex.
02235                  * That assignment is done inside the DbEnv->log_put call,
02236                  * so pass in the appropriate memory location to be filled
02237                  * in by the log_put code.
02238                  */
02239                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
02240                 txn_num = txnid->txnid;
02241         }
02242 
02243         DB_ASSERT(dbp->log_filename != NULL);
02244         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
02245             (ret = __dbreg_lazy_id(dbp)) != 0)
02246                 return (ret);
02247 
02248         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
02249             + sizeof(u_int32_t)
02250             + sizeof(u_int32_t);
02251         if (CRYPTO_ON(dbenv)) {
02252                 npad =
02253                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
02254                 logrec.size += npad;
02255         }
02256 
02257         if (is_durable || txnid == NULL) {
02258                 if ((ret =
02259                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
02260                         return (ret);
02261         } else {
02262                 if ((ret = __os_malloc(dbenv,
02263                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
02264                         return (ret);
02265 #ifdef DIAGNOSTIC
02266                 if ((ret =
02267                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
02268                         __os_free(dbenv, lr);
02269                         return (ret);
02270                 }
02271 #else
02272                 logrec.data = lr->data;
02273 #endif
02274         }
02275         if (npad > 0)
02276                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
02277 
02278         bp = logrec.data;
02279 
02280         memcpy(bp, &rectype, sizeof(rectype));
02281         bp += sizeof(rectype);
02282 
02283         memcpy(bp, &txn_num, sizeof(txn_num));
02284         bp += sizeof(txn_num);
02285 
02286         memcpy(bp, lsnp, sizeof(DB_LSN));
02287         bp += sizeof(DB_LSN);
02288 
02289         uinttmp = (u_int32_t)dbp->log_filename->id;
02290         memcpy(bp, &uinttmp, sizeof(uinttmp));
02291         bp += sizeof(uinttmp);
02292 
02293         uinttmp = (u_int32_t)pgno;
02294         memcpy(bp, &uinttmp, sizeof(uinttmp));
02295         bp += sizeof(uinttmp);
02296 
02297         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
02298 
02299         if (is_durable || txnid == NULL) {
02300                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
02301                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
02302                         *lsnp = *rlsnp;
02303                         if (rlsnp != ret_lsnp)
02304                                  *ret_lsnp = *rlsnp;
02305                 }
02306         } else {
02307 #ifdef DIAGNOSTIC
02308                 /*
02309                  * Set the debug bit if we are going to log non-durable
02310                  * transactions so they will be ignored by recovery.
02311                  */
02312                 memcpy(lr->data, logrec.data, logrec.size);
02313                 rectype |= DB_debug_FLAG;
02314                 memcpy(logrec.data, &rectype, sizeof(rectype));
02315 
02316                 ret = __log_put(dbenv,
02317                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
02318 #else
02319                 ret = 0;
02320 #endif
02321                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
02322                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
02323                 LSN_NOT_LOGGED(*ret_lsnp);
02324         }
02325 
02326 #ifdef LOG_DIAGNOSTIC
02327         if (ret != 0)
02328                 (void)__db_pg_prepare_print(dbenv,
02329                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
02330 #endif
02331 
02332 #ifdef DIAGNOSTIC
02333         __os_free(dbenv, logrec.data);
02334 #else
02335         if (is_durable || txnid == NULL)
02336                 __os_free(dbenv, logrec.data);
02337 #endif
02338         return (ret);
02339 }
02340 
02341 /*
02342  * PUBLIC: int __db_pg_prepare_read __P((DB_ENV *, void *,
02343  * PUBLIC:     __db_pg_prepare_args **));
02344  */
02345 int
02346 __db_pg_prepare_read(dbenv, recbuf, argpp)
02347         DB_ENV *dbenv;
02348         void *recbuf;
02349         __db_pg_prepare_args **argpp;
02350 {
02351         __db_pg_prepare_args *argp;
02352         u_int32_t uinttmp;
02353         u_int8_t *bp;
02354         int ret;
02355 
02356         if ((ret = __os_malloc(dbenv,
02357             sizeof(__db_pg_prepare_args) + sizeof(DB_TXN), &argp)) != 0)
02358                 return (ret);
02359         bp = recbuf;
02360         argp->txnid = (DB_TXN *)&argp[1];
02361 
02362         memcpy(&argp->type, bp, sizeof(argp->type));
02363         bp += sizeof(argp->type);
02364 
02365         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
02366         bp += sizeof(argp->txnid->txnid);
02367 
02368         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
02369         bp += sizeof(DB_LSN);
02370 
02371         memcpy(&uinttmp, bp, sizeof(uinttmp));
02372         argp->fileid = (int32_t)uinttmp;
02373         bp += sizeof(uinttmp);
02374 
02375         memcpy(&uinttmp, bp, sizeof(uinttmp));
02376         argp->pgno = (db_pgno_t)uinttmp;
02377         bp += sizeof(uinttmp);
02378 
02379         *argpp = argp;
02380         return (0);
02381 }
02382 
02383 /*
02384  * PUBLIC: int __db_pg_new_log __P((DB *, DB_TXN *, DB_LSN *,
02385  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *,
02386  * PUBLIC:     db_pgno_t));
02387  */
02388 int
02389 __db_pg_new_log(dbp, txnid, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next)
02390         DB *dbp;
02391         DB_TXN *txnid;
02392         DB_LSN *ret_lsnp;
02393         u_int32_t flags;
02394         db_pgno_t pgno;
02395         DB_LSN * meta_lsn;
02396         db_pgno_t meta_pgno;
02397         const DBT *header;
02398         db_pgno_t next;
02399 {
02400         DBT logrec;
02401         DB_ENV *dbenv;
02402         DB_TXNLOGREC *lr;
02403         DB_LSN *lsnp, null_lsn, *rlsnp;
02404         u_int32_t zero, uinttmp, rectype, txn_num;
02405         u_int npad;
02406         u_int8_t *bp;
02407         int is_durable, ret;
02408 
02409         dbenv = dbp->dbenv;
02410         COMPQUIET(lr, NULL);
02411 
02412         rectype = DB___db_pg_new;
02413         npad = 0;
02414         rlsnp = ret_lsnp;
02415 
02416         ret = 0;
02417 
02418         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
02419             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
02420                 is_durable = 0;
02421         } else
02422                 is_durable = 1;
02423 
02424         if (txnid == NULL) {
02425                 txn_num = 0;
02426                 lsnp = &null_lsn;
02427                 null_lsn.file = null_lsn.offset = 0;
02428         } else {
02429                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
02430                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
02431                         return (ret);
02432                 /*
02433                  * We need to assign begin_lsn while holding region mutex.
02434                  * That assignment is done inside the DbEnv->log_put call,
02435                  * so pass in the appropriate memory location to be filled
02436                  * in by the log_put code.
02437                  */
02438                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
02439                 txn_num = txnid->txnid;
02440         }
02441 
02442         DB_ASSERT(dbp->log_filename != NULL);
02443         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
02444             (ret = __dbreg_lazy_id(dbp)) != 0)
02445                 return (ret);
02446 
02447         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
02448             + sizeof(u_int32_t)
02449             + sizeof(u_int32_t)
02450             + sizeof(*meta_lsn)
02451             + sizeof(u_int32_t)
02452             + sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
02453             + sizeof(u_int32_t);
02454         if (CRYPTO_ON(dbenv)) {
02455                 npad =
02456                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
02457                 logrec.size += npad;
02458         }
02459 
02460         if (is_durable || txnid == NULL) {
02461                 if ((ret =
02462                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
02463                         return (ret);
02464         } else {
02465                 if ((ret = __os_malloc(dbenv,
02466                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
02467                         return (ret);
02468 #ifdef DIAGNOSTIC
02469                 if ((ret =
02470                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
02471                         __os_free(dbenv, lr);
02472                         return (ret);
02473                 }
02474 #else
02475                 logrec.data = lr->data;
02476 #endif
02477         }
02478         if (npad > 0)
02479                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
02480 
02481         bp = logrec.data;
02482 
02483         memcpy(bp, &rectype, sizeof(rectype));
02484         bp += sizeof(rectype);
02485 
02486         memcpy(bp, &txn_num, sizeof(txn_num));
02487         bp += sizeof(txn_num);
02488 
02489         memcpy(bp, lsnp, sizeof(DB_LSN));
02490         bp += sizeof(DB_LSN);
02491 
02492         uinttmp = (u_int32_t)dbp->log_filename->id;
02493         memcpy(bp, &uinttmp, sizeof(uinttmp));
02494         bp += sizeof(uinttmp);
02495 
02496         uinttmp = (u_int32_t)pgno;
02497         memcpy(bp, &uinttmp, sizeof(uinttmp));
02498         bp += sizeof(uinttmp);
02499 
02500         if (meta_lsn != NULL)
02501                 memcpy(bp, meta_lsn, sizeof(*meta_lsn));
02502         else
02503                 memset(bp, 0, sizeof(*meta_lsn));
02504         bp += sizeof(*meta_lsn);
02505 
02506         uinttmp = (u_int32_t)meta_pgno;
02507         memcpy(bp, &uinttmp, sizeof(uinttmp));
02508         bp += sizeof(uinttmp);
02509 
02510         if (header == NULL) {
02511                 zero = 0;
02512                 memcpy(bp, &zero, sizeof(u_int32_t));
02513                 bp += sizeof(u_int32_t);
02514         } else {
02515                 memcpy(bp, &header->size, sizeof(header->size));
02516                 bp += sizeof(header->size);
02517                 memcpy(bp, header->data, header->size);
02518                 bp += header->size;
02519         }
02520 
02521         uinttmp = (u_int32_t)next;
02522         memcpy(bp, &uinttmp, sizeof(uinttmp));
02523         bp += sizeof(uinttmp);
02524 
02525         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
02526 
02527         if (is_durable || txnid == NULL) {
02528                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
02529                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
02530                         *lsnp = *rlsnp;
02531                         if (rlsnp != ret_lsnp)
02532                                  *ret_lsnp = *rlsnp;
02533                 }
02534         } else {
02535 #ifdef DIAGNOSTIC
02536                 /*
02537                  * Set the debug bit if we are going to log non-durable
02538                  * transactions so they will be ignored by recovery.
02539                  */
02540                 memcpy(lr->data, logrec.data, logrec.size);
02541                 rectype |= DB_debug_FLAG;
02542                 memcpy(logrec.data, &rectype, sizeof(rectype));
02543 
02544                 ret = __log_put(dbenv,
02545                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
02546 #else
02547                 ret = 0;
02548 #endif
02549                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
02550                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
02551                 LSN_NOT_LOGGED(*ret_lsnp);
02552         }
02553 
02554 #ifdef LOG_DIAGNOSTIC
02555         if (ret != 0)
02556                 (void)__db_pg_new_print(dbenv,
02557                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
02558 #endif
02559 
02560 #ifdef DIAGNOSTIC
02561         __os_free(dbenv, logrec.data);
02562 #else
02563         if (is_durable || txnid == NULL)
02564                 __os_free(dbenv, logrec.data);
02565 #endif
02566         return (ret);
02567 }
02568 
02569 /*
02570  * PUBLIC: int __db_pg_new_read __P((DB_ENV *, void *, __db_pg_new_args **));
02571  */
02572 int
02573 __db_pg_new_read(dbenv, recbuf, argpp)
02574         DB_ENV *dbenv;
02575         void *recbuf;
02576         __db_pg_new_args **argpp;
02577 {
02578         __db_pg_new_args *argp;
02579         u_int32_t uinttmp;
02580         u_int8_t *bp;
02581         int ret;
02582 
02583         if ((ret = __os_malloc(dbenv,
02584             sizeof(__db_pg_new_args) + sizeof(DB_TXN), &argp)) != 0)
02585                 return (ret);
02586         bp = recbuf;
02587         argp->txnid = (DB_TXN *)&argp[1];
02588 
02589         memcpy(&argp->type, bp, sizeof(argp->type));
02590         bp += sizeof(argp->type);
02591 
02592         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
02593         bp += sizeof(argp->txnid->txnid);
02594 
02595         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
02596         bp += sizeof(DB_LSN);
02597 
02598         memcpy(&uinttmp, bp, sizeof(uinttmp));
02599         argp->fileid = (int32_t)uinttmp;
02600         bp += sizeof(uinttmp);
02601 
02602         memcpy(&uinttmp, bp, sizeof(uinttmp));
02603         argp->pgno = (db_pgno_t)uinttmp;
02604         bp += sizeof(uinttmp);
02605 
02606         memcpy(&argp->meta_lsn, bp,  sizeof(argp->meta_lsn));
02607         bp += sizeof(argp->meta_lsn);
02608 
02609         memcpy(&uinttmp, bp, sizeof(uinttmp));
02610         argp->meta_pgno = (db_pgno_t)uinttmp;
02611         bp += sizeof(uinttmp);
02612 
02613         memset(&argp->header, 0, sizeof(argp->header));
02614         memcpy(&argp->header.size, bp, sizeof(u_int32_t));
02615         bp += sizeof(u_int32_t);
02616         argp->header.data = bp;
02617         bp += argp->header.size;
02618 
02619         memcpy(&uinttmp, bp, sizeof(uinttmp));
02620         argp->next = (db_pgno_t)uinttmp;
02621         bp += sizeof(uinttmp);
02622 
02623         *argpp = argp;
02624         return (0);
02625 }
02626 
02627 /*
02628  * PUBLIC: int __db_pg_init_log __P((DB *, DB_TXN *, DB_LSN *,
02629  * PUBLIC:     u_int32_t, db_pgno_t, const DBT *, const DBT *));
02630  */
02631 int
02632 __db_pg_init_log(dbp, txnid, ret_lsnp, flags, pgno, header, data)
02633         DB *dbp;
02634         DB_TXN *txnid;
02635         DB_LSN *ret_lsnp;
02636         u_int32_t flags;
02637         db_pgno_t pgno;
02638         const DBT *header;
02639         const DBT *data;
02640 {
02641         DBT logrec;
02642         DB_ENV *dbenv;
02643         DB_TXNLOGREC *lr;
02644         DB_LSN *lsnp, null_lsn, *rlsnp;
02645         u_int32_t zero, uinttmp, rectype, txn_num;
02646         u_int npad;
02647         u_int8_t *bp;
02648         int is_durable, ret;
02649 
02650         dbenv = dbp->dbenv;
02651         COMPQUIET(lr, NULL);
02652 
02653         rectype = DB___db_pg_init;
02654         npad = 0;
02655         rlsnp = ret_lsnp;
02656 
02657         ret = 0;
02658 
02659         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
02660             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
02661                 is_durable = 0;
02662         } else
02663                 is_durable = 1;
02664 
02665         if (txnid == NULL) {
02666                 txn_num = 0;
02667                 lsnp = &null_lsn;
02668                 null_lsn.file = null_lsn.offset = 0;
02669         } else {
02670                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
02671                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
02672                         return (ret);
02673                 /*
02674                  * We need to assign begin_lsn while holding region mutex.
02675                  * That assignment is done inside the DbEnv->log_put call,
02676                  * so pass in the appropriate memory location to be filled
02677                  * in by the log_put code.
02678                  */
02679                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
02680                 txn_num = txnid->txnid;
02681         }
02682 
02683         DB_ASSERT(dbp->log_filename != NULL);
02684         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
02685             (ret = __dbreg_lazy_id(dbp)) != 0)
02686                 return (ret);
02687 
02688         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
02689             + sizeof(u_int32_t)
02690             + sizeof(u_int32_t)
02691             + sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
02692             + sizeof(u_int32_t) + (data == NULL ? 0 : data->size);
02693         if (CRYPTO_ON(dbenv)) {
02694                 npad =
02695                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
02696                 logrec.size += npad;
02697         }
02698 
02699         if (is_durable || txnid == NULL) {
02700                 if ((ret =
02701                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
02702                         return (ret);
02703         } else {
02704                 if ((ret = __os_malloc(dbenv,
02705                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
02706                         return (ret);
02707 #ifdef DIAGNOSTIC
02708                 if ((ret =
02709                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
02710                         __os_free(dbenv, lr);
02711                         return (ret);
02712                 }
02713 #else
02714                 logrec.data = lr->data;
02715 #endif
02716         }
02717         if (npad > 0)
02718                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
02719 
02720         bp = logrec.data;
02721 
02722         memcpy(bp, &rectype, sizeof(rectype));
02723         bp += sizeof(rectype);
02724 
02725         memcpy(bp, &txn_num, sizeof(txn_num));
02726         bp += sizeof(txn_num);
02727 
02728         memcpy(bp, lsnp, sizeof(DB_LSN));
02729         bp += sizeof(DB_LSN);
02730 
02731         uinttmp = (u_int32_t)dbp->log_filename->id;
02732         memcpy(bp, &uinttmp, sizeof(uinttmp));
02733         bp += sizeof(uinttmp);
02734 
02735         uinttmp = (u_int32_t)pgno;
02736         memcpy(bp, &uinttmp, sizeof(uinttmp));
02737         bp += sizeof(uinttmp);
02738 
02739         if (header == NULL) {
02740                 zero = 0;
02741                 memcpy(bp, &zero, sizeof(u_int32_t));
02742                 bp += sizeof(u_int32_t);
02743         } else {
02744                 memcpy(bp, &header->size, sizeof(header->size));
02745                 bp += sizeof(header->size);
02746                 memcpy(bp, header->data, header->size);
02747                 bp += header->size;
02748         }
02749 
02750         if (data == NULL) {
02751                 zero = 0;
02752                 memcpy(bp, &zero, sizeof(u_int32_t));
02753                 bp += sizeof(u_int32_t);
02754         } else {
02755                 memcpy(bp, &data->size, sizeof(data->size));
02756                 bp += sizeof(data->size);
02757                 memcpy(bp, data->data, data->size);
02758                 bp += data->size;
02759         }
02760 
02761         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
02762 
02763         if (is_durable || txnid == NULL) {
02764                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
02765                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
02766                         *lsnp = *rlsnp;
02767                         if (rlsnp != ret_lsnp)
02768                                  *ret_lsnp = *rlsnp;
02769                 }
02770         } else {
02771 #ifdef DIAGNOSTIC
02772                 /*
02773                  * Set the debug bit if we are going to log non-durable
02774                  * transactions so they will be ignored by recovery.
02775                  */
02776                 memcpy(lr->data, logrec.data, logrec.size);
02777                 rectype |= DB_debug_FLAG;
02778                 memcpy(logrec.data, &rectype, sizeof(rectype));
02779 
02780                 ret = __log_put(dbenv,
02781                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
02782 #else
02783                 ret = 0;
02784 #endif
02785                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
02786                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
02787                 LSN_NOT_LOGGED(*ret_lsnp);
02788         }
02789 
02790 #ifdef LOG_DIAGNOSTIC
02791         if (ret != 0)
02792                 (void)__db_pg_init_print(dbenv,
02793                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
02794 #endif
02795 
02796 #ifdef DIAGNOSTIC
02797         __os_free(dbenv, logrec.data);
02798 #else
02799         if (is_durable || txnid == NULL)
02800                 __os_free(dbenv, logrec.data);
02801 #endif
02802         return (ret);
02803 }
02804 
02805 /*
02806  * PUBLIC: int __db_pg_init_read __P((DB_ENV *, void *, __db_pg_init_args **));
02807  */
02808 int
02809 __db_pg_init_read(dbenv, recbuf, argpp)
02810         DB_ENV *dbenv;
02811         void *recbuf;
02812         __db_pg_init_args **argpp;
02813 {
02814         __db_pg_init_args *argp;
02815         u_int32_t uinttmp;
02816         u_int8_t *bp;
02817         int ret;
02818 
02819         if ((ret = __os_malloc(dbenv,
02820             sizeof(__db_pg_init_args) + sizeof(DB_TXN), &argp)) != 0)
02821                 return (ret);
02822         bp = recbuf;
02823         argp->txnid = (DB_TXN *)&argp[1];
02824 
02825         memcpy(&argp->type, bp, sizeof(argp->type));
02826         bp += sizeof(argp->type);
02827 
02828         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
02829         bp += sizeof(argp->txnid->txnid);
02830 
02831         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
02832         bp += sizeof(DB_LSN);
02833 
02834         memcpy(&uinttmp, bp, sizeof(uinttmp));
02835         argp->fileid = (int32_t)uinttmp;
02836         bp += sizeof(uinttmp);
02837 
02838         memcpy(&uinttmp, bp, sizeof(uinttmp));
02839         argp->pgno = (db_pgno_t)uinttmp;
02840         bp += sizeof(uinttmp);
02841 
02842         memset(&argp->header, 0, sizeof(argp->header));
02843         memcpy(&argp->header.size, bp, sizeof(u_int32_t));
02844         bp += sizeof(u_int32_t);
02845         argp->header.data = bp;
02846         bp += argp->header.size;
02847 
02848         memset(&argp->data, 0, sizeof(argp->data));
02849         memcpy(&argp->data.size, bp, sizeof(u_int32_t));
02850         bp += sizeof(u_int32_t);
02851         argp->data.data = bp;
02852         bp += argp->data.size;
02853 
02854         *argpp = argp;
02855         return (0);
02856 }
02857 
02858 /*
02859  * PUBLIC: int __db_pg_sort_log __P((DB *, DB_TXN *, DB_LSN *,
02860  * PUBLIC:     u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t,
02861  * PUBLIC:     const DBT *));
02862  */
02863 int
02864 __db_pg_sort_log(dbp, txnid, ret_lsnp, flags, meta, meta_lsn, last_free, last_lsn, last_pgno,
02865     list)
02866         DB *dbp;
02867         DB_TXN *txnid;
02868         DB_LSN *ret_lsnp;
02869         u_int32_t flags;
02870         db_pgno_t meta;
02871         DB_LSN * meta_lsn;
02872         db_pgno_t last_free;
02873         DB_LSN * last_lsn;
02874         db_pgno_t last_pgno;
02875         const DBT *list;
02876 {
02877         DBT logrec;
02878         DB_ENV *dbenv;
02879         DB_TXNLOGREC *lr;
02880         DB_LSN *lsnp, null_lsn, *rlsnp;
02881         u_int32_t zero, uinttmp, rectype, txn_num;
02882         u_int npad;
02883         u_int8_t *bp;
02884         int is_durable, ret;
02885 
02886         dbenv = dbp->dbenv;
02887         COMPQUIET(lr, NULL);
02888 
02889         rectype = DB___db_pg_sort;
02890         npad = 0;
02891         rlsnp = ret_lsnp;
02892 
02893         ret = 0;
02894 
02895         if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
02896             F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
02897                 is_durable = 0;
02898         } else
02899                 is_durable = 1;
02900 
02901         if (txnid == NULL) {
02902                 txn_num = 0;
02903                 lsnp = &null_lsn;
02904                 null_lsn.file = null_lsn.offset = 0;
02905         } else {
02906                 if (TAILQ_FIRST(&txnid->kids) != NULL &&
02907                     (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
02908                         return (ret);
02909                 /*
02910                  * We need to assign begin_lsn while holding region mutex.
02911                  * That assignment is done inside the DbEnv->log_put call,
02912                  * so pass in the appropriate memory location to be filled
02913                  * in by the log_put code.
02914                  */
02915                 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
02916                 txn_num = txnid->txnid;
02917         }
02918 
02919         DB_ASSERT(dbp->log_filename != NULL);
02920         if (dbp->log_filename->id == DB_LOGFILEID_INVALID &&
02921             (ret = __dbreg_lazy_id(dbp)) != 0)
02922                 return (ret);
02923 
02924         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
02925             + sizeof(u_int32_t)
02926             + sizeof(u_int32_t)
02927             + sizeof(*meta_lsn)
02928             + sizeof(u_int32_t)
02929             + sizeof(*last_lsn)
02930             + sizeof(u_int32_t)
02931             + sizeof(u_int32_t) + (list == NULL ? 0 : list->size);
02932         if (CRYPTO_ON(dbenv)) {
02933                 npad =
02934                     ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
02935                 logrec.size += npad;
02936         }
02937 
02938         if (is_durable || txnid == NULL) {
02939                 if ((ret =
02940                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
02941                         return (ret);
02942         } else {
02943                 if ((ret = __os_malloc(dbenv,
02944                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
02945                         return (ret);
02946 #ifdef DIAGNOSTIC
02947                 if ((ret =
02948                     __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
02949                         __os_free(dbenv, lr);
02950                         return (ret);
02951                 }
02952 #else
02953                 logrec.data = lr->data;
02954 #endif
02955         }
02956         if (npad > 0)
02957                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
02958 
02959         bp = logrec.data;
02960 
02961         memcpy(bp, &rectype, sizeof(rectype));
02962         bp += sizeof(rectype);
02963 
02964         memcpy(bp, &txn_num, sizeof(txn_num));
02965         bp += sizeof(txn_num);
02966 
02967         memcpy(bp, lsnp, sizeof(DB_LSN));
02968         bp += sizeof(DB_LSN);
02969 
02970         uinttmp = (u_int32_t)dbp->log_filename->id;
02971         memcpy(bp, &uinttmp, sizeof(uinttmp));
02972         bp += sizeof(uinttmp);
02973 
02974         uinttmp = (u_int32_t)meta;
02975         memcpy(bp, &uinttmp, sizeof(uinttmp));
02976         bp += sizeof(uinttmp);
02977 
02978         if (meta_lsn != NULL)
02979                 memcpy(bp, meta_lsn, sizeof(*meta_lsn));
02980         else
02981                 memset(bp, 0, sizeof(*meta_lsn));
02982         bp += sizeof(*meta_lsn);
02983 
02984         uinttmp = (u_int32_t)last_free;
02985         memcpy(bp, &uinttmp, sizeof(uinttmp));
02986         bp += sizeof(uinttmp);
02987 
02988         if (last_lsn != NULL)
02989                 memcpy(bp, last_lsn, sizeof(*last_lsn));
02990         else
02991                 memset(bp, 0, sizeof(*last_lsn));
02992         bp += sizeof(*last_lsn);
02993 
02994         uinttmp = (u_int32_t)last_pgno;
02995         memcpy(bp, &uinttmp, sizeof(uinttmp));
02996         bp += sizeof(uinttmp);
02997 
02998         if (list == NULL) {
02999                 zero = 0;
03000                 memcpy(bp, &zero, sizeof(u_int32_t));
03001                 bp += sizeof(u_int32_t);
03002         } else {
03003                 memcpy(bp, &list->size, sizeof(list->size));
03004                 bp += sizeof(list->size);
03005                 memcpy(bp, list->data, list->size);
03006                 bp += list->size;
03007         }
03008 
03009         DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
03010 
03011         if (is_durable || txnid == NULL) {
03012                 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
03013                     flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
03014                         *lsnp = *rlsnp;
03015                         if (rlsnp != ret_lsnp)
03016                                  *ret_lsnp = *rlsnp;
03017                 }
03018         } else {
03019 #ifdef DIAGNOSTIC
03020                 /*
03021                  * Set the debug bit if we are going to log non-durable
03022                  * transactions so they will be ignored by recovery.
03023                  */
03024                 memcpy(lr->data, logrec.data, logrec.size);
03025                 rectype |= DB_debug_FLAG;
03026                 memcpy(logrec.data, &rectype, sizeof(rectype));
03027 
03028                 ret = __log_put(dbenv,
03029                     rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
03030 #else
03031                 ret = 0;
03032 #endif
03033                 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
03034                 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
03035                 LSN_NOT_LOGGED(*ret_lsnp);
03036         }
03037 
03038 #ifdef LOG_DIAGNOSTIC
03039         if (ret != 0)
03040                 (void)__db_pg_sort_print(dbenv,
03041                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
03042 #endif
03043 
03044 #ifdef DIAGNOSTIC
03045         __os_free(dbenv, logrec.data);
03046 #else
03047         if (is_durable || txnid == NULL)
03048                 __os_free(dbenv, logrec.data);
03049 #endif
03050         return (ret);
03051 }
03052 
03053 /*
03054  * PUBLIC: int __db_pg_sort_read __P((DB_ENV *, void *, __db_pg_sort_args **));
03055  */
03056 int
03057 __db_pg_sort_read(dbenv, recbuf, argpp)
03058         DB_ENV *dbenv;
03059         void *recbuf;
03060         __db_pg_sort_args **argpp;
03061 {
03062         __db_pg_sort_args *argp;
03063         u_int32_t uinttmp;
03064         u_int8_t *bp;
03065         int ret;
03066 
03067         if ((ret = __os_malloc(dbenv,
03068             sizeof(__db_pg_sort_args) + sizeof(DB_TXN), &argp)) != 0)
03069                 return (ret);
03070         bp = recbuf;
03071         argp->txnid = (DB_TXN *)&argp[1];
03072 
03073         memcpy(&argp->type, bp, sizeof(argp->type));
03074         bp += sizeof(argp->type);
03075 
03076         memcpy(&argp->txnid->txnid,  bp, sizeof(argp->txnid->txnid));
03077         bp += sizeof(argp->txnid->txnid);
03078 
03079         memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
03080         bp += sizeof(DB_LSN);
03081 
03082         memcpy(&uinttmp, bp, sizeof(uinttmp));
03083         argp->fileid = (int32_t)uinttmp;
03084         bp += sizeof(uinttmp);
03085 
03086         memcpy(&uinttmp, bp, sizeof(uinttmp));
03087         argp->meta = (db_pgno_t)uinttmp;
03088         bp += sizeof(uinttmp);
03089 
03090         memcpy(&argp->meta_lsn, bp,  sizeof(argp->meta_lsn));
03091         bp += sizeof(argp->meta_lsn);
03092 
03093         memcpy(&uinttmp, bp, sizeof(uinttmp));
03094         argp->last_free = (db_pgno_t)uinttmp;
03095         bp += sizeof(uinttmp);
03096 
03097         memcpy(&argp->last_lsn, bp,  sizeof(argp->last_lsn));
03098         bp += sizeof(argp->last_lsn);
03099 
03100         memcpy(&uinttmp, bp, sizeof(uinttmp));
03101         argp->last_pgno = (db_pgno_t)uinttmp;
03102         bp += sizeof(uinttmp);
03103 
03104         memset(&argp->list, 0, sizeof(argp->list));
03105         memcpy(&argp->list.size, bp, sizeof(u_int32_t));
03106         bp += sizeof(u_int32_t);
03107         argp->list.data = bp;
03108         bp += argp->list.size;
03109 
03110         *argpp = argp;
03111         return (0);
03112 }
03113 
03114 /*
03115  * PUBLIC: int __db_init_recover __P((DB_ENV *, int (***)(DB_ENV *,
03116  * PUBLIC:     DBT *, DB_LSN *, db_recops, void *), size_t *));
03117  */
03118 int
03119 __db_init_recover(dbenv, dtabp, dtabsizep)
03120         DB_ENV *dbenv;
03121         int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
03122         size_t *dtabsizep;
03123 {
03124         int ret;
03125 
03126         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03127             __db_addrem_recover, DB___db_addrem)) != 0)
03128                 return (ret);
03129         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03130             __db_big_recover, DB___db_big)) != 0)
03131                 return (ret);
03132         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03133             __db_ovref_recover, DB___db_ovref)) != 0)
03134                 return (ret);
03135         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03136             __db_debug_recover, DB___db_debug)) != 0)
03137                 return (ret);
03138         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03139             __db_noop_recover, DB___db_noop)) != 0)
03140                 return (ret);
03141         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03142             __db_pg_alloc_recover, DB___db_pg_alloc)) != 0)
03143                 return (ret);
03144         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03145             __db_pg_free_recover, DB___db_pg_free)) != 0)
03146                 return (ret);
03147         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03148             __db_cksum_recover, DB___db_cksum)) != 0)
03149                 return (ret);
03150         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03151             __db_pg_freedata_recover, DB___db_pg_freedata)) != 0)
03152                 return (ret);
03153         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03154             __db_pg_prepare_recover, DB___db_pg_prepare)) != 0)
03155                 return (ret);
03156         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03157             __db_pg_new_recover, DB___db_pg_new)) != 0)
03158                 return (ret);
03159         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03160             __db_pg_init_recover, DB___db_pg_init)) != 0)
03161                 return (ret);
03162         if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
03163             __db_pg_sort_recover, DB___db_pg_sort)) != 0)
03164                 return (ret);
03165         return (0);
03166 }

Generated on Sun Dec 25 12:14:19 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2