/*static char *SCCSID = "@(#)fnode.h	6.1 90/11/18";*/
/*static char *SCCSID = "@(#)fnode.h	13.3 90/01/30";*/
/*
 *	FNODE.h - definition for fnode structure and associated structs and
 *		constants.
 *
 *	HISTORY
 *	    Wed Sep 14 14:11:18 1988 by Jon Parati [jonpa] resynch w/Gordon
 *      @d01 73790 93SEP03 gy <V4FORMAT changes to support HPFS386 extensions.
 *                            <GHASSAN @ AUSVM1
 */

/** PERMISSION structure definition
 */

typedef struct PERMISSION { /* PERMISSION*/
	ULONG ulID;		/*   permission ID value */
	PERMMASK pmMask;	/*   permission mask */
} PERMISSION;

typedef PERMISSION far *PPERMISSION;

#ifdef  V4FORMAT                /* @d01 */
/** DASD Limits structure within the FNODE. **/
struct DLREC {
    unsigned long DR_MAX;    /* DASD limit in sectors         */
    unsigned long DR_USE;    /* size of tree in sectors       */
};   /* DLREC */
#endif

/**	File Allocation Tracking
 *
 *	File space is allocated as a list of extents, each extent as
 *	large as we can make it.  This list is kept in a B+TREE format.
 *	Each B+TREE block consists of a single sector containing an
 *	ALSEC record, except for the top most block.  The topmost block
 *	consists of just an ALBLK structure, is usually much smaller than
 *	512 bytes, and is typically included in another structure.
 *
 *	The leaf block(s) in the tree contain triples which indicate
 *	the logical to physical mapping for this file.	Typically this
 *	extent list is small enough that it is wholy contained in the
 *	fnode ALBLK stucture.  If more than ALCNT extents are required
 *	then the tree is split into two levels.  Note that when the
 *	topmost B+TREE block is 'split' no actual split is necessary,
 *	since the new child block is much bigger than the parent block
 *	and can contain all of the old records plus the new one.  Thus,
 *	we can have B+TREEs where the root block contains only one
 *	downpointer.
 *
 *	The following rules apply:
 *
 *	1) if the file is not empty, there is at least one sector allocated
 *	   to logical offset 0.  This simplifys some critical loops.
 *
 *	2) The last entry in the last node block contains a AN_LOF value of
 *	   FFFFFFFF.  This allows us to extend that last leaf block
 *	   without having to update the node block.
 *
 *	3) For the node records, the AN_SEC points to a node or leaf
 *	   sector which describes extents which occur before that
 *	   record's AN_LOF value.
 */


/*	AuxInfo Structure
 *
 *	The FNODE contains two AuxInfo structures, one for ACLs and
 *	one for EAs.
 *
 *	These structures point to within FNODE storage and also
 *	potentially point to an overflow area which is an ALBLK structure.
 */

typedef struct AUXINFO { /* AUXINFO */
	SPTR sp;	/* AI_DAL	non-fnode Disk Allocation length */
			/* AI_SEC 	lsn of 1st sec in extent or of ALSEC */
	USHORT usFNL;	/* AI_FNL 	length of fnode info */
	BYTE bDat;	/* AI_DAT 	non-zero if AI_SEC points to ALSEC */
} AUXINFO;

typedef AUXINFO far *PAUXINFO;


/**	Fnode block definition
 *
 *	Every file and directory has an FNODE.	The file location
 *	stuff is only used for files; directories are kept in
 *	a BTREE of DIRBLK records pointed to by fst.alf [0].lsnPhys (we think).
 */

#define FNODENAMELEN	16
#define UIDSIZE		16

typedef struct FNODE { /* FNODE*/

    /*	The following file location information is copied into the OFT
     *	and is used there during normal file access.  The stuff in the
     *	fnode record here may in fact be out of date for open files.
     *	See the OFN_ in the OFT structure THESE TWO AREAS IN THE
     *	RESPECTIVE RECORDS MUST HAVE IDENTICAL FORMATS.
     *
     *	There are two kinds of location info: FNSCNT SPTR records
     *	and then a single, double, triple, and quad indirect block pointer.
     *	The "block threshold" means the first sector number which is
     *	contained in that indirect block heirarchy.  You use this
     *	to quickly find out where to start looking.
     */

    SIGNATURE sig;		/* FN_SIG	signature value */

    /*	History tracking info for softer software */

    ULONG ulSRHist;		/* FN_SRH	sequential read history */
    ULONG ulFRHist;		/* FN_FRH	fast read history */
    CHAR achName [FNODENAMELEN]; /* FN_NAME      first bytes of file name.
						The first byte of this array
						is the DIR_NAML from a DIRENT.
						The remaining bytes are from
						the DIR_NAMA field.  If
						FN_NAME [0] <= 15, the entire
						name follows.  This info is
						for chkdsk; format should set
						up the root name as "." */

    LSN lsnContDir;		/* FN_CONTFN	fnode of dir containing
						this file/dir */
    /*	stuff not interesting once opened */

    AUXINFO aiACL;		/* FN_ACL	access ctl list aux info */
    BYTE cHistBits;		/* FN_HCNT	count of valid history bits */

    AUXINFO aiEA;		/* FN_EA	ea aux info structure */
    BYTE bFlag;			/* FN_FLAG	FNODE flag byte */

    FILESTORAGE fst;		/* file storage
				 *   (contains
				 *    FN_AB
				 *    FN_ALREC
				 *    FN_VLEN)
				 */

    ULONG ulRefCount;		/* FN_xxx	number of "need" EAs in file */

    /*
     * The following fields are unused in this release; they're for future
     * compatibility.  When deleting files, if FN_EEL is non-zero then FN_EEL
     * sectors starting at FN_EEP must be released too.
     */
    CHAR achUID [UIDSIZE];	/* FN_UID	reserved for UID value */
    USHORT usACLBase;		/* FN_ACLBASE	offset of 1st ACE in fnode */

#ifdef  V4FORMAT           /* @d01 */
    /* The abReserved field will be used by HPFS386 for enhancements to
     * DASD Limits.
     */
    BYTE abReserved [10-sizeof(struct DLREC)];   /* Reserved for PIA */
    struct  DLREC FN_DASD;                       /* DASD record      */
#else
    BYTE abSpare [10];		/* FN_SPARE	10 more bytes emergency spares */
#endif

    /* Free pool.  ACLs and EAs are stored here via the AUXINFO structure */

    BYTE abFree [SECSIZE-66-(2*sizeof (AUXINFO))-sizeof (FILESTORAGE)];

} FNODE;

typedef FNODE far * PFNODE;

#define FNF_DIR 0x01		/* is a directory fnode */
