1#include "db_config.h"
2
3#include "db_int.h"
4#include "dbinc/db_page.h"
5#include "dbinc/__ham.h"
6#include "dbinc/log.h"
7
8/*
9 * __ham_insdel_recover --
10 *	Recovery function for insdel.
11 *
12 * PUBLIC: int __ham_insdel_recover
13 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
14 */
15int
16__ham_insdel_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	__ham_insdel_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(__ham_insdel_print);
34	REC_INTRO(__ham_insdel_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 * __ham_newpage_recover --
75 *	Recovery function for newpage.
76 *
77 * PUBLIC: int __ham_newpage_recover
78 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
79 */
80int
81__ham_newpage_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	__ham_newpage_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(__ham_newpage_print);
99	REC_INTRO(__ham_newpage_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 * __ham_splitdata_recover --
140 *	Recovery function for splitdata.
141 *
142 * PUBLIC: int __ham_splitdata_recover
143 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
144 */
145int
146__ham_splitdata_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	__ham_splitdata_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(__ham_splitdata_print);
164	REC_INTRO(__ham_splitdata_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 * __ham_replace_recover --
205 *	Recovery function for replace.
206 *
207 * PUBLIC: int __ham_replace_recover
208 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
209 */
210int
211__ham_replace_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	__ham_replace_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(__ham_replace_print);
229	REC_INTRO(__ham_replace_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 * __ham_copypage_recover --
270 *	Recovery function for copypage.
271 *
272 * PUBLIC: int __ham_copypage_recover
273 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
274 */
275int
276__ham_copypage_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	__ham_copypage_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(__ham_copypage_print);
294	REC_INTRO(__ham_copypage_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 * __ham_metagroup_recover --
335 *	Recovery function for metagroup.
336 *
337 * PUBLIC: int __ham_metagroup_recover
338 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
339 */
340int
341__ham_metagroup_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	__ham_metagroup_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(__ham_metagroup_print);
359	REC_INTRO(__ham_metagroup_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 * __ham_metagroup_recover --
400 *	Recovery function for metagroup.
401 *
402 * PUBLIC: int __ham_metagroup_recover
403 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
404 */
405int
406__ham_metagroup_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	__ham_metagroup_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(__ham_metagroup_print);
424	REC_INTRO(__ham_metagroup_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 * __ham_groupalloc_recover --
465 *	Recovery function for groupalloc.
466 *
467 * PUBLIC: int __ham_groupalloc_recover
468 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
469 */
470int
471__ham_groupalloc_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	__ham_groupalloc_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(__ham_groupalloc_print);
489	REC_INTRO(__ham_groupalloc_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 * __ham_groupalloc_recover --
530 *	Recovery function for groupalloc.
531 *
532 * PUBLIC: int __ham_groupalloc_recover
533 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
534 */
535int
536__ham_groupalloc_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	__ham_groupalloc_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(__ham_groupalloc_print);
554	REC_INTRO(__ham_groupalloc_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 * __ham_curadj_recover --
595 *	Recovery function for curadj.
596 *
597 * PUBLIC: int __ham_curadj_recover
598 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
599 */
600int
601__ham_curadj_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	__ham_curadj_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(__ham_curadj_print);
619	REC_INTRO(__ham_curadj_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 * __ham_chgpg_recover --
660 *	Recovery function for chgpg.
661 *
662 * PUBLIC: int __ham_chgpg_recover
663 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
664 */
665int
666__ham_chgpg_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	__ham_chgpg_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(__ham_chgpg_print);
684	REC_INTRO(__ham_chgpg_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