/*static char *SCCSID = "@(#)freedb.c	6.2 92/01/31";*/
#define ASWAP1 ASWAP1
#include <os2.h>
#include "api.h"
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "fnode.h"
#include "volume.h"
#include "tables.h"
#include "pb_ifs.h"
#include "superb.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"

#include "pr_BITMP.h"
#include "pr_CACHE.h"
#include "pr_MISC.h"


/*
 ***	FreeDB - Free Directory Block
 *
 *	FreeDB is called to release a directory block's allocation.
 *
 *	If the DIRBLK is in the special DIRBLK area we set the proper
 *	bit in the DIRBLK map, else we set the two bits in the
 *	regular map.
 *
 *	ENTRY	lsnFirstToFree (ebx) = number of first bit/sector to free
 *	EXIT	none
 *	USES	all but ESI
 *
 *	HISTORY
 *	    24-Oct-1988 02:30 by Bill McJohn [t-billm]
 *				Translated from 10/21/88 assembly code
 */
void
FreeDB (lsnFirstToFree,pfrm)
LSN lsnFirstToFree;
PFRAME pfrm;
{
	PBUFNODE pbufMap;	/*  ptr to buffer header for DIRBLK map */
	PBYTE pb;		/*  bitmap byte for lsnFirstToFree	*/
	USHORT offus;		/*  DIRBLK offset into DIRBLK map	*/

	PBANDTAB pbtbVol;

	pbtbVol = &(pfrm->pvol->bndDirBand);
	if ((lsnFirstToFree >= pbtbVol->lsnBase) &&
	    (lsnFirstToFree < pbtbVol->lsnBase + pfrm->pvol->csecDirBlkBand)) {

	    /*	The DIRBLK to be freed is in the special DIRBLK band.
	     *	Just clear one bit.
	     */

	    offus = (USHORT)( lsnFirstToFree - pbtbVol->lsnBase ) /
				(DIRBLKS/SECSIZE);

                                                                   //#85759
	    if ((pb = (PBYTE)LSDBM(&(pbtbVol->scpMap),BP_KEEP,&pbufMap,pfrm)) == NULL)
         return;

	    pb += offus/8;

	    #ifdef DEBUG
		if ( ( (USHORT)(*pb) & (USHORT)(1 << offus % 8) ) != 0 ) {

		    /*	The bit is already marked as free!  */
		    INTERR ("FreeDB:  DIRBLK bit already marked free");
		}
	    #endif

	    *pb |= (1 << offus % 8);

	    pbtbVol->csecFree += 1;
	    SetDirt(pb, pbufMap, FALSE, pfrm);

	} else {

	    /*
	     *	The sectors are not in the special DIRBLK band;
	     *	free them in the usual fashion.
	     */
	    SetBit (lsnFirstToFree, (ULONG)(DIRBLKS/SECSIZE), pfrm);
	}
}
