1/* 2 * PREF_FUNC_recover -- 3 * Recovery function for FUNC. 4 * 5 * PUBLIC: int PREF_FUNC_recover 6 * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); 7 */ 8int 9PREF_FUNC_recover(env, dbtp, lsnp, op, info) 10 env *env; 11 DBT *dbtp; 12 DB_LSN *lsnp; 13 db_recops op; 14 void *info; 15{ 16 PREF_DUP_args *argp; 17 DB *file_dbp; 18 DBC *dbc; 19 DB_MPOOLFILE *mpf; 20 DB_THREAD_INFO *ip; 21 PAGE *pagep; 22 int cmp_n, cmp_p, modified, ret; 23 24 ip = ((DB_TXNHEAD *)info)->thread_info; 25 26 REC_PRINT(PREF_DUP_print); 27 REC_INTRO(PREF_DUP_read, ip, 0); 28 29 if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) 30 if (DB_REDO(op)) { 31 if ((ret = mpf->get(mpf, 32 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) 33 goto out; 34 } else { 35 *lsnp = argp->prev_lsn; 36 ret = 0; 37 goto out; 38 } 39 40 modified = 0; 41 cmp_n = log_compare(lsnp, &LSN(pagep)); 42 43 /* 44 * Use this when there is something like "pagelsn" in the argp 45 * structure. Sometimes, you might need to compare meta-data 46 * lsn's instead. 47 * 48 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); 49 */ 50 if (cmp_p == 0 && DB_REDO(op)) { 51 /* Need to redo update described. */ 52 modified = 1; 53 } else if (cmp_n == 0 && !DB_REDO(op)) { 54 /* Need to undo update described. */ 55 modified = 1; 56 } 57 if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) 58 goto out; 59 60 *lsnp = argp->prev_lsn; 61 ret = 0; 62 63out: REC_CLOSE; 64} 65 66