xref: /minix3/external/bsd/nvi/dist/common/vi_rec.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc #include "db_config.h"
2*84d9c625SLionel Sambuc 
3*84d9c625SLionel Sambuc #ifndef NO_SYSTEM_INCLUDES
4*84d9c625SLionel Sambuc #include <sys/types.h>
5*84d9c625SLionel Sambuc 
6*84d9c625SLionel Sambuc #include <string.h>
7*84d9c625SLionel Sambuc #endif
8*84d9c625SLionel Sambuc 
9*84d9c625SLionel Sambuc #include "common.h"
10*84d9c625SLionel Sambuc 
11*84d9c625SLionel Sambuc #include "db_int.h"
12*84d9c625SLionel Sambuc #include "db_page.h"
13*84d9c625SLionel Sambuc #include <log.h>
14*84d9c625SLionel Sambuc #include "hash.h"
15*84d9c625SLionel Sambuc #include "btree.h"
16*84d9c625SLionel Sambuc 
17*84d9c625SLionel Sambuc #define LOG_CURSOR_HIT	    -1000
18*84d9c625SLionel Sambuc 
19*84d9c625SLionel Sambuc /*
20*84d9c625SLionel Sambuc  * PUBLIC: #ifdef USE_DB4_LOGGING
21*84d9c625SLionel Sambuc  */
22*84d9c625SLionel Sambuc /*
23*84d9c625SLionel Sambuc  * __vi_marker_recover --
24*84d9c625SLionel Sambuc  *	Recovery function for marker.
25*84d9c625SLionel Sambuc  *
26*84d9c625SLionel Sambuc  * PUBLIC: int __vi_marker_recover
27*84d9c625SLionel Sambuc  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
28*84d9c625SLionel Sambuc  */
29*84d9c625SLionel Sambuc int
__vi_marker_recover(dbenv,dbtp,lsnp,op,info)30*84d9c625SLionel Sambuc __vi_marker_recover(dbenv, dbtp, lsnp, op, info)
31*84d9c625SLionel Sambuc 	DB_ENV *dbenv;
32*84d9c625SLionel Sambuc 	DBT *dbtp;
33*84d9c625SLionel Sambuc 	DB_LSN *lsnp;
34*84d9c625SLionel Sambuc 	db_recops op;
35*84d9c625SLionel Sambuc 	void *info;
36*84d9c625SLionel Sambuc {
37*84d9c625SLionel Sambuc 	__vi_marker_args *argp;
38*84d9c625SLionel Sambuc 	int ret;
39*84d9c625SLionel Sambuc 
40*84d9c625SLionel Sambuc 	REC_PRINT(__vi_marker_print);
41*84d9c625SLionel Sambuc 	REC_NOOP_INTRO(__vi_marker_read);
42*84d9c625SLionel Sambuc 
43*84d9c625SLionel Sambuc 	*lsnp = argp->prev_lsn;
44*84d9c625SLionel Sambuc 	ret = 0;
45*84d9c625SLionel Sambuc 
46*84d9c625SLionel Sambuc     	REC_NOOP_CLOSE;
47*84d9c625SLionel Sambuc }
48*84d9c625SLionel Sambuc 
49*84d9c625SLionel Sambuc /*
50*84d9c625SLionel Sambuc  * __vi_cursor_recover --
51*84d9c625SLionel Sambuc  *	Recovery function for cursor.
52*84d9c625SLionel Sambuc  *
53*84d9c625SLionel Sambuc  * PUBLIC: int __vi_cursor_recover
54*84d9c625SLionel Sambuc  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
55*84d9c625SLionel Sambuc  */
56*84d9c625SLionel Sambuc int
__vi_cursor_recover(dbenv,dbtp,lsnp,op,info)57*84d9c625SLionel Sambuc __vi_cursor_recover(dbenv, dbtp, lsnp, op, info)
58*84d9c625SLionel Sambuc 	DB_ENV *dbenv;
59*84d9c625SLionel Sambuc 	DBT *dbtp;
60*84d9c625SLionel Sambuc 	DB_LSN *lsnp;
61*84d9c625SLionel Sambuc 	db_recops op;
62*84d9c625SLionel Sambuc 	void *info;
63*84d9c625SLionel Sambuc {
64*84d9c625SLionel Sambuc 	__vi_cursor_args *argp;
65*84d9c625SLionel Sambuc 	int ret;
66*84d9c625SLionel Sambuc 	SCR *sp;
67*84d9c625SLionel Sambuc 
68*84d9c625SLionel Sambuc 	REC_PRINT(__vi_cursor_print);
69*84d9c625SLionel Sambuc 	REC_NOOP_INTRO(__vi_cursor_read);
70*84d9c625SLionel Sambuc 
71*84d9c625SLionel Sambuc 	sp = (SCR *)dbenv->app_private;
72*84d9c625SLionel Sambuc 
73*84d9c625SLionel Sambuc 	*lsnp = argp->prev_lsn;
74*84d9c625SLionel Sambuc 	if (sp->state.undo == UNDO_SETLINE) {
75*84d9c625SLionel Sambuc 		/* Why the check for ep->l_cur ? (copied from log.c)
76*84d9c625SLionel Sambuc 		 */
77*84d9c625SLionel Sambuc 		ret = (argp->lno != sp->lno ||
78*84d9c625SLionel Sambuc 		    (argp->opcode == LOG_CURSOR_INIT && sp->ep->l_cur == 1))
79*84d9c625SLionel Sambuc 			  ? LOG_CURSOR_HIT : 0;
80*84d9c625SLionel Sambuc 	}
81*84d9c625SLionel Sambuc 	else {
82*84d9c625SLionel Sambuc 		ret = argp->opcode ==
83*84d9c625SLionel Sambuc 			(DB_UNDO(op) ? LOG_CURSOR_INIT : LOG_CURSOR_END)
84*84d9c625SLionel Sambuc 			  ? LOG_CURSOR_HIT : 0;
85*84d9c625SLionel Sambuc 		if (ret) {
86*84d9c625SLionel Sambuc 			sp->state.pos.lno = argp->lno;
87*84d9c625SLionel Sambuc 			sp->state.pos.cno = argp->cno;
88*84d9c625SLionel Sambuc 		}
89*84d9c625SLionel Sambuc 	}
90*84d9c625SLionel Sambuc 
91*84d9c625SLionel Sambuc     	REC_NOOP_CLOSE;
92*84d9c625SLionel Sambuc }
93*84d9c625SLionel Sambuc 
94*84d9c625SLionel Sambuc /*
95*84d9c625SLionel Sambuc  * __vi_mark_recover --
96*84d9c625SLionel Sambuc  *	Recovery function for mark.
97*84d9c625SLionel Sambuc  *
98*84d9c625SLionel Sambuc  * PUBLIC: int __vi_mark_recover
99*84d9c625SLionel Sambuc  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
100*84d9c625SLionel Sambuc  */
101*84d9c625SLionel Sambuc int
__vi_mark_recover(dbenv,dbtp,lsnp,op,info)102*84d9c625SLionel Sambuc __vi_mark_recover(dbenv, dbtp, lsnp, op, info)
103*84d9c625SLionel Sambuc 	DB_ENV *dbenv;
104*84d9c625SLionel Sambuc 	DBT *dbtp;
105*84d9c625SLionel Sambuc 	DB_LSN *lsnp;
106*84d9c625SLionel Sambuc 	db_recops op;
107*84d9c625SLionel Sambuc 	void *info;
108*84d9c625SLionel Sambuc {
109*84d9c625SLionel Sambuc 	__vi_mark_args *argp;
110*84d9c625SLionel Sambuc 	int ret;
111*84d9c625SLionel Sambuc 	MARK m;
112*84d9c625SLionel Sambuc 	SCR *sp;
113*84d9c625SLionel Sambuc 
114*84d9c625SLionel Sambuc 	REC_PRINT(__vi_mark_print);
115*84d9c625SLionel Sambuc 	REC_NOOP_INTRO(__vi_mark_read);
116*84d9c625SLionel Sambuc 
117*84d9c625SLionel Sambuc 	sp = (SCR *)dbenv->app_private;
118*84d9c625SLionel Sambuc 	*lsnp = argp->prev_lsn;
119*84d9c625SLionel Sambuc 	m.lno = argp->lmp.lno;
120*84d9c625SLionel Sambuc 	m.cno = argp->lmp.cno;
121*84d9c625SLionel Sambuc 	ret = mark_set(sp, argp->lmp.name, &m, 0);
122*84d9c625SLionel Sambuc 
123*84d9c625SLionel Sambuc     	REC_NOOP_CLOSE;
124*84d9c625SLionel Sambuc }
125*84d9c625SLionel Sambuc 
126*84d9c625SLionel Sambuc /*
127*84d9c625SLionel Sambuc  * __vi_change_recover --
128*84d9c625SLionel Sambuc  *	Recovery function for change.
129*84d9c625SLionel Sambuc  *
130*84d9c625SLionel Sambuc  * PUBLIC: int __vi_change_recover
131*84d9c625SLionel Sambuc  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
132*84d9c625SLionel Sambuc  */
133*84d9c625SLionel Sambuc int
__vi_change_recover(dbenv,dbtp,lsnp,op,info)134*84d9c625SLionel Sambuc __vi_change_recover(dbenv, dbtp, lsnp, op, info)
135*84d9c625SLionel Sambuc 	DB_ENV *dbenv;
136*84d9c625SLionel Sambuc 	DBT *dbtp;
137*84d9c625SLionel Sambuc 	DB_LSN *lsnp;
138*84d9c625SLionel Sambuc 	db_recops op;
139*84d9c625SLionel Sambuc 	void *info;
140*84d9c625SLionel Sambuc {
141*84d9c625SLionel Sambuc 	__vi_change_args *argp;
142*84d9c625SLionel Sambuc 	int ret;
143*84d9c625SLionel Sambuc 	SCR *sp;
144*84d9c625SLionel Sambuc 
145*84d9c625SLionel Sambuc 	REC_PRINT(__vi_change_print);
146*84d9c625SLionel Sambuc 	REC_NOOP_INTRO(__vi_change_read);
147*84d9c625SLionel Sambuc 
148*84d9c625SLionel Sambuc 	ret = 0;
149*84d9c625SLionel Sambuc 
150*84d9c625SLionel Sambuc 	sp = (SCR *)dbenv->app_private;
151*84d9c625SLionel Sambuc 	if (DB_UNDO(op) != (argp->opcode & 1))
152*84d9c625SLionel Sambuc 	    switch (argp->opcode) {
153*84d9c625SLionel Sambuc 	    case LOG_LINE_RESET_B:
154*84d9c625SLionel Sambuc 	    case LOG_LINE_RESET_F:
155*84d9c625SLionel Sambuc 		    ret = line_insdel(sp, LINE_RESET, argp->lno);
156*84d9c625SLionel Sambuc 		    update_cache(sp, LINE_RESET, argp->lno);
157*84d9c625SLionel Sambuc 		    ret = scr_update(sp, argp->lno, LINE_RESET, 1) || ret;
158*84d9c625SLionel Sambuc 		    break;
159*84d9c625SLionel Sambuc 	    case LOG_LINE_APPEND_B:
160*84d9c625SLionel Sambuc 	    case LOG_LINE_DELETE_F:
161*84d9c625SLionel Sambuc 		    ret = line_insdel(sp, LINE_DELETE, argp->lno);
162*84d9c625SLionel Sambuc 		    update_cache(sp, LINE_DELETE, argp->lno);
163*84d9c625SLionel Sambuc 		    ret = scr_update(sp, argp->lno, LINE_DELETE, 1) || ret;
164*84d9c625SLionel Sambuc 		    break;
165*84d9c625SLionel Sambuc 	    case LOG_LINE_DELETE_B:
166*84d9c625SLionel Sambuc 	    case LOG_LINE_APPEND_F:
167*84d9c625SLionel Sambuc 		    ret = line_insdel(sp, LINE_INSERT, argp->lno);
168*84d9c625SLionel Sambuc 		    update_cache(sp, LINE_INSERT, argp->lno);
169*84d9c625SLionel Sambuc 		    ret = scr_update(sp, argp->lno, LINE_INSERT, 1) || ret;
170*84d9c625SLionel Sambuc 		    break;
171*84d9c625SLionel Sambuc 	    }
172*84d9c625SLionel Sambuc 
173*84d9c625SLionel Sambuc 	*lsnp = argp->prev_lsn;
174*84d9c625SLionel Sambuc 
175*84d9c625SLionel Sambuc     	REC_NOOP_CLOSE;
176*84d9c625SLionel Sambuc }
177*84d9c625SLionel Sambuc 
178*84d9c625SLionel Sambuc /*
179*84d9c625SLionel Sambuc  *
180*84d9c625SLionel Sambuc  * PUBLIC: int __vi_log_truncate __P((EXF *ep));
181*84d9c625SLionel Sambuc  */
182*84d9c625SLionel Sambuc int
__vi_log_truncate(EXF * ep)183*84d9c625SLionel Sambuc __vi_log_truncate(EXF *ep)
184*84d9c625SLionel Sambuc {
185*84d9c625SLionel Sambuc 	DB_LSN ckplsn;
186*84d9c625SLionel Sambuc 
187*84d9c625SLionel Sambuc 	ZERO_LSN(ckplsn);
188*84d9c625SLionel Sambuc 	return __log_vtruncate(ep->env, &ep->lsn_cur, &ckplsn);
189*84d9c625SLionel Sambuc 	/*return __log_vtruncate(ep->env, &ep->lsn_cur, &ep->lsn_first);*/
190*84d9c625SLionel Sambuc }
191*84d9c625SLionel Sambuc 
192*84d9c625SLionel Sambuc /*
193*84d9c625SLionel Sambuc  *
194*84d9c625SLionel Sambuc  * PUBLIC: int __vi_log_dispatch __P((DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops));
195*84d9c625SLionel Sambuc  */
196*84d9c625SLionel Sambuc int
__vi_log_dispatch(DB_ENV * dbenv,DBT * data,DB_LSN * lsn,db_recops ops)197*84d9c625SLionel Sambuc __vi_log_dispatch(DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops)
198*84d9c625SLionel Sambuc {
199*84d9c625SLionel Sambuc 	u_int32_t rectype;
200*84d9c625SLionel Sambuc 	char	s[100];
201*84d9c625SLionel Sambuc 
202*84d9c625SLionel Sambuc 	memcpy(&rectype, data->data, sizeof(rectype));
203*84d9c625SLionel Sambuc 	snprintf(s,100,"%d\n", rectype);
204*84d9c625SLionel Sambuc 	return dbenv->dtab[rectype](dbenv, data, lsn, ops, NULL);
205*84d9c625SLionel Sambuc }
206*84d9c625SLionel Sambuc 
207*84d9c625SLionel Sambuc static int
vi_log_get(SCR * sp,DB_LOGC * logc,DBT * data,u_int32_t which)208*84d9c625SLionel Sambuc vi_log_get(SCR *sp, DB_LOGC *logc, DBT *data, u_int32_t which)
209*84d9c625SLionel Sambuc {
210*84d9c625SLionel Sambuc 	size_t nlen;
211*84d9c625SLionel Sambuc 	EXF *ep;
212*84d9c625SLionel Sambuc 
213*84d9c625SLionel Sambuc 	ep = sp->ep;
214*84d9c625SLionel Sambuc 
215*84d9c625SLionel Sambuc 	nlen = 1024;
216*84d9c625SLionel Sambuc retry:
217*84d9c625SLionel Sambuc 	BINC_GOTO(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
218*84d9c625SLionel Sambuc 	memset(data, 0, sizeof(*data));
219*84d9c625SLionel Sambuc 	data->data = sp->wp->l_lp;
220*84d9c625SLionel Sambuc 	data->ulen = sp->wp->l_len;
221*84d9c625SLionel Sambuc 	data->flags = DB_DBT_USERMEM;
222*84d9c625SLionel Sambuc 	switch ((sp->db_error = logc->get(logc, &ep->lsn_cur, data, which))) {
223*84d9c625SLionel Sambuc 	case ENOMEM:
224*84d9c625SLionel Sambuc 		nlen = data->size;
225*84d9c625SLionel Sambuc 		goto retry;
226*84d9c625SLionel Sambuc 	default:
227*84d9c625SLionel Sambuc alloc_err:
228*84d9c625SLionel Sambuc 		msgq(sp, M_DBERR, "logc->get");
229*84d9c625SLionel Sambuc 		F_SET(ep, F_NOLOG);
230*84d9c625SLionel Sambuc 		return (1);
231*84d9c625SLionel Sambuc 	case 0:
232*84d9c625SLionel Sambuc 		;
233*84d9c625SLionel Sambuc 	}
234*84d9c625SLionel Sambuc 	return 0;
235*84d9c625SLionel Sambuc }
236*84d9c625SLionel Sambuc 
237*84d9c625SLionel Sambuc /*
238*84d9c625SLionel Sambuc  *
239*84d9c625SLionel Sambuc  * PUBLIC: int __vi_log_traverse __P((SCR *sp, undo_t undo, MARK *));
240*84d9c625SLionel Sambuc  */
241*84d9c625SLionel Sambuc int
__vi_log_traverse(SCR * sp,undo_t undo,MARK * rp)242*84d9c625SLionel Sambuc __vi_log_traverse(SCR *sp, undo_t undo, MARK *rp)
243*84d9c625SLionel Sambuc {
244*84d9c625SLionel Sambuc 	DB_LOGC *logc;
245*84d9c625SLionel Sambuc 	DBT data;
246*84d9c625SLionel Sambuc 	EXF *ep;
247*84d9c625SLionel Sambuc 	int	    ret;
248*84d9c625SLionel Sambuc 	DB_LSN	    lsn;
249*84d9c625SLionel Sambuc 	u_int32_t   which;
250*84d9c625SLionel Sambuc 	db_recops   ops;
251*84d9c625SLionel Sambuc 
252*84d9c625SLionel Sambuc 	ep = sp->ep;
253*84d9c625SLionel Sambuc 
254*84d9c625SLionel Sambuc 	F_SET(ep, F_NOLOG);		/* Turn off logging. */
255*84d9c625SLionel Sambuc 
256*84d9c625SLionel Sambuc 	sp->state.undo = undo;
257*84d9c625SLionel Sambuc 	ep->env->app_private = sp;
258*84d9c625SLionel Sambuc 	if ((sp->db_error = ep->env->log_cursor(ep->env, &logc, 0))
259*84d9c625SLionel Sambuc 		    != 0) {
260*84d9c625SLionel Sambuc 		msgq(sp, M_DBERR, "env->log_cursor");
261*84d9c625SLionel Sambuc 		return (1);
262*84d9c625SLionel Sambuc 	}
263*84d9c625SLionel Sambuc 	if (vi_log_get(sp, logc, &data, DB_SET))
264*84d9c625SLionel Sambuc 		return 1;
265*84d9c625SLionel Sambuc 	if (undo == UNDO_FORWARD) {
266*84d9c625SLionel Sambuc 		ops = DB_TXN_FORWARD_ROLL;
267*84d9c625SLionel Sambuc 		which = DB_NEXT;
268*84d9c625SLionel Sambuc 		if (vi_log_get(sp, logc, &data, DB_NEXT))
269*84d9c625SLionel Sambuc 			return 1;
270*84d9c625SLionel Sambuc 	} else {
271*84d9c625SLionel Sambuc 		ops = DB_TXN_BACKWARD_ROLL;
272*84d9c625SLionel Sambuc 		which = DB_PREV;
273*84d9c625SLionel Sambuc 	}
274*84d9c625SLionel Sambuc 
275*84d9c625SLionel Sambuc 	for (;;) {
276*84d9c625SLionel Sambuc 		MEMCPY(&lsn, &ep->lsn_cur, 1);
277*84d9c625SLionel Sambuc 		ret = __vi_log_dispatch(ep->env, &data, &lsn, ops);
278*84d9c625SLionel Sambuc 		if (ret != 0) {
279*84d9c625SLionel Sambuc 			if (ret == LOG_CURSOR_HIT)
280*84d9c625SLionel Sambuc 				break;
281*84d9c625SLionel Sambuc 		}
282*84d9c625SLionel Sambuc 
283*84d9c625SLionel Sambuc 		if (vi_log_get(sp, logc, &data, which))
284*84d9c625SLionel Sambuc 			return 1;
285*84d9c625SLionel Sambuc 		if (undo == UNDO_SETLINE &&
286*84d9c625SLionel Sambuc 		    log_compare(&ep->lsn_cur, &ep->lsn_first) <= 0) {
287*84d9c625SLionel Sambuc 			/* Move to previous record without dispatching. */
288*84d9c625SLionel Sambuc 			undo = UNDO_BACKWARD;
289*84d9c625SLionel Sambuc 			break;
290*84d9c625SLionel Sambuc 		}
291*84d9c625SLionel Sambuc 	}
292*84d9c625SLionel Sambuc 	if (undo == UNDO_BACKWARD)
293*84d9c625SLionel Sambuc 		if (vi_log_get(sp, logc, &data, DB_PREV))
294*84d9c625SLionel Sambuc 			return 1;
295*84d9c625SLionel Sambuc 
296*84d9c625SLionel Sambuc 	logc->close(logc, 0);
297*84d9c625SLionel Sambuc 
298*84d9c625SLionel Sambuc 	ep->env->app_private = NULL;
299*84d9c625SLionel Sambuc 
300*84d9c625SLionel Sambuc 	MEMMOVE(rp, &sp->state.pos, 1);
301*84d9c625SLionel Sambuc 
302*84d9c625SLionel Sambuc 	F_CLR(ep, F_NOLOG);
303*84d9c625SLionel Sambuc 
304*84d9c625SLionel Sambuc 	return 0;
305*84d9c625SLionel Sambuc }
306*84d9c625SLionel Sambuc 
307*84d9c625SLionel Sambuc int
vi_db_init_recover(DB_ENV * dbenv)308*84d9c625SLionel Sambuc vi_db_init_recover(DB_ENV *dbenv)
309*84d9c625SLionel Sambuc {
310*84d9c625SLionel Sambuc 	int	ret;
311*84d9c625SLionel Sambuc 
312*84d9c625SLionel Sambuc 	if ((ret = __db_init_recover(dbenv)) != 0)
313*84d9c625SLionel Sambuc 		return (ret);
314*84d9c625SLionel Sambuc 	if ((ret = __bam_init_recover(dbenv)) != 0)
315*84d9c625SLionel Sambuc 		return (ret);
316*84d9c625SLionel Sambuc 
317*84d9c625SLionel Sambuc 	return 0;
318*84d9c625SLionel Sambuc }
319*84d9c625SLionel Sambuc /*
320*84d9c625SLionel Sambuc  * PUBLIC: #endif
321*84d9c625SLionel Sambuc  */
322