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