diff options
Diffstat (limited to 'roms/edk2/FatPkg/EnhancedFatDxe/DirectoryCache.c')
-rw-r--r-- | roms/edk2/FatPkg/EnhancedFatDxe/DirectoryCache.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/roms/edk2/FatPkg/EnhancedFatDxe/DirectoryCache.c b/roms/edk2/FatPkg/EnhancedFatDxe/DirectoryCache.c new file mode 100644 index 000000000..2333016d1 --- /dev/null +++ b/roms/edk2/FatPkg/EnhancedFatDxe/DirectoryCache.c @@ -0,0 +1,184 @@ +/** @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--;
+ }
+}
|