/*static char *SCCSID = "@(#)tables.h   6.4 92/02/27";*/
/*
 **     OFT - Open File Table
 *
 *      HISTORY
 *          25-Aug-89 by JR (John Rogers, JohnRo@Microsoft)
 *              - Converted HPFS from OS/2 1.2 to run with OS/2 2.0 (really
 *                changed comment style to not use slash-slash, as it generates
 *                too many warnings under MSC 5.2 with /W3 switch).
 *          14-Sep-1988 13:26 by Leif Pederson [leifp] resynch w/Gordon
 *          8-Nov-1988 by Thomas Fenwick [thomasf] pick up volume changes
 */


/*
 *      The OFT contains file specific information which is independent
 *      of an instance of use of the file.
 *
 *      If the file is open for write access, we keep a pointer to
 *      it's directory entry, not just it's
 *      FNODE, so that we can update the length and modification time when it's
 *      written.
 *
 *      We store the directory's FNODE number and the file name, with these
 *      we can find the directory entry again even if the directory has
 *      been shuffled by creates or deletes of other files.  Two advisories
 *      are kept - the Vsector number, cache block address, and cache block
 *      offset of the actual directory entry.  This information has three
 *      levels of validity:
 *
 *              1) Vsector, header address, and offset are valid
 *                      you can find the dir entry easily
 *              2) the header address is invalid due to cache flushing.
 *                      Vsector # and offset are still valid, so read the
 *                      cache block and go directly to the entry
 *                      In this case the header address points to the wrong
 *                      Vsector
 *              3) the directory has been altered since we opened the file,
 *                      so none of this info is accurate.  In this case the
 *                      directory alteration routines located this OFT
 *                      entry and zeroed the Vsector number.  Go to the directory
 *                      and search the name again.
 */

union LASTRUN {
        PALLEAF pallLastRun;    /* pointer to last storage for file */
        SECPTR scpLastRun;      /* sector of last leaf */
};

typedef union LASTRUN LRP;
typedef LRP far *PLRP;

typedef struct OFT { /* OFT */
        DCHN dcpOFTList;        /* OFT_P   double chain of OFT structures, *
                                 *  rooted in OFTHead[i]                   */
          /* not needed */      /* OFT_FHT double chain of FHTs used for   *
                                 *  sharing only                           */
          /* not needed */      /* OFT_RLCK double chain of RECLOCKs used  *
                                 *  for record locking only                */
        SECPTR scpFNode;        /* OFT_FN  pointer to file FNODE           */
        PSUBDIR psbdDir;        /* OFT_SBD pointer to SBDIR structure      */
        SECPTR scpDirBlk;       /* OFT_DIRE pointer to directory block     */
        USHORT  flDMask;                /* OFT_DMASK value to 'OR' into buf.flDMask */
        ULONG culChange;        /* OFT_CCNT value from dirblk for          *
                                 *  scpDirBlk to check offusDirEnt         *
                                 *  validity                               */
        ULONG culFreeDB;        /* OFT_FREEDCNT  value from subdir struct  *
                                 *  for scpDirBlk to be valid              */
        /*
         * These length fields are used when writing the file.
         * The FILESTORAGE entries reflect the ulFAllocLen value.  These
         * aren't updated in the FNODE until the file closes, whereas
         * they are trimmed back to ulFActualLen length which is itself
         * propagated to the file's DIR entry.  If write-through is set
         * then the entries below will be propagated to the FNODE and
         * then to the disk, but if we crash the cleanup program
         * will deallocate the "extra" sectors.
         */

        ULONG ulFActualLen;     /* OFT_LEN   file actual length            */
        ULONG ulFAllocLen;      /* OFT_ALEN  file allocated length         *
                                                 * (SECSIZE multiple)                      */
        LSN lsnLast;            /* OFT_LAST  Psector # of last sector in   *
                                                         *  file, or 0                             */
        LRP LastRun;            /* OFT_LRP   union of PALLEAF/SECPTR - for *
                                 *  last leaf in in file                   */
                                /*  Last run pointer.  Valid if lsnLast!=0.*
                                 *                                         *
                                 *  If (alb.bFlag & AFB_NODE != 0) in fst, *
                                 *      (was alb.ab_flag in 386)           *
                                 *      this is the address of an ALLEAF   *
                                 *      record in the aall field of this   *
                                 *      OFT entry;                         *
                                 *  else                                   *
                                 *      this is a SECPTR that points to    *
                                 *      the last ALSEC containing the last *
                                 *      run record.                        */
        PVOLTAB pVolume;        /* OFT_VOL  ptr to VOLTAB for this file    */
          /* not needed */      /* OFT_NAME ptr to name (we keep name at   *
                                 *  end of OFT)                            */
        USHORT offusDirEnt;     /* OFT_DIRO  offset into directory block   *
                                 *  for entry                              */
          /* not needed */      /* OFT_FILL unused filler                  */
          /* not needed */      /* OFT_LCKCNT count of guys in OFT_RLCK    */
        USHORT cusClientFHTs;   /* OFT_??? # of client FHTs                *
                                 *  MASM uses OFT_RD, OFT_WT, OFT_FIND     */
        USHORT cWaits;          /* OFT_WCNT     number of people waiting   *
                                 *  the following three fields are used to *
                                 *  control access.  They're identical in  *
                                 *  use to the equivalent fields in SBDIR  */
        USHORT cusHolds;        /* OFT_HCNT hold count                     */
          /* not needed */      /* OFT_DMY unused, must be 0               *
                                 * if this byte is ever used, move bMFlag  *
                                 * to the end of this structure            */
        BYTE bMFlag;            /* OFT_??? - PIA does not have this field  *
                                 *  Misc PIC-only flags (see OFM_, below)  */
        BYTE bFlag;             /* OFT_FLAG flag byte                      */
        PVOID pWaitChain;       /* OFT_WAITC head of wait chain if locked  */
                                /* OFT_OPLOCK Oplock value, 0 if none      */
        PBANDTAB pbtLastAlloc;  /* OFT_BANDP pointer to BANDTAB structure  *
                                 *  in BandList for our last allocation.   *
                                 *  =0 if unused                           */
          /* not needed */      /* OFT_RD # of opens for write             */
          /* not needed */      /* OFT_WT # of opens for write             */
          /* not needed */      /* OFT_DR # of opens with deny read        */
          /* not needed */      /* OFT_DW # of opens with deny write       */
          /* not needed */      /* OFT_COMPAT # of opens for compatibility *
                                 *  mode                                   */
          /* not needed */      /* OFT_FIND # of active FINDs using OFT    */
        BYTE bCorrupt;          /* OFT_Fxxxxx   non-zero if file is        *
                                 *  unusable due to corrupt disk           */
        BYTE bSFlag;            /* OFT_SFLAG special byte flag             */
          /* not needed */      /* OFT_DMY2 unused                         */

        USHORT cWriDir;         // @128641 Count of write directs in progress.
                                // Read aheads will be disabled if this is
                                // not zero.
        /*
         *      The file storage information from the fnode is replicated
         *      in the OFT.  This saves us from having to blow a cache block
         *      keeping the FNODE in RAM for every open file.  The FNODE
         *      is only accessed when a file is open, and when it's closed.
         *      (If write-through is set, it's accessed for every growth)
         */
        FILESTORAGE fst;        /* OFT_AB duplicate of what's in fnode     */
#ifdef PERFVIEW
        USHORT cWrite;          /* Count of writers                        */
#endif
        BYTE iCPVol;            /* index for code page (in volume table    *
                                 * array                                   */
        BYTE cchName;           /* OFT_??? length of name, real name       *
                                 *  follows OFT (see OFT_NAME)             */

} OFT;  /* OFT */

