Added support for FAT16 partition with clustersize greater than page size.

Patch by Hartmut Birr.

svn path=/trunk/; revision=2057
This commit is contained in:
Eric Kohl 2001-07-13 10:31:14 +00:00
parent 6d64efee46
commit 889f9e3c01
3 changed files with 58 additions and 33 deletions

View file

@ -1,4 +1,4 @@
/* $Id: direntry.c,v 1.1 2001/07/05 01:51:52 rex Exp $ /* $Id: direntry.c,v 1.2 2001/07/13 10:31:14 ekohl Exp $
* *
* *
* FILE: DirEntry.c * FILE: DirEntry.c
@ -20,8 +20,12 @@
#include "vfat.h" #include "vfat.h"
#define ENTRIES_PER_PAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \ #define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
(PAGESIZE / ((pDeviceExt)->BytesPerSector))) (pDeviceExt)->BytesPerCluster : PAGESIZE)
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
(CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->BytesPerSector)))
ULONG ULONG
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
@ -74,8 +78,8 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
PFAT_DIR_ENTRY pDirEntry) PFAT_DIR_ENTRY pDirEntry)
{ {
NTSTATUS status; NTSTATUS status;
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_PAGE(pDeviceExt); ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt);
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_PAGE(pDeviceExt); ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt);
PVOID currentPage = NULL; PVOID currentPage = NULL;
PCACHE_SEGMENT cacheSegment = NULL; PCACHE_SEGMENT cacheSegment = NULL;
FATDirEntry * fatDirEntry; FATDirEntry * fatDirEntry;
@ -94,7 +98,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
DPRINT ("Validating current directory page\n"); DPRINT ("Validating current directory page\n");
status = vfatRequestAndValidateRegion (pDeviceExt, status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB, pDirectoryFCB,
pageNumber * PAGESIZE, pageNumber * CACHEPAGESIZE(pDeviceExt),
(PVOID *) &currentPage, (PVOID *) &currentPage,
&cacheSegment, &cacheSegment,
FALSE); FALSE);
@ -139,7 +143,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
{ {
(*pDirectoryIndex)++; (*pDirectoryIndex)++;
indexInPage++; indexInPage++;
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt)) if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
{ {
indexInPage = 0; indexInPage = 0;
pageNumber++; pageNumber++;
@ -153,7 +157,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
} }
status = vfatRequestAndValidateRegion (pDeviceExt, status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB, pDirectoryFCB,
pageNumber * PAGESIZE, pageNumber * CACHEPAGESIZE(pDeviceExt),
(PVOID *) &currentPage, (PVOID *) &currentPage,
&cacheSegment, &cacheSegment,
FALSE); FALSE);
@ -181,7 +185,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
} }
(*pDirectoryIndex)++; (*pDirectoryIndex)++;
indexInPage++; indexInPage++;
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt)) if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
{ {
indexInPage = 0; indexInPage = 0;
pageNumber++; pageNumber++;
@ -195,7 +199,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
} }
status = vfatRequestAndValidateRegion (pDeviceExt, status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB, pDirectoryFCB,
pageNumber * PAGESIZE, pageNumber * CACHEPAGESIZE(pDeviceExt),
(PVOID *) &currentPage, (PVOID *) &currentPage,
&cacheSegment, &cacheSegment,
FALSE); FALSE);

View file

@ -1,5 +1,5 @@
/* /*
* $Id: fat.c,v 1.27 2001/06/15 11:14:53 ekohl Exp $ * $Id: fat.c,v 1.28 2001/07/13 10:31:14 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -20,6 +20,13 @@
#include "vfat.h" #include "vfat.h"
/* GLOBALS ******************************************************************/
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
(pDeviceExt)->BytesPerCluster : PAGESIZE)
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS NTSTATUS
@ -83,11 +90,14 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
PCACHE_SEGMENT CacheSeg; PCACHE_SEGMENT CacheSeg;
NTSTATUS Status; NTSTATUS Status;
ULONG FATOffset; ULONG FATOffset;
ULONG ChunkSize;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + (CurrentCluster * 2); FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + (CurrentCluster * 2);
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb, Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
PAGE_ROUND_DOWN(FATOffset), ROUND_DOWN(FATOffset, ChunkSize),
&BaseAddress, &BaseAddress,
&Valid, &Valid,
&CacheSeg); &CacheSeg);
@ -98,8 +108,8 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
if (!Valid) if (!Valid)
{ {
Status = VfatReadSectors(DeviceExt->StorageDevice, Status = VfatReadSectors(DeviceExt->StorageDevice,
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE, ROUND_DOWN(FATOffset, ChunkSize) / BLOCKSIZE,
PAGESIZE / BLOCKSIZE, ChunkSize / BLOCKSIZE,
BaseAddress); BaseAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -108,7 +118,7 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
} }
} }
CurrentCluster = *((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))); CurrentCluster = *((PUSHORT)(BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff; CurrentCluster = 0xffffffff;
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
@ -191,6 +201,9 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
PCACHE_SEGMENT CacheSeg; PCACHE_SEGMENT CacheSeg;
BOOLEAN Valid; BOOLEAN Valid;
ULONG FatStart; ULONG FatStart;
ULONG ChunkSize;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FatStart = DeviceExt->FATStart * BLOCKSIZE; FatStart = DeviceExt->FATStart * BLOCKSIZE;
FatLength = DeviceExt->Boot->FATSectors * BLOCKSIZE; FatLength = DeviceExt->Boot->FATSectors * BLOCKSIZE;
@ -199,14 +212,14 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
for (i = 2; i < FatLength; i+=2) for (i = 2; i < FatLength; i+=2)
{ {
if (((FatStart + i) % PAGESIZE) == 0 || CacheSeg == NULL) if (((FatStart + i) % ChunkSize) == 0 || CacheSeg == NULL)
{ {
if (CacheSeg != NULL) if (CacheSeg != NULL)
{ {
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
} }
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb, Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
PAGE_ROUND_DOWN(FatStart + i), ROUND_DOWN(FatStart + i, ChunkSize),
&BaseAddress, &BaseAddress,
&Valid, &Valid,
&CacheSeg); &CacheSeg);
@ -217,9 +230,9 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
if (!Valid) if (!Valid)
{ {
Status = VfatReadSectors(DeviceExt->StorageDevice, Status = VfatReadSectors(DeviceExt->StorageDevice,
PAGE_ROUND_DOWN(FatStart + i) ROUND_DOWN(FatStart + i, ChunkSize)
/ BLOCKSIZE, / BLOCKSIZE,
PAGESIZE / BLOCKSIZE, ChunkSize / BLOCKSIZE,
BaseAddress); BaseAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -229,7 +242,7 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
} }
} }
} }
if (*((PUSHORT)(BaseAddress + ((FatStart + i) % PAGESIZE))) == 0) if (*((PUSHORT)(BaseAddress + ((FatStart + i) % ChunkSize))) == 0)
{ {
DPRINT("Found available cluster 0x%x\n", i); DPRINT("Found available cluster 0x%x\n", i);
*Cluster = i / 2; *Cluster = i / 2;
@ -609,6 +622,9 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG FATOffset; ULONG FATOffset;
ULONG Start; ULONG Start;
ULONG i; ULONG i;
ULONG ChunkSize;
ChunkSize = CACHEPAGESIZE(DeviceExt);
Start = DeviceExt->FATStart; Start = DeviceExt->FATStart;
@ -617,7 +633,7 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
for (i = 0; i < DeviceExt->Boot->FATCount; i++) for (i = 0; i < DeviceExt->Boot->FATCount; i++)
{ {
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb, Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
PAGE_ROUND_DOWN(FATOffset), ROUND_DOWN(FATOffset, ChunkSize),
&BaseAddress, &BaseAddress,
&Valid, &Valid,
&CacheSeg); &CacheSeg);
@ -628,8 +644,8 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
if (!Valid) if (!Valid)
{ {
Status = VfatReadSectors(DeviceExt->StorageDevice, Status = VfatReadSectors(DeviceExt->StorageDevice,
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE, ROUND_DOWN(FATOffset, ChunkSize) / BLOCKSIZE,
PAGESIZE / BLOCKSIZE, ChunkSize / BLOCKSIZE,
BaseAddress); BaseAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -640,10 +656,10 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset, DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
ClusterToWrite); ClusterToWrite);
*((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))) = NewValue; *((PUSHORT)(BaseAddress + (FATOffset % ChunkSize))) = NewValue;
Status = VfatWriteSectors(DeviceExt->StorageDevice, Status = VfatWriteSectors(DeviceExt->StorageDevice,
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE, ROUND_DOWN(FATOffset,ChunkSize) / BLOCKSIZE,
PAGESIZE / BLOCKSIZE, ChunkSize / BLOCKSIZE,
BaseAddress); BaseAddress);
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
@ -957,3 +973,5 @@ GetNextSector (PDEVICE_EXTENSION DeviceExt,
return (STATUS_SUCCESS); return (STATUS_SUCCESS);
} }
} }
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: iface.c,v 1.54 2001/07/05 01:51:52 rex Exp $ /* $Id: iface.c,v 1.55 2001/07/13 10:31:14 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -35,6 +35,9 @@
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
(pDeviceExt)->BytesPerCluster : PAGESIZE)
static PDRIVER_OBJECT VfatDriverObject; static PDRIVER_OBJECT VfatDriverObject;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -203,7 +206,7 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
DeviceExt->StorageDevice); DeviceExt->StorageDevice);
Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice, Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice,
&DeviceExt->StorageBcb, &DeviceExt->StorageBcb,
PAGESIZE); CACHEPAGESIZE(DeviceExt));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* FIXME: delete device object */ /* FIXME: delete device object */