if (dbmfp->fd == -1) if ((ret = __db_appname(dbenv, DB_APP_TMP, NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1) { UNLOCKHANDLE(dbmp, dbmfp->mutexp); __db_err(dbenv, "unable to create temporary backing file"); goto err; }
if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv, DB_APP_TMP, NULL, NULL, DB_CREATE | DB_EXCL | DB_TEMPORARY, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) { UNLOCKHANDLE(dbmp, dbmfp->mutexp); __db_err(dbenv, "unable to create temporary backing file"); goto err; }
__memp_pgwrite(dbmfp, bhp, restartp, wrotep)	DB_MPOOLFILE *dbmfp;	BH *bhp;	int *restartp, *wrotep;{	DB_ENV *dbenv;	DB_LOG *lg_info;	DB_LSN lsn;	DB_MPOOL *dbmp;	MPOOL *mp;	MPOOLFILE *mfp;	size_t pagesize;	ssize_t nw;	int callpgin, ret, syncfail;	const char *fail;	dbmp = dbmfp->dbmp;	dbenv = dbmp->dbenv;	mp = dbmp->mp;	mfp = dbmfp->mfp;	if (restartp != NULL)		*restartp = 0;	if (wrotep != NULL)		*wrotep = 0;	callpgin = 0;	pagesize = mfp->stat.st_pagesize;	/*	 * Check the dirty bit -- this buffer may have been written since we	 * decided to write it.	 */	if (!F_ISSET(bhp, BH_DIRTY)) {		if (wrotep != NULL)			*wrotep = 1;		return (0);	}	LOCKBUFFER(dbmp, bhp);	/*	 * If there were two writers, we may have just been waiting while the	 * other writer completed I/O on this buffer.  Check the dirty bit one	 * more time.	 */	if (!F_ISSET(bhp, BH_DIRTY)) {		UNLOCKBUFFER(dbmp, bhp);		if (wrotep != NULL)			*wrotep = 1;		return (0);	}	F_SET(bhp, BH_LOCKED);	UNLOCKREGION(dbmp);	if (restartp != NULL)		*restartp = 1;	/* Copy the LSN off the page if we're going to need it. */	lg_info = dbenv->lg_info;	if (lg_info != NULL || F_ISSET(bhp, BH_WRITE))		memcpy(&lsn, bhp->buf + mfp->lsn_off, sizeof(DB_LSN));	/* Ensure the appropriate log records are on disk. */	if (lg_info != NULL && (ret = log_flush(lg_info, &lsn)) != 0)		goto err;	/*	 * Call any pgout function.  We set the callpgin flag so that we flag	 * that the contents of the buffer will need to be passed through pgin	 * before they are reused.	 */	if (mfp->ftype == 0)		ret = 0;	else {		callpgin = 1;		if ((ret = __memp_pg(dbmfp, bhp, 0)) != 0)			goto err;	}	/* Temporary files may not yet have been created. */	LOCKHANDLE(dbmp, dbmfp->mutexp);	if (dbmfp->fd == -1)		if ((ret = __db_appname(dbenv, DB_APP_TMP,		    NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1) {			UNLOCKHANDLE(dbmp, dbmfp->mutexp);			__db_err(dbenv,			    "unable to create temporary backing file");			goto err;		}	/* Write the page out. */	if ((ret = __db_seek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0)		fail = "seek";	else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)		fail = "write";	UNLOCKHANDLE(dbmp, dbmfp->mutexp);	if (ret != 0) {		/*		 * XXX		 * Shut the compiler up; it doesn't understand the correlation		 * between the failing clauses to __db_lseek and __db_write and		 * this ret != 0.		 */		COMPQUIET(fail, NULL);		goto syserr;	}	if (nw != (ssize_t)pagesize) {		ret = EIO;		fail = "write";		goto syserr;	}	if (wrotep != NULL)		*wrotep = 1;	/* Unlock the buffer and reacquire the region lock. */	UNLOCKBUFFER(dbmp, bhp);	LOCKREGION(dbmp);	/*	 * Clean up the flags based on a successful write.	 *	 * If we rewrote the page, it will need processing by the pgin	 * routine before reuse.	 */	if (callpgin)		F_SET(bhp, BH_CALLPGIN);	F_CLR(bhp, BH_DIRTY | BH_LOCKED);	/*	 * If we write a buffer for which a checkpoint is waiting, update	 * the count of pending buffers (both in the mpool as a whole and	 * for this file).  If the count for this file goes to zero, flush	 * the writes.	 *	 * XXX:	 * Don't lock the region around the sync, fsync(2) has no atomicity	 * issues.	 *	 * XXX:	 * We ignore errors from the sync -- it makes no sense to return an	 * error to the calling process, so set a flag causing the checkpoint	 * to be retried later.	 */	if (F_ISSET(bhp, BH_WRITE)) {		if (mfp->lsn_cnt == 1) {			UNLOCKREGION(dbmp);			syncfail = __db_fsync(dbmfp->fd) != 0;			LOCKREGION(dbmp);			if (syncfail)				F_SET(mp, MP_LSN_RETRY);		}		F_CLR(bhp, BH_WRITE);		/*		 * If the buffer just written has a larger LSN than the current		 * max LSN written for this checkpoint, update the saved value.		 */		if (log_compare(&lsn, &mp->lsn) > 0)			mp->lsn = lsn;		--mp->lsn_cnt;		--mfp->lsn_cnt;	}	/* Update the page clean/dirty statistics. */	++mp->stat.st_page_clean;	--mp->stat.st_page_dirty;	/* Update I/O statistics. */	++mp->stat.st_page_out;	++mfp->stat.st_page_out;	return (0);syserr:	__db_err(dbenv, "%s: %s failed for page %lu",	    __memp_fn(dbmfp), fail, (u_long)bhp->pgno);err:	/* Unlock the buffer and reacquire the region lock. */	UNLOCKBUFFER(dbmp, bhp);	LOCKREGION(dbmp);	/*	 * Clean up the flags based on a failure.	 *	 * The page remains dirty but we remove our lock.  If we rewrote the	 * page, it will need processing by the pgin routine before reuse.	 */	if (callpgin)		F_SET(bhp, BH_CALLPGIN);	F_CLR(bhp, BH_LOCKED);	return (ret);}