1#include "db_config.h"
2
3#include "db_int.h"
4#include "dbinc/db_page.h"
5#include "dbinc/__db.h"
6#include "dbinc/log.h"
7
8/*
9 * __db_addrem_recover --
10 *	Recovery function for addrem.
11 *
12 * PUBLIC: int __db_addrem_recover
13 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
14 */
15int
16__db_addrem_recover(env, dbtp, lsnp, op, info)
17	env *env;
18	DBT *dbtp;
19	DB_LSN *lsnp;
20	db_recops op;
21	void *info;
22{
23	__db_addrem_args *argp;
24	DB *file_dbp;
25	DBC *dbc;
26	DB_MPOOLFILE *mpf;
27	DB_THREAD_INFO *ip;
28	PAGE *pagep;
29	int cmp_n, cmp_p, modified, ret;
30
31	ip = ((DB_TXNHEAD *)info)->thread_info;
32
33	REC_PRINT(__db_addrem_print);
34	REC_INTRO(__db_addrem_read, ip, 0);
35
36	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
37		if (DB_REDO(op)) {
38			if ((ret = mpf->get(mpf,
39			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
40				goto out;
41		} else {
42			*lsnp = argp->prev_lsn;
43			ret = 0;
44			goto out;
45		}
46
47	modified = 0;
48	cmp_n = log_compare(lsnp, &LSN(pagep));
49
50	/*
51	 * Use this when there is something like "pagelsn" in the argp
52	 * structure.  Sometimes, you might need to compare meta-data
53	 * lsn's instead.
54	 *
55	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
56	 */
57	if (cmp_p == 0 && DB_REDO(op)) {
58		/* Need to redo update described. */
59		modified = 1;
60	} else if (cmp_n == 0 && !DB_REDO(op)) {
61		/* Need to undo update described. */
62		modified = 1;
63	}
64	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
65		goto out;
66
67	*lsnp = argp->prev_lsn;
68	ret = 0;
69
70out:	REC_CLOSE;
71}
72
73/*
74 * __db_big_recover --
75 *	Recovery function for big.
76 *
77 * PUBLIC: int __db_big_recover
78 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
79 */
80int
81__db_big_recover(env, dbtp, lsnp, op, info)
82	env *env;
83	DBT *dbtp;
84	DB_LSN *lsnp;
85	db_recops op;
86	void *info;
87{
88	__db_big_args *argp;
89	DB *file_dbp;
90	DBC *dbc;
91	DB_MPOOLFILE *mpf;
92	DB_THREAD_INFO *ip;
93	PAGE *pagep;
94	int cmp_n, cmp_p, modified, ret;
95
96	ip = ((DB_TXNHEAD *)info)->thread_info;
97
98	REC_PRINT(__db_big_print);
99	REC_INTRO(__db_big_read, ip, 0);
100
101	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
102		if (DB_REDO(op)) {
103			if ((ret = mpf->get(mpf,
104			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
105				goto out;
106		} else {
107			*lsnp = argp->prev_lsn;
108			ret = 0;
109			goto out;
110		}
111
112	modified = 0;
113	cmp_n = log_compare(lsnp, &LSN(pagep));
114
115	/*
116	 * Use this when there is something like "pagelsn" in the argp
117	 * structure.  Sometimes, you might need to compare meta-data
118	 * lsn's instead.
119	 *
120	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
121	 */
122	if (cmp_p == 0 && DB_REDO(op)) {
123		/* Need to redo update described. */
124		modified = 1;
125	} else if (cmp_n == 0 && !DB_REDO(op)) {
126		/* Need to undo update described. */
127		modified = 1;
128	}
129	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
130		goto out;
131
132	*lsnp = argp->prev_lsn;
133	ret = 0;
134
135out:	REC_CLOSE;
136}
137
138/*
139 * __db_ovref_recover --
140 *	Recovery function for ovref.
141 *
142 * PUBLIC: int __db_ovref_recover
143 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
144 */
145int
146__db_ovref_recover(env, dbtp, lsnp, op, info)
147	env *env;
148	DBT *dbtp;
149	DB_LSN *lsnp;
150	db_recops op;
151	void *info;
152{
153	__db_ovref_args *argp;
154	DB *file_dbp;
155	DBC *dbc;
156	DB_MPOOLFILE *mpf;
157	DB_THREAD_INFO *ip;
158	PAGE *pagep;
159	int cmp_n, cmp_p, modified, ret;
160
161	ip = ((DB_TXNHEAD *)info)->thread_info;
162
163	REC_PRINT(__db_ovref_print);
164	REC_INTRO(__db_ovref_read, ip, 0);
165
166	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
167		if (DB_REDO(op)) {
168			if ((ret = mpf->get(mpf,
169			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
170				goto out;
171		} else {
172			*lsnp = argp->prev_lsn;
173			ret = 0;
174			goto out;
175		}
176
177	modified = 0;
178	cmp_n = log_compare(lsnp, &LSN(pagep));
179
180	/*
181	 * Use this when there is something like "pagelsn" in the argp
182	 * structure.  Sometimes, you might need to compare meta-data
183	 * lsn's instead.
184	 *
185	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
186	 */
187	if (cmp_p == 0 && DB_REDO(op)) {
188		/* Need to redo update described. */
189		modified = 1;
190	} else if (cmp_n == 0 && !DB_REDO(op)) {
191		/* Need to undo update described. */
192		modified = 1;
193	}
194	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
195		goto out;
196
197	*lsnp = argp->prev_lsn;
198	ret = 0;
199
200out:	REC_CLOSE;
201}
202
203/*
204 * __db_relink_recover --
205 *	Recovery function for relink.
206 *
207 * PUBLIC: int __db_relink_recover
208 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
209 */
210int
211__db_relink_recover(env, dbtp, lsnp, op, info)
212	env *env;
213	DBT *dbtp;
214	DB_LSN *lsnp;
215	db_recops op;
216	void *info;
217{
218	__db_relink_args *argp;
219	DB *file_dbp;
220	DBC *dbc;
221	DB_MPOOLFILE *mpf;
222	DB_THREAD_INFO *ip;
223	PAGE *pagep;
224	int cmp_n, cmp_p, modified, ret;
225
226	ip = ((DB_TXNHEAD *)info)->thread_info;
227
228	REC_PRINT(__db_relink_print);
229	REC_INTRO(__db_relink_read, ip, 0);
230
231	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
232		if (DB_REDO(op)) {
233			if ((ret = mpf->get(mpf,
234			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
235				goto out;
236		} else {
237			*lsnp = argp->prev_lsn;
238			ret = 0;
239			goto out;
240		}
241
242	modified = 0;
243	cmp_n = log_compare(lsnp, &LSN(pagep));
244
245	/*
246	 * Use this when there is something like "pagelsn" in the argp
247	 * structure.  Sometimes, you might need to compare meta-data
248	 * lsn's instead.
249	 *
250	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
251	 */
252	if (cmp_p == 0 && DB_REDO(op)) {
253		/* Need to redo update described. */
254		modified = 1;
255	} else if (cmp_n == 0 && !DB_REDO(op)) {
256		/* Need to undo update described. */
257		modified = 1;
258	}
259	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
260		goto out;
261
262	*lsnp = argp->prev_lsn;
263	ret = 0;
264
265out:	REC_CLOSE;
266}
267
268/*
269 * __db_debug_recover --
270 *	Recovery function for debug.
271 *
272 * PUBLIC: int __db_debug_recover
273 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
274 */
275int
276__db_debug_recover(env, dbtp, lsnp, op, info)
277	env *env;
278	DBT *dbtp;
279	DB_LSN *lsnp;
280	db_recops op;
281	void *info;
282{
283	__db_debug_args *argp;
284	DB *file_dbp;
285	DBC *dbc;
286	DB_MPOOLFILE *mpf;
287	DB_THREAD_INFO *ip;
288	PAGE *pagep;
289	int cmp_n, cmp_p, modified, ret;
290
291	ip = ((DB_TXNHEAD *)info)->thread_info;
292
293	REC_PRINT(__db_debug_print);
294	REC_INTRO(__db_debug_read, ip, 0);
295
296	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
297		if (DB_REDO(op)) {
298			if ((ret = mpf->get(mpf,
299			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
300				goto out;
301		} else {
302			*lsnp = argp->prev_lsn;
303			ret = 0;
304			goto out;
305		}
306
307	modified = 0;
308	cmp_n = log_compare(lsnp, &LSN(pagep));
309
310	/*
311	 * Use this when there is something like "pagelsn" in the argp
312	 * structure.  Sometimes, you might need to compare meta-data
313	 * lsn's instead.
314	 *
315	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
316	 */
317	if (cmp_p == 0 && DB_REDO(op)) {
318		/* Need to redo update described. */
319		modified = 1;
320	} else if (cmp_n == 0 && !DB_REDO(op)) {
321		/* Need to undo update described. */
322		modified = 1;
323	}
324	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
325		goto out;
326
327	*lsnp = argp->prev_lsn;
328	ret = 0;
329
330out:	REC_CLOSE;
331}
332
333/*
334 * __db_noop_recover --
335 *	Recovery function for noop.
336 *
337 * PUBLIC: int __db_noop_recover
338 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
339 */
340int
341__db_noop_recover(env, dbtp, lsnp, op, info)
342	env *env;
343	DBT *dbtp;
344	DB_LSN *lsnp;
345	db_recops op;
346	void *info;
347{
348	__db_noop_args *argp;
349	DB *file_dbp;
350	DBC *dbc;
351	DB_MPOOLFILE *mpf;
352	DB_THREAD_INFO *ip;
353	PAGE *pagep;
354	int cmp_n, cmp_p, modified, ret;
355
356	ip = ((DB_TXNHEAD *)info)->thread_info;
357
358	REC_PRINT(__db_noop_print);
359	REC_INTRO(__db_noop_read, ip, 0);
360
361	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
362		if (DB_REDO(op)) {
363			if ((ret = mpf->get(mpf,
364			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
365				goto out;
366		} else {
367			*lsnp = argp->prev_lsn;
368			ret = 0;
369			goto out;
370		}
371
372	modified = 0;
373	cmp_n = log_compare(lsnp, &LSN(pagep));
374
375	/*
376	 * Use this when there is something like "pagelsn" in the argp
377	 * structure.  Sometimes, you might need to compare meta-data
378	 * lsn's instead.
379	 *
380	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
381	 */
382	if (cmp_p == 0 && DB_REDO(op)) {
383		/* Need to redo update described. */
384		modified = 1;
385	} else if (cmp_n == 0 && !DB_REDO(op)) {
386		/* Need to undo update described. */
387		modified = 1;
388	}
389	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
390		goto out;
391
392	*lsnp = argp->prev_lsn;
393	ret = 0;
394
395out:	REC_CLOSE;
396}
397
398/*
399 * __db_pg_alloc_recover --
400 *	Recovery function for pg_alloc.
401 *
402 * PUBLIC: int __db_pg_alloc_recover
403 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
404 */
405int
406__db_pg_alloc_recover(env, dbtp, lsnp, op, info)
407	env *env;
408	DBT *dbtp;
409	DB_LSN *lsnp;
410	db_recops op;
411	void *info;
412{
413	__db_pg_alloc_args *argp;
414	DB *file_dbp;
415	DBC *dbc;
416	DB_MPOOLFILE *mpf;
417	DB_THREAD_INFO *ip;
418	PAGE *pagep;
419	int cmp_n, cmp_p, modified, ret;
420
421	ip = ((DB_TXNHEAD *)info)->thread_info;
422
423	REC_PRINT(__db_pg_alloc_print);
424	REC_INTRO(__db_pg_alloc_read, ip, 0);
425
426	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
427		if (DB_REDO(op)) {
428			if ((ret = mpf->get(mpf,
429			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
430				goto out;
431		} else {
432			*lsnp = argp->prev_lsn;
433			ret = 0;
434			goto out;
435		}
436
437	modified = 0;
438	cmp_n = log_compare(lsnp, &LSN(pagep));
439
440	/*
441	 * Use this when there is something like "pagelsn" in the argp
442	 * structure.  Sometimes, you might need to compare meta-data
443	 * lsn's instead.
444	 *
445	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
446	 */
447	if (cmp_p == 0 && DB_REDO(op)) {
448		/* Need to redo update described. */
449		modified = 1;
450	} else if (cmp_n == 0 && !DB_REDO(op)) {
451		/* Need to undo update described. */
452		modified = 1;
453	}
454	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
455		goto out;
456
457	*lsnp = argp->prev_lsn;
458	ret = 0;
459
460out:	REC_CLOSE;
461}
462
463/*
464 * __db_pg_alloc_recover --
465 *	Recovery function for pg_alloc.
466 *
467 * PUBLIC: int __db_pg_alloc_recover
468 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
469 */
470int
471__db_pg_alloc_recover(env, dbtp, lsnp, op, info)
472	env *env;
473	DBT *dbtp;
474	DB_LSN *lsnp;
475	db_recops op;
476	void *info;
477{
478	__db_pg_alloc_args *argp;
479	DB *file_dbp;
480	DBC *dbc;
481	DB_MPOOLFILE *mpf;
482	DB_THREAD_INFO *ip;
483	PAGE *pagep;
484	int cmp_n, cmp_p, modified, ret;
485
486	ip = ((DB_TXNHEAD *)info)->thread_info;
487
488	REC_PRINT(__db_pg_alloc_print);
489	REC_INTRO(__db_pg_alloc_read, ip, 0);
490
491	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
492		if (DB_REDO(op)) {
493			if ((ret = mpf->get(mpf,
494			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
495				goto out;
496		} else {
497			*lsnp = argp->prev_lsn;
498			ret = 0;
499			goto out;
500		}
501
502	modified = 0;
503	cmp_n = log_compare(lsnp, &LSN(pagep));
504
505	/*
506	 * Use this when there is something like "pagelsn" in the argp
507	 * structure.  Sometimes, you might need to compare meta-data
508	 * lsn's instead.
509	 *
510	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
511	 */
512	if (cmp_p == 0 && DB_REDO(op)) {
513		/* Need to redo update described. */
514		modified = 1;
515	} else if (cmp_n == 0 && !DB_REDO(op)) {
516		/* Need to undo update described. */
517		modified = 1;
518	}
519	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
520		goto out;
521
522	*lsnp = argp->prev_lsn;
523	ret = 0;
524
525out:	REC_CLOSE;
526}
527
528/*
529 * __db_pg_free_recover --
530 *	Recovery function for pg_free.
531 *
532 * PUBLIC: int __db_pg_free_recover
533 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
534 */
535int
536__db_pg_free_recover(env, dbtp, lsnp, op, info)
537	env *env;
538	DBT *dbtp;
539	DB_LSN *lsnp;
540	db_recops op;
541	void *info;
542{
543	__db_pg_free_args *argp;
544	DB *file_dbp;
545	DBC *dbc;
546	DB_MPOOLFILE *mpf;
547	DB_THREAD_INFO *ip;
548	PAGE *pagep;
549	int cmp_n, cmp_p, modified, ret;
550
551	ip = ((DB_TXNHEAD *)info)->thread_info;
552
553	REC_PRINT(__db_pg_free_print);
554	REC_INTRO(__db_pg_free_read, ip, 0);
555
556	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
557		if (DB_REDO(op)) {
558			if ((ret = mpf->get(mpf,
559			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
560				goto out;
561		} else {
562			*lsnp = argp->prev_lsn;
563			ret = 0;
564			goto out;
565		}
566
567	modified = 0;
568	cmp_n = log_compare(lsnp, &LSN(pagep));
569
570	/*
571	 * Use this when there is something like "pagelsn" in the argp
572	 * structure.  Sometimes, you might need to compare meta-data
573	 * lsn's instead.
574	 *
575	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
576	 */
577	if (cmp_p == 0 && DB_REDO(op)) {
578		/* Need to redo update described. */
579		modified = 1;
580	} else if (cmp_n == 0 && !DB_REDO(op)) {
581		/* Need to undo update described. */
582		modified = 1;
583	}
584	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
585		goto out;
586
587	*lsnp = argp->prev_lsn;
588	ret = 0;
589
590out:	REC_CLOSE;
591}
592
593/*
594 * __db_pg_free_recover --
595 *	Recovery function for pg_free.
596 *
597 * PUBLIC: int __db_pg_free_recover
598 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
599 */
600int
601__db_pg_free_recover(env, dbtp, lsnp, op, info)
602	env *env;
603	DBT *dbtp;
604	DB_LSN *lsnp;
605	db_recops op;
606	void *info;
607{
608	__db_pg_free_args *argp;
609	DB *file_dbp;
610	DBC *dbc;
611	DB_MPOOLFILE *mpf;
612	DB_THREAD_INFO *ip;
613	PAGE *pagep;
614	int cmp_n, cmp_p, modified, ret;
615
616	ip = ((DB_TXNHEAD *)info)->thread_info;
617
618	REC_PRINT(__db_pg_free_print);
619	REC_INTRO(__db_pg_free_read, ip, 0);
620
621	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
622		if (DB_REDO(op)) {
623			if ((ret = mpf->get(mpf,
624			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
625				goto out;
626		} else {
627			*lsnp = argp->prev_lsn;
628			ret = 0;
629			goto out;
630		}
631
632	modified = 0;
633	cmp_n = log_compare(lsnp, &LSN(pagep));
634
635	/*
636	 * Use this when there is something like "pagelsn" in the argp
637	 * structure.  Sometimes, you might need to compare meta-data
638	 * lsn's instead.
639	 *
640	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
641	 */
642	if (cmp_p == 0 && DB_REDO(op)) {
643		/* Need to redo update described. */
644		modified = 1;
645	} else if (cmp_n == 0 && !DB_REDO(op)) {
646		/* Need to undo update described. */
647		modified = 1;
648	}
649	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
650		goto out;
651
652	*lsnp = argp->prev_lsn;
653	ret = 0;
654
655out:	REC_CLOSE;
656}
657
658/*
659 * __db_cksum_recover --
660 *	Recovery function for cksum.
661 *
662 * PUBLIC: int __db_cksum_recover
663 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
664 */
665int
666__db_cksum_recover(env, dbtp, lsnp, op, info)
667	env *env;
668	DBT *dbtp;
669	DB_LSN *lsnp;
670	db_recops op;
671	void *info;
672{
673	__db_cksum_args *argp;
674	DB *file_dbp;
675	DBC *dbc;
676	DB_MPOOLFILE *mpf;
677	DB_THREAD_INFO *ip;
678	PAGE *pagep;
679	int cmp_n, cmp_p, modified, ret;
680
681	ip = ((DB_TXNHEAD *)info)->thread_info;
682
683	REC_PRINT(__db_cksum_print);
684	REC_INTRO(__db_cksum_read, ip, 0);
685
686	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
687		if (DB_REDO(op)) {
688			if ((ret = mpf->get(mpf,
689			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
690				goto out;
691		} else {
692			*lsnp = argp->prev_lsn;
693			ret = 0;
694			goto out;
695		}
696
697	modified = 0;
698	cmp_n = log_compare(lsnp, &LSN(pagep));
699
700	/*
701	 * Use this when there is something like "pagelsn" in the argp
702	 * structure.  Sometimes, you might need to compare meta-data
703	 * lsn's instead.
704	 *
705	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
706	 */
707	if (cmp_p == 0 && DB_REDO(op)) {
708		/* Need to redo update described. */
709		modified = 1;
710	} else if (cmp_n == 0 && !DB_REDO(op)) {
711		/* Need to undo update described. */
712		modified = 1;
713	}
714	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
715		goto out;
716
717	*lsnp = argp->prev_lsn;
718	ret = 0;
719
720out:	REC_CLOSE;
721}
722
723/*
724 * __db_pg_freedata_recover --
725 *	Recovery function for pg_freedata.
726 *
727 * PUBLIC: int __db_pg_freedata_recover
728 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
729 */
730int
731__db_pg_freedata_recover(env, dbtp, lsnp, op, info)
732	env *env;
733	DBT *dbtp;
734	DB_LSN *lsnp;
735	db_recops op;
736	void *info;
737{
738	__db_pg_freedata_args *argp;
739	DB *file_dbp;
740	DBC *dbc;
741	DB_MPOOLFILE *mpf;
742	DB_THREAD_INFO *ip;
743	PAGE *pagep;
744	int cmp_n, cmp_p, modified, ret;
745
746	ip = ((DB_TXNHEAD *)info)->thread_info;
747
748	REC_PRINT(__db_pg_freedata_print);
749	REC_INTRO(__db_pg_freedata_read, ip, 0);
750
751	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
752		if (DB_REDO(op)) {
753			if ((ret = mpf->get(mpf,
754			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
755				goto out;
756		} else {
757			*lsnp = argp->prev_lsn;
758			ret = 0;
759			goto out;
760		}
761
762	modified = 0;
763	cmp_n = log_compare(lsnp, &LSN(pagep));
764
765	/*
766	 * Use this when there is something like "pagelsn" in the argp
767	 * structure.  Sometimes, you might need to compare meta-data
768	 * lsn's instead.
769	 *
770	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
771	 */
772	if (cmp_p == 0 && DB_REDO(op)) {
773		/* Need to redo update described. */
774		modified = 1;
775	} else if (cmp_n == 0 && !DB_REDO(op)) {
776		/* Need to undo update described. */
777		modified = 1;
778	}
779	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
780		goto out;
781
782	*lsnp = argp->prev_lsn;
783	ret = 0;
784
785out:	REC_CLOSE;
786}
787
788/*
789 * __db_pg_freedata_recover --
790 *	Recovery function for pg_freedata.
791 *
792 * PUBLIC: int __db_pg_freedata_recover
793 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
794 */
795int
796__db_pg_freedata_recover(env, dbtp, lsnp, op, info)
797	env *env;
798	DBT *dbtp;
799	DB_LSN *lsnp;
800	db_recops op;
801	void *info;
802{
803	__db_pg_freedata_args *argp;
804	DB *file_dbp;
805	DBC *dbc;
806	DB_MPOOLFILE *mpf;
807	DB_THREAD_INFO *ip;
808	PAGE *pagep;
809	int cmp_n, cmp_p, modified, ret;
810
811	ip = ((DB_TXNHEAD *)info)->thread_info;
812
813	REC_PRINT(__db_pg_freedata_print);
814	REC_INTRO(__db_pg_freedata_read, ip, 0);
815
816	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
817		if (DB_REDO(op)) {
818			if ((ret = mpf->get(mpf,
819			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
820				goto out;
821		} else {
822			*lsnp = argp->prev_lsn;
823			ret = 0;
824			goto out;
825		}
826
827	modified = 0;
828	cmp_n = log_compare(lsnp, &LSN(pagep));
829
830	/*
831	 * Use this when there is something like "pagelsn" in the argp
832	 * structure.  Sometimes, you might need to compare meta-data
833	 * lsn's instead.
834	 *
835	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
836	 */
837	if (cmp_p == 0 && DB_REDO(op)) {
838		/* Need to redo update described. */
839		modified = 1;
840	} else if (cmp_n == 0 && !DB_REDO(op)) {
841		/* Need to undo update described. */
842		modified = 1;
843	}
844	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
845		goto out;
846
847	*lsnp = argp->prev_lsn;
848	ret = 0;
849
850out:	REC_CLOSE;
851}
852
853/*
854 * __db_pg_init_recover --
855 *	Recovery function for pg_init.
856 *
857 * PUBLIC: int __db_pg_init_recover
858 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
859 */
860int
861__db_pg_init_recover(env, dbtp, lsnp, op, info)
862	env *env;
863	DBT *dbtp;
864	DB_LSN *lsnp;
865	db_recops op;
866	void *info;
867{
868	__db_pg_init_args *argp;
869	DB *file_dbp;
870	DBC *dbc;
871	DB_MPOOLFILE *mpf;
872	DB_THREAD_INFO *ip;
873	PAGE *pagep;
874	int cmp_n, cmp_p, modified, ret;
875
876	ip = ((DB_TXNHEAD *)info)->thread_info;
877
878	REC_PRINT(__db_pg_init_print);
879	REC_INTRO(__db_pg_init_read, ip, 0);
880
881	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
882		if (DB_REDO(op)) {
883			if ((ret = mpf->get(mpf,
884			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
885				goto out;
886		} else {
887			*lsnp = argp->prev_lsn;
888			ret = 0;
889			goto out;
890		}
891
892	modified = 0;
893	cmp_n = log_compare(lsnp, &LSN(pagep));
894
895	/*
896	 * Use this when there is something like "pagelsn" in the argp
897	 * structure.  Sometimes, you might need to compare meta-data
898	 * lsn's instead.
899	 *
900	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
901	 */
902	if (cmp_p == 0 && DB_REDO(op)) {
903		/* Need to redo update described. */
904		modified = 1;
905	} else if (cmp_n == 0 && !DB_REDO(op)) {
906		/* Need to undo update described. */
907		modified = 1;
908	}
909	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
910		goto out;
911
912	*lsnp = argp->prev_lsn;
913	ret = 0;
914
915out:	REC_CLOSE;
916}
917
918/*
919 * __db_pg_sort_recover --
920 *	Recovery function for pg_sort.
921 *
922 * PUBLIC: int __db_pg_sort_recover
923 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
924 */
925int
926__db_pg_sort_recover(env, dbtp, lsnp, op, info)
927	env *env;
928	DBT *dbtp;
929	DB_LSN *lsnp;
930	db_recops op;
931	void *info;
932{
933	__db_pg_sort_args *argp;
934	DB *file_dbp;
935	DBC *dbc;
936	DB_MPOOLFILE *mpf;
937	DB_THREAD_INFO *ip;
938	PAGE *pagep;
939	int cmp_n, cmp_p, modified, ret;
940
941	ip = ((DB_TXNHEAD *)info)->thread_info;
942
943	REC_PRINT(__db_pg_sort_print);
944	REC_INTRO(__db_pg_sort_read, ip, 0);
945
946	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
947		if (DB_REDO(op)) {
948			if ((ret = mpf->get(mpf,
949			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
950				goto out;
951		} else {
952			*lsnp = argp->prev_lsn;
953			ret = 0;
954			goto out;
955		}
956
957	modified = 0;
958	cmp_n = log_compare(lsnp, &LSN(pagep));
959
960	/*
961	 * Use this when there is something like "pagelsn" in the argp
962	 * structure.  Sometimes, you might need to compare meta-data
963	 * lsn's instead.
964	 *
965	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
966	 */
967	if (cmp_p == 0 && DB_REDO(op)) {
968		/* Need to redo update described. */
969		modified = 1;
970	} else if (cmp_n == 0 && !DB_REDO(op)) {
971		/* Need to undo update described. */
972		modified = 1;
973	}
974	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
975		goto out;
976
977	*lsnp = argp->prev_lsn;
978	ret = 0;
979
980out:	REC_CLOSE;
981}
982
983