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