]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/EnhancedFatDxe/DirectoryCache.c
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / DirectoryCache.c
CommitLineData
cae7420b
DB
1/** @file\r
2 Functions for directory cache operation.\r
b9ec9330 3\r
6163cc98
HT
4Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials are licensed and made available\r
b9ec9330
QH
6under the terms and conditions of the BSD License which accompanies this\r
7distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13\r
cae7420b 14**/\r
b9ec9330 15\r
cae7420b 16#include "Fat.h"\r
b9ec9330 17\r
cae7420b 18/**\r
b9ec9330 19\r
cae7420b 20 Free the directory structure and release the memory.\r
b9ec9330 21\r
cae7420b 22 @param ODir - The directory to be freed.\r
b9ec9330 23\r
cae7420b 24**/\r
b9ec9330
QH
25STATIC\r
26VOID\r
27FatFreeODir (\r
28 IN FAT_ODIR *ODir\r
29 )\r
b9ec9330
QH
30{\r
31 FAT_DIRENT *DirEnt;\r
32\r
33 //\r
34 // Release Directory Entry Nodes\r
35 //\r
36 while (!IsListEmpty (&ODir->ChildList)) {\r
37 DirEnt = DIRENT_FROM_LINK (ODir->ChildList.ForwardLink);\r
38 RemoveEntryList (&DirEnt->Link);\r
39 //\r
40 // Make sure the OFile has been closed\r
41 //\r
42 ASSERT (DirEnt->OFile == NULL);\r
43 FatFreeDirEnt (DirEnt);\r
44 }\r
45\r
46 FreePool (ODir);\r
47}\r
48\r
cae7420b
DB
49/**\r
50\r
51 Allocate the directory structure.\r
52\r
53 @param OFile - The corresponding OFile.\r
54\r
55**/\r
b9ec9330
QH
56STATIC\r
57FAT_ODIR *\r
58FatAllocateODir (\r
59 IN FAT_OFILE *OFile\r
60 )\r
b9ec9330
QH
61{\r
62 FAT_ODIR *ODir;\r
63\r
64 ODir = AllocateZeroPool (sizeof (FAT_ODIR));\r
65 if (ODir != NULL) {\r
66 //\r
67 // Initialize the directory entry list\r
68 //\r
69 ODir->Signature = FAT_ODIR_SIGNATURE;\r
70 InitializeListHead (&ODir->ChildList);\r
71 ODir->CurrentCursor = &ODir->ChildList;\r
72 }\r
73\r
74 return ODir;\r
75}\r
76\r
cae7420b 77/**\r
b9ec9330
QH
78\r
79 Discard the directory structure when an OFile will be freed.\r
80 Volume will cache this directory if the OFile does not represent a deleted file.\r
81\r
cae7420b 82 @param OFile - The OFile whose directory structure is to be discarded.\r
b9ec9330 83\r
cae7420b
DB
84**/\r
85VOID\r
86FatDiscardODir (\r
87 IN FAT_OFILE *OFile\r
88 )\r
b9ec9330
QH
89{\r
90 FAT_ODIR *ODir;\r
91 FAT_VOLUME *Volume;\r
92\r
93 Volume = OFile->Volume;\r
94 ODir = OFile->ODir;\r
95 if (!OFile->DirEnt->Invalid) {\r
96 //\r
97 // If OFile does not represent a deleted file, then we will cache the directory\r
98 // We use OFile's first cluster as the directory's tag\r
99 //\r
100 ODir->DirCacheTag = OFile->FileCluster;\r
101 InsertHeadList (&Volume->DirCacheList, &ODir->DirCacheLink);\r
102 if (Volume->DirCacheCount == FAT_MAX_DIR_CACHE_COUNT) {\r
103 //\r
104 // Replace the least recent used directory\r
105 //\r
106 ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);\r
107 RemoveEntryList (&ODir->DirCacheLink);\r
108 } else {\r
109 //\r
110 // No need to find a replace\r
111 //\r
112 Volume->DirCacheCount++;\r
113 ODir = NULL;\r
114 }\r
115 }\r
116 //\r
117 // Release ODir Structure\r
118 //\r
119 if (ODir != NULL) {\r
120 FatFreeODir (ODir);\r
121 }\r
122}\r
123\r
cae7420b 124/**\r
b9ec9330 125\r
b9ec9330
QH
126\r
127 Request the directory structure when an OFile is newly generated.\r
128 If the directory structure is cached by volume, then just return this directory;\r
129 Otherwise, allocate a new one for OFile.\r
130\r
cae7420b 131 @param OFile - The OFile which requests directory structure.\r
b9ec9330 132\r
cae7420b
DB
133**/\r
134VOID\r
135FatRequestODir (\r
136 IN FAT_OFILE *OFile\r
137 )\r
b9ec9330
QH
138{\r
139 UINTN DirCacheTag;\r
140 FAT_VOLUME *Volume;\r
141 FAT_ODIR *ODir;\r
142 FAT_ODIR *CurrentODir;\r
143 LIST_ENTRY *CurrentODirLink;\r
144\r
145 Volume = OFile->Volume;\r
146 ODir = NULL;\r
147 DirCacheTag = OFile->FileCluster;\r
148 for (CurrentODirLink = Volume->DirCacheList.ForwardLink;\r
149 CurrentODirLink != &Volume->DirCacheList;\r
150 CurrentODirLink = CurrentODirLink->ForwardLink\r
151 ) {\r
152 CurrentODir = ODIR_FROM_DIRCACHELINK (CurrentODirLink);\r
153 if (CurrentODir->DirCacheTag == DirCacheTag) {\r
154 RemoveEntryList (&CurrentODir->DirCacheLink);\r
155 Volume->DirCacheCount--;\r
156 ODir = CurrentODir;\r
157 break;\r
158 }\r
159 }\r
160\r
161 if (ODir == NULL) {\r
162 //\r
163 // This directory is not cached, then allocate a new one\r
164 //\r
165 ODir = FatAllocateODir (OFile);\r
166 }\r
167\r
168 OFile->ODir = ODir;\r
169}\r
170\r
cae7420b 171/**\r
b9ec9330
QH
172\r
173 Clean up all the cached directory structures when the volume is going to be abandoned.\r
174\r
cae7420b 175 @param Volume - FAT file system volume.\r
b9ec9330 176\r
cae7420b
DB
177**/\r
178VOID\r
179FatCleanupODirCache (\r
180 IN FAT_VOLUME *Volume\r
181 )\r
b9ec9330
QH
182{\r
183 FAT_ODIR *ODir;\r
184 while (Volume->DirCacheCount > 0) {\r
185 ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);\r
186 RemoveEntryList (&ODir->DirCacheLink);\r
187 FatFreeODir (ODir);\r
188 Volume->DirCacheCount--;\r
189 }\r
190}\r