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