TianoCore EDK2 master
Loading...
Searching...
No Matches
DirectoryCache.c
Go to the documentation of this file.
1
10#include "Fat.h"
11
20VOID
22 IN FAT_ODIR *ODir
23 )
24{
25 FAT_DIRENT *DirEnt;
26
27 //
28 // Release Directory Entry Nodes
29 //
30 while (!IsListEmpty (&ODir->ChildList)) {
31 DirEnt = DIRENT_FROM_LINK (ODir->ChildList.ForwardLink);
32 RemoveEntryList (&DirEnt->Link);
33 //
34 // Make sure the OFile has been closed
35 //
36 ASSERT (DirEnt->OFile == NULL);
37 FatFreeDirEnt (DirEnt);
38 }
39
40 FreePool (ODir);
41}
42
53 IN FAT_OFILE *OFile
54 )
55{
56 FAT_ODIR *ODir;
57
58 ODir = AllocateZeroPool (sizeof (FAT_ODIR));
59 if (ODir != NULL) {
60 //
61 // Initialize the directory entry list
62 //
63 ODir->Signature = FAT_ODIR_SIGNATURE;
64 InitializeListHead (&ODir->ChildList);
65 ODir->CurrentCursor = &ODir->ChildList;
66 }
67
68 return ODir;
69}
70
79VOID
81 IN FAT_OFILE *OFile
82 )
83{
84 FAT_ODIR *ODir;
85 FAT_VOLUME *Volume;
86
87 Volume = OFile->Volume;
88 ODir = OFile->ODir;
89 if (!OFile->DirEnt->Invalid) {
90 //
91 // If OFile does not represent a deleted file, then we will cache the directory
92 // We use OFile's first cluster as the directory's tag
93 //
94 ODir->DirCacheTag = OFile->FileCluster;
95 InsertHeadList (&Volume->DirCacheList, &ODir->DirCacheLink);
96 if (Volume->DirCacheCount == FAT_MAX_DIR_CACHE_COUNT) {
97 //
98 // Replace the least recent used directory
99 //
100 ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);
101 RemoveEntryList (&ODir->DirCacheLink);
102 } else {
103 //
104 // No need to find a replace
105 //
106 Volume->DirCacheCount++;
107 ODir = NULL;
108 }
109 }
110
111 //
112 // Release ODir Structure
113 //
114 if (ODir != NULL) {
115 FatFreeODir (ODir);
116 }
117}
118
129VOID
131 IN FAT_OFILE *OFile
132 )
133{
134 UINTN DirCacheTag;
135 FAT_VOLUME *Volume;
136 FAT_ODIR *ODir;
137 FAT_ODIR *CurrentODir;
138 LIST_ENTRY *CurrentODirLink;
139
140 Volume = OFile->Volume;
141 ODir = NULL;
142 DirCacheTag = OFile->FileCluster;
143 for (CurrentODirLink = Volume->DirCacheList.ForwardLink;
144 CurrentODirLink != &Volume->DirCacheList;
145 CurrentODirLink = CurrentODirLink->ForwardLink
146 )
147 {
148 CurrentODir = ODIR_FROM_DIRCACHELINK (CurrentODirLink);
149 if (CurrentODir->DirCacheTag == DirCacheTag) {
150 RemoveEntryList (&CurrentODir->DirCacheLink);
151 Volume->DirCacheCount--;
152 ODir = CurrentODir;
153 break;
154 }
155 }
156
157 if (ODir == NULL) {
158 //
159 // This directory is not cached, then allocate a new one
160 //
161 ODir = FatAllocateODir (OFile);
162 }
163
164 OFile->ODir = ODir;
165}
166
174VOID
176 IN FAT_VOLUME *Volume
177 )
178{
179 FAT_ODIR *ODir;
180
181 while (Volume->DirCacheCount > 0) {
182 ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);
183 RemoveEntryList (&ODir->DirCacheLink);
184 FatFreeODir (ODir);
185 Volume->DirCacheCount--;
186 }
187}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
STATIC VOID FatFreeODir(IN FAT_ODIR *ODir)
VOID FatRequestODir(IN FAT_OFILE *OFile)
VOID FatDiscardODir(IN FAT_OFILE *OFile)
VOID FatCleanupODirCache(IN FAT_VOLUME *Volume)
STATIC FAT_ODIR * FatAllocateODir(IN FAT_OFILE *OFile)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID FatFreeDirEnt(IN FAT_DIRENT *DirEnt)
Definition: Misc.c:441
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
Definition: Fat.h:204