/*static char *SCCSID = "@(#)selflush.c	6.2 92/01/31";*/
#include <os2def.h>

#include "const.h"
#include "misc.h"
#include "buf.h"

#include "chain.h"
#include "dir.h"

#include "volume.h"
#include "storage.h"
#include "tables.h"

#include "frame.h"
#include "lw.h"
#include "fsdata.h"

#include "pr_cache.h"
#include "pr_debug.h"
#include "pr_misc.h"
/*
 **	SelFlush - Do Selective Flush
 *
 *  SelFlush is called when we're to flush the dirty sectors
 *  belonging to a particular file.  We go down through the
 *  dirty chain writing these guys out.
 *
 *  Note that an optimial algorithm would be to give a list
 *  of these guys to the asynchronous disk driver, but we believe
 *  that we're rare so we'll just skip that for now and call
 *  BufWrite.
 *
 *  SelFlush doesn't interlock things, so if some other thread
 *  is writing to the file we're flushing when we're called then
 *  some stuff might be missed.
 *
 *  Our quick-and-dirty algorithm looks N-squared, since we start
 *  over at the top of the dirty chain each time we write a buffer.
 *  It's not quite so bad.  If there are few eligible guys then
 *  we don't make many passes.  If there are a lot, then each pass
 *  doesn't go very far until we find a guy to write.  Also, the
 *  CPU time is spread out over time because we write a sector between
 *  each pass.
 *
 *	ENTRY	    flMask = mask code for pbuf->flDMask
 *
 *	HISTORY
 *	    19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

void SelFlush(USHORT flMask , PFRAME pfrm)
{
    PBUFNODE pbuf;
    BOOL fDone = FALSE;

    for (;;) {

	/*
	 * BUGBUG - can we move this out of the loop? or
	 * will that cause late arrival dirty buffers to be skipped?
	 */
	pbuf = &bufLWHead;

	/*
	 *   flMask (eax) = mask code
	 *   pbuf   (ebx) = address of guy we're to consider flushing
	 */

	do {

	    if ( (pbuf = pbuf->dcbpDirt.pbufFwd) == &bufLWHead ) { //@76575
		/* done */
         fDone = TRUE;
		   break;
       }

	/* get next if this buf not eligible */
	} while ( (pbuf->fFlag & BFL_LWLOCK) && ((pbuf->flDMask & flMask) == 0) );

   if (fDone)
     break;

	/* remove buffer from dirty chain */
// Not needed since BufWrit can also do the DBCREM. #114986
//	DBCREM (pbuf);

	/* write this guy */
	BufWrit(pbuf,pfrm);

    }

return;

}