typedef OFT far *POFT;

/* flag bits for bFlag (OFT_FLAG) */

#define OTF_LCK  0x01           /* directory is locked against access */
#define OTF_PLK  0x02           /* pending lock */
#define OTF_PSO  0x04           /* pending solo */
#define OTF_PND  0x80           /* lock pending bit */

/* flag bits for bSFlag (OFT_SFLAG) */

#if 0
    #define OFS_OPLCK 0x01         /* oplocked */
    #define OFS_OPBA 0x02          /* oplock BATCH flag set */
#endif

#define OFS_DASD 0x04           /* DASD (really DirectAccess) file */
#ifdef DEBUG
#define OFS_SAC 0x10            /* supress OFT_ALEN debug check */
#endif
#define OFS_SECTORIO  0x08      /* DASD with Sector I/O              */
#define OFS_ONLYSECIO 0x20      /* Big disk DASD-Only allow sectorio */

/* flag bits for bMFlag (OFT_??) */
#define OFM_Written    0x01     /* file has been written to since last  *
                                 * commit/close or Last Modification    *
                                 * time was changed (DosSetFileInfo)    */
#define OFM_Read       0x02     /* file has been read to since last     *
                                 * commit/close or Last Access          *
                                 * time was changed (DosSetFileInfo)    */
#ifdef RAHEAD
#define OFM_Cache      0x04     /* file has been cached                 */
#endif
#define OFM_FInfo_Lev1 0x08     /* User has called the DosSetFileInfo   *
                                 * API to change the file's Level 1     *
                                 * information since the last           *
                                 * commit/close. This flag should be    *
                                 * used by commit/close as a check for  *
                                 * whether Last Mod/Last Access should  *
                                 * be overwritten with time_now().      */


/*
 **     FHT - File Handle Table
 *
 *      The FHT contains per-handle informatiuon
 */

typedef struct FHT { /* FHT */
        ULONG offSeek;          /* FHT_SEEK  seek pointer               */
                                /*  NOTE: This is PIOH for Pager Files  */
        POFT  poft;             /* FHT_OFT   pointer to OFT             */
          /* not needed */      /* FHT_CHN   chain of FHTs for an OFT   */
          /* not needed */      /* FHT_UID   UID and Session ID         */
        USHORT usMode;          /* FHT_MODE  mode bits from open        */
        USHORT usMode2;         /* FHT_MODE2 extended mode bits */
        USHORT usRdAheadAdv;    /* FHT_RAA   read ahead advisory        */
#ifdef RAHEAD
        BYTE  bRAFlags;         /* See RAHEAD.H                         */
        BYTE  bRAReads;         /* 'Avg' # of last seq reads            */
        BYTE  bRABigReads;      /* 'Avg' # of last seq big seq reads    */
        ULONG ulBufRun;         /* # of sectors read by last RA request */
        ULONG ulNextRA;
#endif
        BYTE bHint;             /* FHT_HINT  hint flags                 *
                                 *    note: FHT_HINT is a USHORT in PIA */
        BYTE bFlush;            /* FHT_FLUSH OPEN_WRITE_THROUGH/256 if  *
                                 *           a BufReset or writethu seen*/
                                /* FHT_UNUSED not needed in PIC         */
} FHT;  /* FHT */

typedef FHT far *PFHT;


/*
 **     FHT_HINT flags
 */

#define FHH_SEQ         0x01      /* sequential file                 */
#ifdef PERFVIEW
#define FHH_READ        0x02      /* file has been only read         */
#define FHH_READSEQ     0x04      /* file read strictly sequentially */
#define FHH_WRITE       0x08      /* File is being written to        */
#endif
