DirectoryCache.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*++
  2. Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>
  3. This program and the accompanying materials are licensed and made available
  4. under the terms and conditions of the BSD License which accompanies this
  5. distribution. The full text of the license may be found at
  6. http://opensource.org/licenses/bsd-license.php
  7. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  9. Module Name:
  10. DirectoryCache.c
  11. Abstract:
  12. Functions for directory cache operation
  13. Revision History
  14. --*/
  15. #include "Fat.h"
  16. STATIC
  17. VOID
  18. FatFreeODir (
  19. IN FAT_ODIR *ODir
  20. )
  21. /*++
  22. Routine Description:
  23. Free the directory structure and release the memory.
  24. Arguments:
  25. ODir - The directory to be freed.
  26. Returns:
  27. None.
  28. --*/
  29. {
  30. FAT_DIRENT *DirEnt;
  31. //
  32. // Release Directory Entry Nodes
  33. //
  34. while (!IsListEmpty (&ODir->ChildList)) {
  35. DirEnt = DIRENT_FROM_LINK (ODir->ChildList.ForwardLink);
  36. RemoveEntryList (&DirEnt->Link);
  37. //
  38. // Make sure the OFile has been closed
  39. //
  40. ASSERT (DirEnt->OFile == NULL);
  41. FatFreeDirEnt (DirEnt);
  42. }
  43. FreePool (ODir);
  44. }
  45. STATIC
  46. FAT_ODIR *
  47. FatAllocateODir (
  48. IN FAT_OFILE *OFile
  49. )
  50. /*++
  51. Routine Description:
  52. Allocate the directory structure.
  53. Arguments:
  54. OFile - The corresponding OFile.
  55. Returns:
  56. None.
  57. --*/
  58. {
  59. FAT_ODIR *ODir;
  60. ODir = AllocateZeroPool (sizeof (FAT_ODIR));
  61. if (ODir != NULL) {
  62. //
  63. // Initialize the directory entry list
  64. //
  65. ODir->Signature = FAT_ODIR_SIGNATURE;
  66. InitializeListHead (&ODir->ChildList);
  67. ODir->CurrentCursor = &ODir->ChildList;
  68. }
  69. return ODir;
  70. }
  71. VOID
  72. FatDiscardODir (
  73. IN FAT_OFILE *OFile
  74. )
  75. /*++
  76. Routine Description:
  77. Discard the directory structure when an OFile will be freed.
  78. Volume will cache this directory if the OFile does not represent a deleted file.
  79. Arguments:
  80. OFile - The OFile whose directory structure is to be discarded.
  81. Returns:
  82. None.
  83. --*/
  84. {
  85. FAT_ODIR *ODir;
  86. FAT_VOLUME *Volume;
  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. // Release ODir Structure
  112. //
  113. if (ODir != NULL) {
  114. FatFreeODir (ODir);
  115. }
  116. }
  117. VOID
  118. FatRequestODir (
  119. IN FAT_OFILE *OFile
  120. )
  121. /*++
  122. Routine Description:
  123. Request the directory structure when an OFile is newly generated.
  124. If the directory structure is cached by volume, then just return this directory;
  125. Otherwise, allocate a new one for OFile.
  126. Arguments:
  127. OFile - The OFile which requests directory structure.
  128. Returns:
  129. None.
  130. --*/
  131. {
  132. UINTN DirCacheTag;
  133. FAT_VOLUME *Volume;
  134. FAT_ODIR *ODir;
  135. FAT_ODIR *CurrentODir;
  136. LIST_ENTRY *CurrentODirLink;
  137. Volume = OFile->Volume;
  138. ODir = NULL;
  139. DirCacheTag = OFile->FileCluster;
  140. for (CurrentODirLink = Volume->DirCacheList.ForwardLink;
  141. CurrentODirLink != &Volume->DirCacheList;
  142. CurrentODirLink = CurrentODirLink->ForwardLink
  143. ) {
  144. CurrentODir = ODIR_FROM_DIRCACHELINK (CurrentODirLink);
  145. if (CurrentODir->DirCacheTag == DirCacheTag) {
  146. RemoveEntryList (&CurrentODir->DirCacheLink);
  147. Volume->DirCacheCount--;
  148. ODir = CurrentODir;
  149. break;
  150. }
  151. }
  152. if (ODir == NULL) {
  153. //
  154. // This directory is not cached, then allocate a new one
  155. //
  156. ODir = FatAllocateODir (OFile);
  157. }
  158. OFile->ODir = ODir;
  159. }
  160. VOID
  161. FatCleanupODirCache (
  162. IN FAT_VOLUME *Volume
  163. )
  164. /*++
  165. Routine Description:
  166. Clean up all the cached directory structures when the volume is going to be abandoned.
  167. Arguments:
  168. Volume - FAT file system volume.
  169. Returns:
  170. None.
  171. --*/
  172. {
  173. FAT_ODIR *ODir;
  174. while (Volume->DirCacheCount > 0) {
  175. ODir = ODIR_FROM_DIRCACHELINK (Volume->DirCacheList.BackLink);
  176. RemoveEntryList (&ODir->DirCacheLink);
  177. FatFreeODir (ODir);
  178. Volume->DirCacheCount--;
  179. }
  180. }