/** @file
  Routines that check references and flush OFiles

Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.


**/

#include "Fat.h"

/**

  Flushes all data associated with the file handle.

  @param  FHand                 - Handle to file to flush.
  @param  Token                 - A pointer to the token associated with the transaction.

  @retval EFI_SUCCESS           - Flushed the file successfully.
  @retval EFI_WRITE_PROTECTED   - The volume is read only.
  @retval EFI_ACCESS_DENIED     - The file is read only.
  @return Others                - Flushing of the file failed.

**/
EFI_STATUS
EFIAPI
FatFlushEx (
  IN EFI_FILE_PROTOCOL  *FHand,
  IN EFI_FILE_IO_TOKEN  *Token
  )
{
  FAT_IFILE   *IFile;
  FAT_OFILE   *OFile;
  FAT_VOLUME  *Volume;
  EFI_STATUS  Status;
  FAT_TASK    *Task;

  IFile   = IFILE_FROM_FHAND (FHand);
  OFile   = IFile->OFile;
  Volume  = OFile->Volume;
  Task    = NULL;

  //
  // If the file has a permanent error, return it
  //
  if (EFI_ERROR (OFile->Error)) {
    return OFile->Error;
  }

  if (Volume->ReadOnly) {
    return EFI_WRITE_PROTECTED;
  }
  //
  // If read only, return error
  //
  if (IFile->ReadOnly) {
    return EFI_ACCESS_DENIED;
  }

  if (Token == NULL) {
    FatWaitNonblockingTask (IFile);
  } else {
    //
    // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
    // But if it calls, the below check can avoid crash.
    //
    if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
      return EFI_UNSUPPORTED;
    }
    Task = FatCreateTask (IFile, Token);
    if (Task == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // Flush the OFile
  //
  FatAcquireLock ();
  Status  = FatOFileFlush (OFile);
  Status  = FatCleanupVolume (OFile->Volume, OFile, Status, Task);
  FatReleaseLock ();

  if (Token != NULL) {
    if (!EFI_ERROR (Status)) {
      Status = FatQueueTask (IFile, Task);
    } else {
      FatDestroyTask (Task);
    }
  }

  return Status;
}

/**

  Flushes all data associated with the file handle.

  @param  FHand                 - Handle to file to flush.

  @retval EFI_SUCCESS           - Flushed the file successfully.
  @retval EFI_WRITE_PROTECTED   - The volume is read only.
  @retval EFI_ACCESS_DENIED     - The file is read only.
  @return Others                - Flushing of the file failed.

**/
EFI_STATUS
EFIAPI
FatFlush (
  IN EFI_FILE_PROTOCOL  *FHand
  )
{
  return FatFlushEx (FHand, NULL);
}

/**

  Flushes & Closes the file handle.

  @param  FHand                 - Handle to the file to delete.

  @retval EFI_SUCCESS           - Closed the file successfully.

**/
EFI_STATUS
EFIAPI
FatClose (
  IN EFI_FILE_PROTOCOL  *FHand
  )
{
  FAT_IFILE   *IFile;
  FAT_OFILE   *OFile;
  FAT_VOLUME  *Volume;

  IFile   = IFILE_FROM_FHAND (FHand);
  OFile   = IFile->OFile;
  Volume  = OFile->Volume;

  //
  // Lock the volume
  //
  FatAcquireLock ();

  //
  // Close the file instance handle
  //
  FatIFileClose (IFile);

  //
  // Done. Unlock the volume
  //
  FatCleanupVolume (Volume, OFile, EFI_SUCCESS, NULL);
  FatReleaseLock ();

  //
  // Close always succeed
  //
  return EFI_SUCCESS;
}

/**

  Close the open file instance.

  @param  IFile                 - Open file instance.

  @retval EFI_SUCCESS           - Closed the file successfully.

**/
EFI_STATUS
FatIFileClose (
  FAT_IFILE           *IFile
  )
{
  FAT_OFILE   *OFile;
  FAT_VOLUME  *Volume;

  OFile   = IFile->OFile;
  Volume  = OFile->Volume;

  ASSERT_VOLUME_LOCKED (Volume);

  FatWaitNonblockingTask (IFile);

  //
  // Remove the IFile struct
  //
  RemoveEntryList (&IFile->Link);

  //
  // Add the OFile to the check reference list
  //
  if (OFile->CheckLink.ForwardLink == NULL) {
    InsertHeadList (&Volume->CheckRef, &OFile->CheckLink);
  }
  //
  // Done. Free the open instance structure
  //
  FreePool (IFile);
  return EFI_SUCCESS;
}

/**

  Flush the data associated with an open file.
  In this implementation, only last Mod/Access time is updated.

  @param  OFile                 - The open file.

  @retval EFI_SUCCESS           - The OFile is flushed successfully.
  @return Others                - An error occurred when flushing this OFile.

**/
EFI_STATUS
FatOFileFlush (
  IN FAT_OFILE    *OFile
  )
{
  EFI_STATUS    Status;
  FAT_OFILE     *Parent;
  FAT_DIRENT    *DirEnt;
  FAT_DATE_TIME FatNow;

  //
  // Flush each entry up the tree while dirty
  //
  do {
    //
    // If the file has a permanant error, then don't write any
    // of its data to the device (may be from different media)
    //
    if (EFI_ERROR (OFile->Error)) {
      return OFile->Error;
    }

    Parent  = OFile->Parent;
    DirEnt  = OFile->DirEnt;
    if (OFile->Dirty) {
      //
      // Update the last modification time
      //
      FatGetCurrentFatTime (&FatNow);
      CopyMem (&DirEnt->Entry.FileLastAccess, &FatNow.Date, sizeof (FAT_DATE));
      if (!OFile->PreserveLastModification) {
        FatGetCurrentFatTime (&DirEnt->Entry.FileModificationTime);
      }

      OFile->PreserveLastModification = FALSE;
      if (OFile->Archive) {
        DirEnt->Entry.Attributes |= FAT_ATTRIBUTE_ARCHIVE;
        OFile->Archive = FALSE;
      }
      //
      // Write the directory entry
      //
      if (Parent != NULL && !DirEnt->Invalid) {
        //
        // Write the OFile's directory entry
        //
        Status = FatStoreDirEnt (Parent, DirEnt);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }

      OFile->Dirty = FALSE;
    }
    //
    // Check the parent
    //
    OFile = Parent;
  } while (OFile != NULL);
  return EFI_SUCCESS;
}

/**

  Check the references of the OFile.
  If the OFile (that is checked) is no longer
  referenced, then it is freed.

  @param  OFile                 - The OFile to be checked.

  @retval TRUE                  - The OFile is not referenced and freed.
  @retval FALSE                 - The OFile is kept.

**/
BOOLEAN
FatCheckOFileRef (
  IN FAT_OFILE   *OFile
  )
{
  //
  // If the OFile is on the check ref list, remove it
  //
  if (OFile->CheckLink.ForwardLink != NULL) {
    RemoveEntryList (&OFile->CheckLink);
    OFile->CheckLink.ForwardLink = NULL;
  }

  FatOFileFlush (OFile);
  //
  // Are there any references to this OFile?
  //
  if (!IsListEmpty (&OFile->Opens) || !IsListEmpty (&OFile->ChildHead)) {
    //
    // The OFile cannot be freed
    //
    return FALSE;
  }
  //
  // Free the Ofile
  //
  FatCloseDirEnt (OFile->DirEnt);
  return TRUE;
}

/**

  Check the references of all open files on the volume.
  Any open file (that is checked) that is no longer
  referenced, is freed - and it's parent open file
  is then referenced checked.

  @param  Volume                - The volume to check the pending open file list.

**/
STATIC
VOID
FatCheckVolumeRef (
  IN FAT_VOLUME   *Volume
  )
{
  FAT_OFILE *OFile;
  FAT_OFILE *Parent;

  //
  // Check all files on the pending check list
  //
  while (!IsListEmpty (&Volume->CheckRef)) {
    //
    // Start with the first file listed
    //
    Parent = OFILE_FROM_CHECKLINK (Volume->CheckRef.ForwardLink);
    //
    // Go up the tree cleaning up any un-referenced OFiles
    //
    while (Parent != NULL) {
      OFile   = Parent;
      Parent  = OFile->Parent;
      if (!FatCheckOFileRef (OFile)) {
        break;
      }
    }
  }
}

/**

  Set error status for a specific OFile, reference checking the volume.
  If volume is already marked as invalid, and all resources are freed
  after reference checking, the file system protocol is uninstalled and
  the volume structure is freed.

  @param  Volume                - the Volume that is to be reference checked and unlocked.
  @param  OFile                 - the OFile whose permanent error code is to be set.
  @param  EfiStatus             - error code to be set.
  @param  Task                    point to task instance.

  @retval EFI_SUCCESS           - Clean up the volume successfully.
  @return Others                - Cleaning up of the volume is failed.

**/
EFI_STATUS
FatCleanupVolume (
  IN FAT_VOLUME       *Volume,
  IN FAT_OFILE        *OFile,
  IN EFI_STATUS       EfiStatus,
  IN FAT_TASK         *Task
  )
{
  EFI_STATUS  Status;
  //
  // Flag the OFile
  //
  if (OFile != NULL) {
    FatSetVolumeError (OFile, EfiStatus);
  }
  //
  // Clean up any dangling OFiles that don't have IFiles
  // we don't check return status here because we want the
  // volume be cleaned up even the volume is invalid.
  //
  FatCheckVolumeRef (Volume);
  if (Volume->Valid) {
    //
    // Update the free hint info. Volume->FreeInfoPos != 0
    // indicates this a FAT32 volume
    //
    if (Volume->FreeInfoValid && Volume->FatDirty && Volume->FreeInfoPos) {
      Status = FatDiskIo (Volume, WriteDisk, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector, Task);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
    //
    // Update that the volume is not dirty
    //
    if (Volume->FatDirty && Volume->FatType != Fat12) {
      Volume->FatDirty  = FALSE;
      Status            = FatAccessVolumeDirty (Volume, WriteFat, &Volume->NotDirtyValue);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
    //
    // Flush all dirty cache entries to disk
    //
    Status = FatVolumeFlushCache (Volume, Task);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  //
  // If the volume is cleared , remove it.
  // The only time volume be invalidated is in DriverBindingStop.
  //
  if (Volume->Root == NULL && !Volume->Valid) {
    //
    // Free the volume structure
    //
    FatFreeVolume (Volume);
  }

  return EfiStatus;
}

/**

  Set the OFile and its child OFile with the error Status

  @param  OFile                 - The OFile whose permanent error code is to be set.
  @param  Status                - Error code to be set.

**/
VOID
FatSetVolumeError (
  IN FAT_OFILE            *OFile,
  IN EFI_STATUS           Status
  )
{
  LIST_ENTRY      *Link;
  FAT_OFILE       *ChildOFile;

  //
  // If this OFile doesn't already have an error, set one
  //
  if (!EFI_ERROR (OFile->Error)) {
    OFile->Error = Status;
  }
  //
  // Set the error on each child OFile
  //
  for (Link = OFile->ChildHead.ForwardLink; Link != &OFile->ChildHead; Link = Link->ForwardLink) {
    ChildOFile = OFILE_FROM_CHILDLINK (Link);
    FatSetVolumeError (ChildOFile, Status);
  }
}
