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