return (ret);
goto err;
__bam_page(dbp, pp, cp)	DB *dbp;	EPG *pp, *cp;{	BTREE *t;	DB_LOCK tplock;	PAGE *lp, *rp, *tp;	int ret;	t = dbp->internal;	lp = rp = tp = NULL;	ret = -1;	/* Create new right page for the split. */	if ((ret = __bam_new(dbp, TYPE(cp->page), &rp)) != 0)		return (ret);	P_INIT(rp, dbp->pgsize, rp->pgno,	    ISINTERNAL(cp->page) ? PGNO_INVALID : cp->page->pgno,	    ISINTERNAL(cp->page) ? PGNO_INVALID : cp->page->next_pgno,	    cp->page->level, TYPE(cp->page));	/* Create new left page for the split. */	if ((lp = (PAGE *)__db_malloc(dbp->pgsize)) == NULL) {		ret = ENOMEM;		goto err;	}#ifdef DEBUG	memset(lp, 0xff, dbp->pgsize);#endif	P_INIT(lp, dbp->pgsize, cp->page->pgno,	    ISINTERNAL(cp->page) ?  PGNO_INVALID : cp->page->prev_pgno,	    ISINTERNAL(cp->page) ?  PGNO_INVALID : rp->pgno,	    cp->page->level, TYPE(cp->page));	ZERO_LSN(lp->lsn);	/*	 * Split right.	 *	 * Only the indices are sorted on the page, i.e., the key/data pairs	 * aren't, so it's simpler to copy the data from the split page onto	 * two new pages instead of copying half the data to the right page	 * and compacting the left page in place.  Since the left page can't	 * change, we swap the original and the allocated left page after the	 * split.	 */	if ((ret = __bam_psplit(dbp, cp, lp, rp, 0)) != 0)		goto err;	/*	 * Fix up the previous pointer of any leaf page following the split	 * page.	 *	 * !!!	 * There are interesting deadlock situations here as we write-lock a	 * page that's not in our direct ancestry.  Consider a cursor walking	 * through the leaf pages, that has the previous page read-locked and	 * is waiting on a lock for the page we just split.  It will deadlock	 * here.  If this is a problem, we can fail in the split; it's not a	 * problem as the split will succeed after the cursor passes through	 * the page we're splitting.	 */	if (TYPE(cp->page) == P_LBTREE && rp->next_pgno != PGNO_INVALID) {		if ((ret = __bam_lget(dbp,		    0, rp->next_pgno, DB_LOCK_WRITE, &tplock)) != 0)			goto err;		if ((ret = __bam_pget(dbp, &tp, &rp->next_pgno, 0)) != 0)			goto err;	}	/* Insert the new pages into the parent page. */	if ((ret = __bam_pinsert(dbp, pp, lp, rp)) != 0)		goto err;	/* Log the change. */	if (DB_LOGGING(dbp)) {		DBT __a;		DB_LSN __lsn;		memset(&__a, 0, sizeof(__a));		__a.data = cp->page;		__a.size = dbp->pgsize;		if (tp == NULL)			ZERO_LSN(__lsn);		if ((ret = __bam_split_log(dbp->dbenv->lg_info, dbp->txn,		    &cp->page->lsn, 0, dbp->log_fileid, PGNO(cp->page),		    &LSN(cp->page), PGNO(rp), &LSN(rp), (u_int32_t)NUM_ENT(lp),		    tp == NULL ? 0 : PGNO(tp),		    tp == NULL ? &__lsn : &LSN(tp), &__a)) != 0)			goto err;		LSN(lp) = LSN(rp) = LSN(cp->page);		if (tp != NULL)			LSN(tp) = LSN(cp->page);	}	/* Copy the allocated page into place. */	memcpy(cp->page, lp, LOFFSET(lp));	memcpy((u_int8_t *)cp->page + HOFFSET(lp),	    (u_int8_t *)lp + HOFFSET(lp), dbp->pgsize - HOFFSET(lp));	FREE(lp, dbp->pgsize);	lp = NULL;	/* Finish the next-page link. */	if (tp != NULL)		tp->prev_pgno = rp->pgno;	/* Success -- write the real pages back to the store. */	(void)memp_fput(dbp->mpf, pp->page, DB_MPOOL_DIRTY);	(void)__BT_TLPUT(dbp, pp->lock);	(void)memp_fput(dbp->mpf, cp->page, DB_MPOOL_DIRTY);	(void)__BT_TLPUT(dbp, cp->lock);	(void)memp_fput(dbp->mpf, rp, DB_MPOOL_DIRTY);	if (tp != NULL) {		(void)memp_fput(dbp->mpf, tp, DB_MPOOL_DIRTY);		(void)__BT_TLPUT(dbp, tplock);	}	return (0);err:	if (lp != NULL)		FREE(lp, dbp->pgsize);	if (rp != NULL)		(void)__bam_free(dbp, rp);	if (tp != NULL) {		(void)memp_fput(dbp->mpf, tp, 0);		(void)__BT_TLPUT(dbp, tplock);	}	(void)memp_fput(dbp->mpf, pp->page, 0);	(void)__BT_TLPUT(dbp, pp->lock);	(void)memp_fput(dbp->mpf, cp->page, 0);	(void)__BT_TLPUT(dbp, cp->lock);	return (ret);}