DB_LOG *logp; DBT rdbt; DB_LSN key_lsn;
__txn_undo(txnp)	DB_TXN *txnp;{	DB_TXNMGR *mgr;	DB_LOG *logp;	DBT rdbt;	DB_LSN key_lsn;	int ret;	mgr = txnp->mgrp;	logp = mgr->dbenv->lg_info;	if (logp == NULL)		return (0);	/*	 * This is the simplest way to code this, but if the mallocs during	 * recovery turn out to be a performance issue, we can do the	 * allocation here and use DB_DBT_USERMEM.	 */	memset(&rdbt, 0, sizeof(rdbt));	if (F_ISSET(logp, DB_AM_THREAD))		F_SET(&rdbt, DB_DBT_MALLOC);	key_lsn = txnp->last_lsn;		/* structure assignment */	for (ret = 0; ret == 0 && !IS_ZERO_LSN(key_lsn);) {		/*		 * The dispatch routine returns the lsn of the record		 * before the current one in the key_lsn argument.		 */		if ((ret = log_get(logp, &key_lsn, &rdbt, DB_SET)) == 0) {			ret =			    mgr->recover(logp, &rdbt, &key_lsn, TXN_UNDO, NULL);			if (F_ISSET(logp, DB_AM_THREAD) && rdbt.data != NULL) {				__db_free(rdbt.data);				rdbt.data = NULL;			}		}		if (ret != 0)			return (ret);	}	return (ret);}