/** @file
  Functions for directory cache operation.

Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Fat.h"

/**

  Free the directory structure and release the memory.

  @param  ODir                  - The directory to be freed.

**/
STATIC
VOID
FatFreeODir (
  IN FAT_ODIR  *ODir
  )
{
  FAT_DIRENT  *DirEnt;

  //
  // Release Directory Entry Nodes
  //
  while (!IsListEmpty (&ODir->ChildList)) {
    DirEnt = DIRENT_FROM_LINK (ODir->ChildList.ForwardLink);
    RemoveEntryList (&DirEnt->Link);
    //
    // Make sure the OFile has been closed
    //
    ASSERT (DirEnt->OFile == NULL);
    FatFreeDirEnt (DirEnt);
  }

  FreePool (ODir);
}

/**

  Allocate the directory structure.

  @param  OFile                   - The corresponding OFile.

**/
STATIC
FAT_ODIR *
FatAllocateODir (
  IN FAT_OFILE  *OFile
  )
{
  FAT_ODIR  *ODir;

  ODir = AllocateZeroPool (sizeof (FAT_ODIR));
  if (ODir != NULL) {
    //
    // Initialize the directory entry list
    //
    ODir->Signature = FAT_ODIR_SIGNATURE;
    InitializeListHead (&ODir->ChildList);
    ODir->CurrentCursor = &ODir->ChildList;
  }

  return ODir;
}

/**

  Discard the directory structure when an OFile will be freed.
  Volume will cache this directory if the OFile does not represent a deleted file.

  @param  OFile                 - The OFile whose directory structure is to be discarded.

**/
VOID
FatDiscardODir (
  IN FAT_OFILE  *OFile
  )
{
  FAT_ODIR    *ODir;
  FAT_VOLUME  *Volume;

  Volume = OFile->Volume;
  ODir   = OFile->ODir;
  if (!OFile->DirEnt->Invalid) {
    //
    // If OFile does not represent a deleted file, then we will cache the directory
    // We use OFile's first cluster as the directory's tag
    //
    ODir->DirCacheTag = OFile->FileCluster;
    InsertHeadList (&Volume->DirCacheList, &ODir->DirCacheLink);
    if (Volume->DirCacheCount == FAT_MAX_DIR_CACHE_COUNT) {
      //
      // Replace the least recent used directory
      //
      ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);
      RemoveEntryList (&ODir->DirCacheLink);
    } else {
      //
      // No need to find a replace
      //
      Volume->DirCacheCount++;
      ODir = NULL;
    }
  }

  //
  // Release ODir Structure
  //
  if (ODir != NULL) {
    FatFreeODir (ODir);
  }
}

/**


  Request the directory structure when an OFile is newly generated.
  If the directory structure is cached by volume, then just return this directory;
  Otherwise, allocate a new one for OFile.

  @param  OFile                 - The OFile which requests directory structure.

**/
VOID
FatRequestODir (
  IN FAT_OFILE  *OFile
  )
{
  UINTN       DirCacheTag;
  FAT_VOLUME  *Volume;
  FAT_ODIR    *ODir;
  FAT_ODIR    *CurrentODir;
  LIST_ENTRY  *CurrentODirLink;

  Volume      = OFile->Volume;
  ODir        = NULL;
  DirCacheTag = OFile->FileCluster;
  for (CurrentODirLink  = Volume->DirCacheList.ForwardLink;
       CurrentODirLink != &Volume->DirCacheList;
       CurrentODirLink  = CurrentODirLink->ForwardLink
       )
  {
    CurrentODir = ODIR_FROM_DIRCACHELINK (CurrentODirLink);
    if (CurrentODir->DirCacheTag == DirCacheTag) {
      RemoveEntryList (&CurrentODir->DirCacheLink);
      Volume->DirCacheCount--;
      ODir = CurrentODir;
      break;
    }
  }

  if (ODir == NULL) {
    //
    // This directory is not cached, then allocate a new one
    //
    ODir = FatAllocateODir (OFile);
  }

  OFile->ODir = ODir;
}

/**

  Clean up all the cached directory structures when the volume is going to be abandoned.

  @param  Volume                - FAT file system volume.

**/
VOID
FatCleanupODirCache (
  IN FAT_VOLUME  *Volume
  )
{
  FAT_ODIR  *ODir;

  while (Volume->DirCacheCount > 0) {
    ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);
    RemoveEntryList (&ODir->DirCacheLink);
    FatFreeODir (ODir);
    Volume->DirCacheCount--;
  }
}
