size_t mf_offset; int ar_cnt, cnt, nalloc, next, pincnt, ret, wrote;
int is_tmp;
memp_fsync(dbmfp)	DB_MPOOLFILE *dbmfp;{	BH *bhp, **bharray;	DB_MPOOL *dbmp;	size_t mf_offset;	int ar_cnt, cnt, nalloc, next, pincnt, ret, wrote;	dbmp = dbmfp->dbmp;	/*	 * If this handle doesn't have a file descriptor that's open for	 * writing, or if the file is a temporary, there's no reason to	 * proceed further.	 */	if (F_ISSET(dbmfp, MP_READONLY))		return (0);	ret = 0;	LOCKREGION(dbmp);	if (F_ISSET(dbmfp->mfp, MP_TEMP))		ret = 1;	UNLOCKREGION(dbmp);	if (ret)		return (0);	mf_offset = R_OFFSET(dbmp, dbmfp->mfp);	/*	 * We try and write the buffers in page order so that the underlying	 * filesystem doesn't have to seek and can write contiguous blocks,	 * plus, we don't want to hold the region lock while we write the	 * buffers.  Get memory to hold the buffer pointers.  Get a good-size	 * block, too, because we realloc while holding the region lock if we	 * run out.	 */	nalloc = 1024;	if ((bharray =	    (BH **)__db_malloc((size_t)nalloc * sizeof(BH *))) == NULL)		return (ENOMEM);	LOCKREGION(dbmp);	/*	 * Walk the LRU list of buffer headers, and get a list of buffers to	 * write for this MPOOLFILE.	 */	ar_cnt = pincnt = 0;	for (bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);	    bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {		if (!F_ISSET(bhp, BH_DIRTY) || bhp->mf_offset != mf_offset)			continue;		if (bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED)) {			++pincnt;			continue;		}		if (ar_cnt == nalloc) {			nalloc *= 2;			if ((bharray = (BH **)__db_realloc(bharray,			    nalloc * sizeof(BH *))) == NULL) {				ret = ENOMEM;				goto err;			}		}		bharray[ar_cnt++] = bhp;	}	/* Lock down the buffers and their contents. */	for (cnt = 0; cnt < ar_cnt; ++cnt)		++bharray[cnt]->ref;	UNLOCKREGION(dbmp);	/* Sort the buffers we're going to write. */	qsort(bharray, ar_cnt, sizeof(BH *), __bhcmp);	LOCKREGION(dbmp);	/* Walk the array, writing buffers. */	for (next = 0; next < ar_cnt; ++next) {		/*		 * It's possible for a thread to have gotten the buffer since		 * we listed it for writing.  If the reference count is still		 * 1, we're the only ones using the buffer, go ahead and write.		 * If it's >1, then skip the buffer and assume that it will be		 * written when it's returned to the cache.		 */		if (bharray[next]->ref > 1) {			++pincnt;			--bharray[next]->ref;			continue;		}		/* Write the buffer. */		ret = __memp_pgwrite(dbmfp, bharray[next], NULL, &wrote);		/* Release the buffer. */		--bharray[next]->ref;		/* If there's an error, release the rest of the buffers. */		if (ret != 0) {			while (++next < ar_cnt)				--bharray[next]->ref;			goto err;		}		if (!wrote)			++pincnt;	}err:	UNLOCKREGION(dbmp);	__db_free(bharray);	/*	 * Sync the underlying file as the last thing we do, so that the OS	 * has maximal opportunity to flush buffers before we request it.	 *	 * XXX:	 * Don't lock the region around the sync, fsync(2) has no atomicity	 * issues.	 */	if (ret == 0)		return (pincnt == 0 ? __db_fsync(dbmfp->fd) : DB_INCOMPLETE);	return (ret);}