/*static char *SCCSID = "@(#)fs_comit.c 6.3 92/01/31";*/
#define _BTXT _BTXT

#define INCL_DOSERRORS
#include <os2.h>
#include <fsh.h>
#include "heap.h"
#include "filemode.h"
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "volume.h"
#include "tables.h"
#include "pb_ifs.h"
#include "pbmacros.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "api.h"
#include "log.h"
#include "assert.h"
#include "notify.h"
#include "shutdown.h"
#include "pr_fsd.h"
#include "pr_debug.h"
#include "pr_HEAP.h"
#include "pr_misc.h"
#include "pr_cache.h"
#include "pr_fssub.h"
#include "pr_dir.h"
#include "pr_fcn.h"


/*
 ***    FS_COMMIT - Flush requesting process's cache buffers to disk.
 *
 *      This routine is called for the final close of an open file.  We call
 *      the file system to close the file.  The new modification time for
 *      the file will be taken from the sfsfi structure.
 *
 *      Entry   type = what type of a commit operation this is:
 *                 FS_COMMIT_ONE (1) - commit for a single file
 *                 FS_COMMIT_ALL (2) - commit for all files (for this process)
 *                                                      <from DosBufReset (-1)>
 *                 (We are called once for each handle!)
 *              IOFlag = information about the operation on the handle:
 *                       (0x0010 = write-through; 0x0020 = no-cache)
 *              psffsi  = pointer to file system independant param block
 *              psffsd  = pointer to file system dependant param block
 *
 *      Returns  error code (NO_ERROR for success)
 *
 *      HISTORY
 *          25-Feb-1990 by JR (John Rogers, JohnRo@Microsoft)
 *              - PTR B788262: fix FS_DoPageIO probs (e.g. nested swap).
 *          19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *              - Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 *          26-May-1989 by JR (John Rogers, JohnRo@Microsoft)
 *              - DCR 259.2: added counting of write threads for shutdown.
 *              - DCR 259.2: changed names of macros in "frame.h".
 *          21-Apr-1989 18:34:44 by Jon Parati [jonpa] Rewrote curr. PIA Commit
 *          08-Feb-1989 09:43:13 by MarkH  added call to Commit
 *          17-Nov-1988 19:22:51 by Jon Parati [jonpa]  added new dcr 165 param
 *          07-Oct-1988 17:04:55 by Jon Parati [jonpa]  translated from ASM
 */

int far pascal
FS_COMMIT (USHORT type,
           USHORT IOflag,
           struct sffsi far *psffsi,
           struct sffsd far *psffsd)
{
#ifdef MINIFSD
    /* mini-fsd shouldn't do anything for commit */
    return NO_ERROR;

    /* to prevent W3 warnings */
    psffsi; psffsd; type; IOflag;

#else   /* MINIFSD */
    SHUTDOWN_LOCAL_VARS;
    POFT poft;
    FRAME frm;
    int RetCode = NO_ERROR;

    frm.usHardErr = NO_ERROR;
    frm.fRecheckAddr = TRUE;
    frm.fFlag = 0;               // Clear Frame flag  @132506

    /* Don't care if type == FS_COMMIT_ALL because we get called once for
     * each SFT anyway.
     */

    /* Help keep track of write threads for shutdown purposes. */
    INCR_WRITE_THREADS;

    /* multiplex the poft for quick fix of pfht */

    { PFHT pfht;

        poft = (pfht = ((PPB_SFD)psffsd->sfd_work)->pfht)->poft;

        pfht->bFlush |= HIBYTE( OPEN_WRITE_THROUGH );
    }

    ASSERT_OFT( poft );

    /* file is corrupt, return code */
    if (poft->bCorrupt != 0) {
#ifdef DEBUG
        dprintf ("FS_COMMIT: poft->bCorrupt is non-zero\n");
#endif
        DECR_WRITE_THREADS;
        RetCode = FS_GetHardErr(ERROR_READ_FAULT);
        return RetCode;
    }

    frm.pvol = poft->pVolume;     /* setup pvol for lower level routines */

    if ((poft->bSFlag & OFS_DASD) == 0) {

        /*
         *  Not the result of a DASD open--i.e. a normal file OFT.
         *  Update the time and date fields, flush the buffers,
         *  and notify that this file has been committed.
         */

#ifndef MINIFSD
        if (fShuttingDown) {  /* are we shutting down? */

           /* release extra allocation   */

           if (ReleaseExtraAlloc(poft, &frm)) {
              /* if that didn't work... */

              poft->bCorrupt = 1;            /* mark the file no good.    */
              DECR_WRITE_THREADS;
              return OFTCorrupt(poft,&frm);  /* mark OFT as corrupt       */
           }

        }
#endif
        LOCKSWAP(&swapASWAP1);
                                                      //#83299
        UpdateDisk(poft,TRUE,&frm);
        UNLOCKSWAP(&swapASWAP1);

        SelFlush(poft->flDMask, &frm);


        { PSUBDIR psbd = poft->psbdDir;
          PDIRENT pde;
     PBUFNODE pbuf;

            if (psbd->dcpNotifyChain.pFwd) {
                /*
                 * There are folks who want notification on this directory.
                 * See if they're interested in our file name
                 */
                pde = RDE (poft, &pbuf, &frm);

                /* unhold subdir */
                UnHoldDir_( psbd );

                NotifyScan( psbd->dcpNotifyChain.pFwd, pde, &frm);
            }
        }
    } else {

        /*
         *  This poft is the result of a DASD open.
         *  Just flush the appropriate buffers.
         */

        SelFlush(poft->flDMask, &frm);

    }

#ifdef DEBUG
    VBS ();
#endif

    /* Indicate completion of this write thread. */
    DECR_WRITE_THREADS;

    psffsi->sfi_tstamp = 0;
    return NO_ERROR;

    /* to prevent W3 warnings */
    psffsi; psffsd; type; IOflag;
#endif
}
