/*static char *SCCSID = "@(#)flushvol.c	6.2 92/01/31";*/
#define BSWAP1 BSWAP1

#include <os2def.h>
#include <bse.h>
#include <fsh.h>
#include "api.h"
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "volume.h"
#include "pbmacros.h"
#include "tables.h"
#include "pb_ifs.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "pr_CACHE.h"
#include "pr_MISC.h"
#include "pr_FCN.h"
#include "pr_DEBUG.h"

/*
 ***	FlushVol - flush all specified volume's cache to disk.
 *
 *	FlushVol is used to assure that we have no dirty buffers for a
 *	specific volume.  It is also used to clear the cache of buffers
 *	for a specific volume - the volume is going away (unmount).
 *
 *	ENTRY	fDiscard - TRUE iff to discard cache data
 *
 *	EXIT	None
 *
 *	HISTORY
 *	    07-Oct-1988 17:07:24 by Jon Parati [jonpa]	brought upd w/ 6-26 asm
 */

void
FlushVol (PVOLTAB pvol,			/* pointer to volume table entry */
	  BOOL	  fDiscardCache,	/* flag if we are to discard buffers */
	  PFRAME  pfrm)
{
    USHORT	us;
    PBUFNODE	pbuf;
    BOOL	fChecked;

    ULONG VolBits = pvol->ulVolBits;

    for (us = 0, pbuf = abufCache; us < cBufs; us++, pbuf++) {

	fChecked = FALSE;

//#114986
	while( (VolBits == (pbuf->lsnSec & ~SECMASK)) && !fChecked &&
          (!(pbuf->fFlag & BFL_LWLOCK)) ) {

	    /*
	     *	This buffer has data from the volume we are flushing,
	     *	so we have to deal with it somehow.
	     */
	    if( pbuf->cLocked ) {

		WBU( pbuf,pfrm );

	    } else if( pbuf->cusHolds != 0 ) {

		LowPriYield();

	    } else if (pbuf->dcbpDirt.pbufFwd != NULL) {

		/*
		 *  It's on the dirty chain.  Take it
		 *  off, and write it if necessary.
		 */

      if (pbuf->fFlag & BFL_LWLOCK) {
		  fChecked = TRUE;
        continue;
      }

//#114986. Not needed since BufWrit can also do the DBCREM
//		DBCREM (pbuf);

		if (pbuf->bDirtMask) {
		  BufWrit(pbuf,pfrm);
		}

	    } else {

		/*
		 *  The buffer is neither locked nor held,
		 *  and it's not on the dirty chain.  We can
		 *  do whatever we like to it.
		 */

		fChecked = TRUE;

		if (fDiscardCache) {
		    pbuf->lsnSec = LSN_BOGUS;
		}
	    }

	} /* while */
    } /* for (us...) */

#ifdef DEBUG
    VBS ();
#endif
}
