Speed optimization in FATxxFindAvailableCluster().

svn path=/trunk/; revision=2344
This commit is contained in:
Hartmut Birr 2001-11-02 22:35:31 +00:00
parent 2723d14c06
commit b5e7b94ea7

View file

@ -1,5 +1,5 @@
/* /*
* $Id: fat.c,v 1.33 2001/10/10 22:16:46 hbirr Exp $ * $Id: fat.c,v 1.34 2001/11/02 22:35:31 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -145,7 +145,8 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
*/ */
{ {
ULONG FatLength; ULONG FatLength;
ULONG i; ULONG StartCluster;
ULONG i, j;
NTSTATUS Status; NTSTATUS Status;
PVOID BaseAddress; PVOID BaseAddress;
ULONG ChunkSize; ULONG ChunkSize;
@ -153,32 +154,38 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt); ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2)*2; FatLength = DeviceExt->NumberOfClusters * 2;
*Cluster = 0; *Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
for (i = 2; i < FatLength; i+=2) for (j = 0; j < 2; j++)
{ {
if ((i % ChunkSize) == 0 || Context ==0) for (i = StartCluster * 2; i < FatLength; i += 2)
{ {
Offset.QuadPart = ROUND_DOWN(i, ChunkSize); if ((i % ChunkSize) == 0 || Context == NULL)
if (Context != NULL) {
{ Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
if (Context != NULL)
{
CcUnpinData(Context);
}
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
}
if (*((PUSHORT)(BaseAddress + (i % ChunkSize))) == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 2);
DeviceExt->LastAvailableCluster = *Cluster = i / 2;
CcUnpinData(Context); CcUnpinData(Context);
} return(STATUS_SUCCESS);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress)) }
{ }
return STATUS_UNSUCCESSFUL; FatLength = StartCluster * 2;
} StartCluster = 2;
}
if (*((PUSHORT)(BaseAddress + (i % ChunkSize))) == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 2);
*Cluster = i / 2;
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
} }
CcUnpinData(Context); CcUnpinData(Context);
return(STATUS_DISK_FULL); return(STATUS_DISK_FULL);
@ -190,47 +197,54 @@ FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
* FUNCTION: Finds the first available cluster in a FAT12 table * FUNCTION: Finds the first available cluster in a FAT12 table
*/ */
{ {
ULONG FatLength;
ULONG FATOffset; ULONG FATOffset;
ULONG StartCluster;
ULONG Entry; ULONG Entry;
PUCHAR CBlock; PUCHAR CBlock;
ULONG i; ULONG i, j;
PVOID BaseAddress; PVOID BaseAddress;
NTSTATUS Status; NTSTATUS Status;
ULONG numberofclusters;
PVOID Context; PVOID Context;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
FatLength = DeviceExt->NumberOfClusters * 2;
*Cluster = 0; *Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
{ {
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->Boot->FATSectors * BLOCKSIZE);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CBlock = (PUCHAR)BaseAddress; CBlock = (PUCHAR)BaseAddress;
numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2; for (j = 0; j < 2; j++)
{
for (i = 2; i < numberofclusters; i++) for (i = StartCluster * 2; i < FatLength; i++)
{ {
FATOffset = (i * 12) / 8; FATOffset = (i * 12) / 8;
if ((i % 2) == 0) if ((i % 2) == 0)
{ {
Entry = CBlock[FATOffset]; Entry = CBlock[FATOffset];
Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8); Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
} }
else else
{ {
Entry = (CBlock[FATOffset] >> 4); Entry = (CBlock[FATOffset] >> 4);
Entry |= (CBlock[FATOffset + 1] << 4); Entry |= (CBlock[FATOffset + 1] << 4);
} }
if (Entry == 0) if (Entry == 0)
{ {
DPRINT("Found available cluster 0x%x\n", i); DPRINT("Found available cluster 0x%x\n", i);
*Cluster = i; DeviceExt->LastAvailableCluster = *Cluster = i;
CcUnpinData(Context); CcUnpinData(Context);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
} }
FatLength = StartCluster * 2;
StartCluster = 2;
}
CcUnpinData(Context); CcUnpinData(Context);
return (STATUS_DISK_FULL); return (STATUS_DISK_FULL);
} }
@ -248,13 +262,19 @@ FAT32FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
ULONG ChunkSize; ULONG ChunkSize;
PVOID Context = NULL; PVOID Context = NULL;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
ULONG StartCluster;
ChunkSize = CACHEPAGESIZE(DeviceExt); ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2)*4; FatLength = DeviceExt->NumberOfClusters * 4;
StartCluster = DeviceExt->LastAvailableCluster;
if (StartCluster == 0)
{
StartCluster = 2;
}
*Cluster = 0; *Cluster = 0;
for (i = 4; i < FatLength; i+=4) for (i = StartCluster * 4; i < FatLength; i += 4)
{ {
if ((i % ChunkSize) == 0 || Context == NULL) if ((i % ChunkSize) == 0 || Context == NULL)
{ {
@ -265,13 +285,38 @@ FAT32FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
} }
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{ {
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
} }
if ((*((PULONG)(BaseAddress + (/*(FatStart +*/ i/*)*/ % ChunkSize))) & 0x0fffffff) == 0) if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
{ {
DPRINT("Found available cluster 0x%x\n", i / 4); DPRINT("Found available cluster 0x%x\n", i / 4);
*Cluster = i / 4; DeviceExt->LastAvailableCluster = *Cluster = i / 4;
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
}
FatLength = StartCluster * 4;
for (i = 8; i < FatLength; i += 4)
{
if ((i % ChunkSize) == 0 || Context == NULL)
{
Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
if (Context != NULL)
{
CcUnpinData(Context);
}
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
}
if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 4);
DeviceExt->LastAvailableCluster = *Cluster = i / 4;
CcUnpinData(Context); CcUnpinData(Context);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -307,7 +352,7 @@ FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CBlock = (PUCHAR)BaseAddress; CBlock = (PUCHAR)BaseAddress;
numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2; numberofclusters = DeviceExt->NumberOfClusters;
for (i = 2; i < numberofclusters; i++) for (i = 2; i < numberofclusters; i++)
{ {