https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			185 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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--;
 | |
|   }
 | |
| }
 |