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