1#include "db_config.h"
2
3#include "db_int.h"
4#include "dbinc/db_page.h"
5#include "dbinc/__crdel.h"
6#include "dbinc/log.h"
7
8/*
9 * __crdel_metasub_recover --
10 *	Recovery function for metasub.
11 *
12 * PUBLIC: int __crdel_metasub_recover
13 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
14 */
15int
16__crdel_metasub_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	__crdel_metasub_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(__crdel_metasub_print);
34	REC_INTRO(__crdel_metasub_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 * __crdel_inmem_create_recover --
75 *	Recovery function for inmem_create.
76 *
77 * PUBLIC: int __crdel_inmem_create_recover
78 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
79 */
80int
81__crdel_inmem_create_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	__crdel_inmem_create_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(__crdel_inmem_create_print);
99	REC_INTRO(__crdel_inmem_create_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 * __crdel_inmem_rename_recover --
140 *	Recovery function for inmem_rename.
141 *
142 * PUBLIC: int __crdel_inmem_rename_recover
143 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
144 */
145int
146__crdel_inmem_rename_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	__crdel_inmem_rename_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(__crdel_inmem_rename_print);
164	REC_INTRO(__crdel_inmem_rename_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 * __crdel_inmem_remove_recover --
205 *	Recovery function for inmem_remove.
206 *
207 * PUBLIC: int __crdel_inmem_remove_recover
208 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
209 */
210int
211__crdel_inmem_remove_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	__crdel_inmem_remove_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(__crdel_inmem_remove_print);
229	REC_INTRO(__crdel_inmem_remove_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