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