reactos/drivers/filesystems/fastfat/fat.c

708 lines
18 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/fat.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include "vfat.h"
/* GLOBALS ******************************************************************/
2002-10-01 Casper S. Hornstrup <chorns@users.sourceforge.net> * drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. * drivers/fs/cdfs/fcb.c: Ditto. * drivers/fs/cdfs/fsctl.c: Ditto. * drivers/fs/cdfs/rw.c: Ditto. * drivers/fs/ext2/dir.c: Ditto. * drivers/fs/ext2/inode.c: Ditto. * drivers/fs/ext2/rw.c: Ditto. * drivers/fs/ext2/super.c: Ditto. * drivers/fs/minix/blockdev.c: Ditto. * drivers/fs/minix/cache.c: Ditto. * drivers/fs/minix/inode.c: Ditto. * drivers/fs/minix/rw.c: Ditto. * drivers/fs/ntfs/fcb.c: Ditto. * drivers/fs/ntfs/ntfs.h: Ditto. * drivers/fs/vfat/create.c: Ditto. * drivers/fs/vfat/direntry.c: Ditto. * drivers/fs/vfat/dirwr.c: Ditto. * drivers/fs/vfat/fat.c: Ditto. * drivers/fs/vfat/fcb.c: Ditto. * drivers/fs/vfat/fsctl.c: Ditto. * drivers/fs/vfat/rw.c: Ditto. * drivers/storage/class2/class2.c: Ditto. * drivers/storage/scsiport/scsiport.c: Ditto. * hal/halx86/adapter.c: Ditto. * hal/halx86/mp.c: Ditto. * include/ddk/mmfuncs.h: Ditto. * include/ddk/mmtypes.h: Ditto. * include/ddk/i386/pagesize.h: Ditto. * include/ntdll/pagesize.h: Ditto. * lib/kernel32/process/create.c: Ditto. * lib/kernel32/thread/thread.c: Ditto. * lib/ntdll/ldr/utils.c: Ditto. * lib/ntdll/rtl/env.c: Ditto. * lib/ntdll/rtl/heap.c: Ditto. * lib/ntdll/rtl/ppb.c: Ditto. * lib/ntdll/rtl/process.c: Ditto. * lib/ntdll/rtl/thread.c: Ditto. * ntoskrnl/cc/copy.c: Ditto. * ntoskrnl/cc/view.c: Ditto. * ntoskrnl/ex/sysinfo.c: Ditto. * ntoskrnl/include/internal/i386/mm.h: Ditto. * ntoskrnl/io/mdl.c: Ditto. * ntoskrnl/ke/kthread.c: Ditto. * ntoskrnl/ke/i386/kernel.c: Ditto. * ntoskrnl/ldr/init.c: Ditto. * ntoskrnl/ldr/loader.c: Ditto. * ntoskrnl/mm/anonmem.c: Ditto. * ntoskrnl/mm/cont.c: Ditto. * ntoskrnl/mm/freelist.c: Ditto. * ntoskrnl/mm/iospace.c: Ditto. * ntoskrnl/mm/kmap.c: Ditto. * ntoskrnl/mm/marea.c: Ditto. * ntoskrnl/mm/mdl.c: Ditto. * ntoskrnl/mm/mminit.c: Ditto. * ntoskrnl/mm/ncache.c: Ditto. * ntoskrnl/mm/npool.c: Ditto. * ntoskrnl/mm/pagefile.c: Ditto. * ntoskrnl/mm/pageop.c: Ditto. * ntoskrnl/mm/section.c: Ditto. * ntoskrnl/mm/slab.c: Ditto. * ntoskrnl/mm/i386/page.c: Ditto. * ntoskrnl/ob/handle.c: Ditto. * ntoskrnl/ps/create.c: Ditto. * ntoskrnl/ps/process.c: Ditto. * ntoskrnl/ps/w32call.c: Ditto. * subsys/win32k/include/object.h: Ditto. svn path=/trunk/; revision=3594
2002-10-01 19:27:25 +00:00
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
/* FUNCTIONS ****************************************************************/
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
* disk read
*/
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * sizeof(ULONG);
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return (STATUS_SUCCESS);
}
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table
*/
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return (STATUS_SUCCESS);
}
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
*/
{
PUSHORT CBlock;
ULONG Entry;
PVOID BaseAddress;
PVOID Context;
LARGE_INTEGER Offset;
*NextCluster = 0;
Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
if ((CurrentCluster % 2) == 0)
{
Entry = *CBlock & 0x0fff;
}
else
{
Entry = *CBlock >> 4;
}
// DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff;
// DPRINT("Returning %x\n",Entry);
*NextCluster = Entry;
CcUnpinData(Context);
// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT16 table
*/
{
ULONG FatLength;
ULONG StartCluster;
ULONG i, j;
PVOID BaseAddress;
ULONG ChunkSize;
PVOID Context = 0;
LARGE_INTEGER Offset;
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
PUSHORT Block;
PUSHORT BlockEnd;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
for (j = 0; j < 2; j++)
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
for (i = StartCluster; i < FatLength; )
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return STATUS_UNSUCCESSFUL;
}
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
if (*Block == 0)
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
DPRINT("Found available cluster 0x%x\n", i);
DeviceExt->LastAvailableCluster = *Cluster = i;
*Block = 0xffff;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return(STATUS_SUCCESS);
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Block++;
i++;
}
CcUnpinData(Context);
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = StartCluster;
StartCluster = 2;
}
return(STATUS_DISK_FULL);
}
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT12 table
*/
{
ULONG FatLength;
ULONG StartCluster;
ULONG Entry;
PUSHORT CBlock;
ULONG i, j;
PVOID BaseAddress;
PVOID Context;
LARGE_INTEGER Offset;
FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
Offset.QuadPart = 0;
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
return STATUS_UNSUCCESSFUL;
}
for (j = 0; j < 2; j++)
{
for (i = StartCluster; i < FatLength; i++)
{
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
if ((i % 2) == 0)
{
Entry = *CBlock & 0xfff;
}
else
{
Entry = *CBlock >> 4;
}
if (Entry == 0)
{
DPRINT("Found available cluster 0x%x\n", i);
DeviceExt->LastAvailableCluster = *Cluster = i;
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
if ((i % 2) == 0)
*CBlock = (*CBlock & 0xf000) | 0xfff;
else
*CBlock = (*CBlock & 0xf) | 0xfff0;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
return(STATUS_SUCCESS);
}
}
FatLength = StartCluster;
StartCluster = 2;
}
CcUnpinData(Context);
return (STATUS_DISK_FULL);
}
NTSTATUS
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT32 table
*/
{
ULONG FatLength;
ULONG StartCluster;
ULONG i, j;
PVOID BaseAddress;
ULONG ChunkSize;
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
PVOID Context;
LARGE_INTEGER Offset;
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
PULONG Block;
PULONG BlockEnd;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
for (j = 0; j < 2; j++)
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
for (i = StartCluster; i < FatLength;)
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return STATUS_UNSUCCESSFUL;
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
if ((*Block & 0x0fffffff) == 0)
{
DPRINT("Found available cluster 0x%x\n", i);
DeviceExt->LastAvailableCluster = *Cluster = i;
*Block = 0x0fffffff;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return(STATUS_SUCCESS);
}
Block++;
i++;
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
CcUnpinData(Context);
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = StartCluster;
StartCluster = 2;
}
return (STATUS_DISK_FULL);
}
static NTSTATUS
FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free cluster in a FAT12 table
*/
{
ULONG Entry;
PVOID BaseAddress;
ULONG ulCount = 0;
ULONG i;
ULONG numberofclusters;
LARGE_INTEGER Offset;
PVOID Context;
PUSHORT CBlock;
Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
for (i = 2; i < numberofclusters; i++)
{
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
if ((i % 2) == 0)
{
Entry = *CBlock & 0x0fff;
}
else
{
Entry = *CBlock >> 4;
}
if (Entry == 0)
ulCount++;
}
CcUnpinData(Context);
DeviceExt->AvailableClusters = ulCount;
DeviceExt->AvailableClustersValid = TRUE;
return(STATUS_SUCCESS);
}
static NTSTATUS
FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT16 table
*/
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
PUSHORT Block;
PUSHORT BlockEnd;
PVOID BaseAddress = NULL;
ULONG ulCount = 0;
ULONG i;
ULONG ChunkSize;
PVOID Context = NULL;
LARGE_INTEGER Offset;
ULONG FatLength;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
for (i = 2; i < FatLength; )
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return STATUS_UNSUCCESSFUL;
}
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
if (*Block == 0)
ulCount++;
Block++;
i++;
}
CcUnpinData(Context);
}
DeviceExt->AvailableClusters = ulCount;
DeviceExt->AvailableClustersValid = TRUE;
return(STATUS_SUCCESS);
}
static NTSTATUS
FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT32 table
*/
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
PULONG Block;
PULONG BlockEnd;
PVOID BaseAddress = NULL;
ULONG ulCount = 0;
ULONG i;
ULONG ChunkSize;
PVOID Context = NULL;
LARGE_INTEGER Offset;
ULONG FatLength;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
for (i = 2; i < FatLength; )
{
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
return STATUS_UNSUCCESSFUL;
}
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
if ((*Block & 0x0fffffff) == 0)
ulCount++;
Block++;
i++;
}
CcUnpinData(Context);
}
DeviceExt->AvailableClusters = ulCount;
DeviceExt->AvailableClustersValid = TRUE;
return(STATUS_SUCCESS);
}
NTSTATUS
CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
PLARGE_INTEGER Clusters)
{
NTSTATUS Status = STATUS_SUCCESS;
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
if (!DeviceExt->AvailableClustersValid)
{
if (DeviceExt->FatInfo.FatType == FAT12)
Status = FAT12CountAvailableClusters(DeviceExt);
else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
Status = FAT16CountAvailableClusters(DeviceExt);
else
Status = FAT32CountAvailableClusters(DeviceExt);
}
Clusters->QuadPart = DeviceExt->AvailableClusters;
ExReleaseResourceLite (&DeviceExt->FatResource);
return Status;
}
NTSTATUS
FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
ULONG NewValue,
PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
*/
{
ULONG FATOffset;
PUCHAR CBlock;
PVOID BaseAddress;
PVOID Context;
LARGE_INTEGER Offset;
Offset.QuadPart = 0;
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CBlock = (PUCHAR)BaseAddress;
FATOffset = (ClusterToWrite * 12) / 8;
DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
NewValue, ClusterToWrite, FATOffset);
if ((ClusterToWrite % 2) == 0)
{
*OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
CBlock[FATOffset] = (UCHAR)NewValue;
CBlock[FATOffset + 1] &= 0xf0;
CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
}
else
{
*OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
CBlock[FATOffset] &= 0x0f;
CBlock[FATOffset] |= (NewValue & 0xf) << 4;
CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
}
/* Write the changed FAT sector(s) to disk */
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
NTSTATUS
FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
ULONG NewValue,
PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
*/
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PUSHORT Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = ClusterToWrite * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
ClusterToWrite);
Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
*OldValue = *Cluster;
*Cluster = (USHORT)NewValue;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
NTSTATUS
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
ULONG NewValue,
PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT32 physical tables
*/
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PULONG Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = (ClusterToWrite * 4);
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
ClusterToWrite);
Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
*OldValue = *Cluster & 0x0fffffff;
*Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
NTSTATUS
WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
ULONG NewValue)
/*
* FUNCTION: Write a changed FAT entry
*/
{
NTSTATUS Status;
ULONG OldValue;
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
if (DeviceExt->AvailableClustersValid)
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
{
if (OldValue && NewValue == 0)
InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
else if (OldValue == 0 && NewValue)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
}
ExReleaseResourceLite(&DeviceExt->FatResource);
return(Status);
}
ULONGLONG
ClusterToSector(PDEVICE_EXTENSION DeviceExt,
ULONG Cluster)
/*
* FUNCTION: Converts the cluster number to a sector number for this physical
* device
*/
{
return DeviceExt->FatInfo.dataStart +
((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
}
NTSTATUS
GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next cluster depending on the FAT type
*/
{
NTSTATUS Status;
DPRINT ("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
DeviceExt, CurrentCluster);
if (CurrentCluster == 0)
return(STATUS_INVALID_PARAMETER);
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
ExReleaseResourceLite(&DeviceExt->FatResource);
return(Status);
}
NTSTATUS
GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next cluster depending on the FAT type
*/
{
NTSTATUS Status;
DPRINT ("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
DeviceExt, CurrentCluster);
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
/*
* If the file hasn't any clusters allocated then we need special
* handling
*/
if (CurrentCluster == 0)
{
ULONG NewCluster;
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&DeviceExt->FatResource);
return Status;
}
*NextCluster = NewCluster;
ExReleaseResourceLite(&DeviceExt->FatResource);
return(STATUS_SUCCESS);
}
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
if ((*NextCluster) == 0xFFFFFFFF)
{
ULONG NewCluster;
/* We are after last existing cluster, we must add one to file */
- Change all FAT*FindAvailableCluster functions to new functions FAT*FindAndMarkAvailableCluster which have incorporated the setting of EOF marker in the File Allocation Table for the returned cluster. - Rewritten FAT32CountAvailableClusters, FAT32FindAndMarkAvailableCluster, FAT16CountAvailableClusters and FAT16FindAndMarkAvailableCluster for better performance. These functions were using one big loop for traversing the FAT and had a block of code in the loop for requesting cache manger for next chunk of FAT *if necessary* (which commonly wasn't the case). Now it's changed to request always a whole FAT chunk and process it at once in a nested loop. - Cache last offset + cluster pair while reading/writing from/to file. This ensures almost linear times when doing sequential reads/writes, because the whole FAT traversing for the file is not done again for every request. Previously there was code for this, but it was neither correctly used nor working. It stored the last offset + cluster pair in file CCB structure (that is unique for each opened file handle) and not FCB structure (which is shared among all instances of the same file). This resulted in inconsistent cluster + offset number when the file allocation chain was changed (eg. by enlarging/shrinking the file), but since the cached offsets weren't actully used it went unnoticed. - Remove old hack from NextCluster and fix the call to it in VfatAddEntry. Not much to say about it, there was an temporary hack in NextCluster and with fixed VfatAddEntry it's now no longer needed. - Add pointers to WriteCluster, FindAndMarkAvailableCluster and GetNextCluster functions to device extension (set during mount) and use them at appropriate locations. This avoids some nasty if's in the code and causes some unnoticable performance improvment in the low-level FAT code. - Lock the directory FCB in VfatAddEntry while modifying it. This should propably be done on more places, but it needs more investigations. - Increase the file cache allocation size in VfatRead/VfatWrite. It boosts the overall speed of the driver a lot. svn path=/trunk/; revision=10344
2004-08-01 21:57:18 +00:00
/* Firstly, find the next available open allocation unit and
mark it as end of file */
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&DeviceExt->FatResource);
return Status;
}
/* Now, write the AU of the LastCluster with the value of the newly
found AU */
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
*NextCluster = NewCluster;
}
ExReleaseResourceLite(&DeviceExt->FatResource);
return(Status);
}
/* EOF */