[FREELDR]

Implement directory buffer caching for FAT

svn path=/trunk/; revision=53983
This commit is contained in:
Timo Kreuzer 2011-10-03 23:35:27 +00:00
parent 9893e19698
commit adb380a421

View file

@ -370,9 +370,21 @@ ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSect
} }
} }
typedef struct _DIRECTORY_BUFFER
{
LIST_ENTRY Link;
PVOID Volume;
ULONG DirectoryStartCluster;
ULONG DirectorySize;
UCHAR Data[];
} DIRECTORY_BUFFER, *PDIRECTORY_BUFFER;
LIST_ENTRY DirectoryBufferListHead = {&DirectoryBufferListHead, &DirectoryBufferListHead};
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *DirectorySize, BOOLEAN RootDirectory) PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *DirectorySize, BOOLEAN RootDirectory)
{ {
PVOID DirectoryBuffer; PDIRECTORY_BUFFER DirectoryBuffer;
PLIST_ENTRY Entry;
TRACE("FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE")); TRACE("FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE"));
@ -386,6 +398,23 @@ PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, U
RootDirectory = FALSE; RootDirectory = FALSE;
} }
/* Search the list for a match */
for (Entry = DirectoryBufferListHead.Flink;
Entry != &DirectoryBufferListHead;
Entry = Entry->Flink)
{
DirectoryBuffer = CONTAINING_RECORD(Entry, DIRECTORY_BUFFER, Link);
/* Check if it matches */
if ((DirectoryBuffer->Volume == Volume) &&
(DirectoryBuffer->DirectoryStartCluster == DirectoryStartCluster))
{
TRACE("Found cached buffer\n");
*DirectorySize = DirectoryBuffer->DirectorySize;
return DirectoryBuffer->Data;
}
}
// //
// Calculate the size of the directory // Calculate the size of the directory
// //
@ -402,7 +431,7 @@ PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, U
// Attempt to allocate memory for directory buffer // Attempt to allocate memory for directory buffer
// //
TRACE("Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize); TRACE("Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize);
DirectoryBuffer = MmHeapAlloc(*DirectorySize); DirectoryBuffer = MmHeapAlloc(*DirectorySize + sizeof(DIRECTORY_BUFFER));
if (DirectoryBuffer == NULL) if (DirectoryBuffer == NULL)
{ {
@ -414,7 +443,7 @@ PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, U
// //
if (RootDirectory) if (RootDirectory)
{ {
if (!FatReadVolumeSectors(Volume, Volume->RootDirSectorStart, Volume->RootDirSectors, DirectoryBuffer)) if (!FatReadVolumeSectors(Volume, Volume->RootDirSectorStart, Volume->RootDirSectors, DirectoryBuffer->Data))
{ {
MmHeapFree(DirectoryBuffer); MmHeapFree(DirectoryBuffer);
return NULL; return NULL;
@ -422,14 +451,20 @@ PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, U
} }
else else
{ {
if (!FatReadClusterChain(Volume, DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer)) if (!FatReadClusterChain(Volume, DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer->Data))
{ {
MmHeapFree(DirectoryBuffer); MmHeapFree(DirectoryBuffer);
return NULL; return NULL;
} }
} }
return DirectoryBuffer; /* Enqueue it in the list */
DirectoryBuffer->Volume = Volume;
DirectoryBuffer->DirectoryStartCluster = DirectoryStartCluster;
DirectoryBuffer->DirectorySize = *DirectorySize;
InsertTailList(&DirectoryBufferListHead, &DirectoryBuffer->Link);
return DirectoryBuffer->Data;
} }
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
@ -774,7 +809,6 @@ LONG FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, ULONG DeviceId, PFAT
{ {
if (!FatXSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo)) if (!FatXSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
{ {
MmHeapFree(DirectoryBuffer);
return ENOENT; return ENOENT;
} }
} }
@ -782,13 +816,10 @@ LONG FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, ULONG DeviceId, PFAT
{ {
if (!FatSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo)) if (!FatSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
{ {
MmHeapFree(DirectoryBuffer);
return ENOENT; return ENOENT;
} }
} }
MmHeapFree(DirectoryBuffer);
// //
// If we have another sub-directory to go then // If we have another sub-directory to go then
// grab the start cluster and free the fat chain array // grab the start cluster and free the fat chain array