The VFAT filesystem driver now goes through the cache for reads, writing

is disabled.

svn path=/trunk/; revision=1490
This commit is contained in:
David Welch 2001-01-01 04:42:12 +00:00
parent 9e386e114c
commit 240c9da1da
10 changed files with 438 additions and 84 deletions

View file

@ -27,7 +27,7 @@ NTSTATUS MinixRequestCacheBlock(PDEVICE_OBJECT DeviceObject,
{ {
BOOLEAN UptoDate; BOOLEAN UptoDate;
CcRequestCachePage(Bcb, CcRequestCacheSegment(Bcb,
FileOffset, FileOffset,
BaseAddress, BaseAddress,
&UptoDate, &UptoDate,

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.10 2000/12/29 23:17:12 dwelch Exp $ /* $Id: create.c,v 1.11 2001/01/01 04:42:11 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -392,6 +392,7 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
short i, j; short i, j;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
KIRQL oldIrql; KIRQL oldIrql;
ULONG BytesPerCluster;
DPRINT ("FsdOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName); DPRINT ("FsdOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
@ -579,7 +580,17 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
vfat_wcsncpy (ParentFcb->PathName, FileName, MAX_PATH); vfat_wcsncpy (ParentFcb->PathName, FileName, MAX_PATH);
ParentFcb->ObjectName = ParentFcb->PathName + (current - FileName); ParentFcb->ObjectName = ParentFcb->PathName + (current - FileName);
ParentFcb->pDevExt = DeviceExt; ParentFcb->pDevExt = DeviceExt;
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb); BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
if (BytesPerCluster >= PAGESIZE)
{
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb,
BytesPerCluster);
}
else
{
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb,
PAGESIZE);
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("CcInitializeFileCache failed\n"); DbgPrint("CcInitializeFileCache failed\n");
@ -642,10 +653,14 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|| RequestedDisposition == FILE_SUPERSEDE) || RequestedDisposition == FILE_SUPERSEDE)
{ {
CHECKPOINT; CHECKPOINT;
#if 0
Status = Status =
addEntry (DeviceExt, FileObject, RequestedOptions, addEntry (DeviceExt, FileObject, RequestedOptions,
(Stack->Parameters. (Stack->Parameters.
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS)); Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
#else
Status = STATUS_UNSUCCESSFUL;
#endif
if (NT_SUCCESS (Status)) if (NT_SUCCESS (Status))
Irp->IoStatus.Information = FILE_CREATED; Irp->IoStatus.Information = FILE_CREATED;
/* FIXME set size if AllocationSize requested */ /* FIXME set size if AllocationSize requested */
@ -677,7 +692,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
Cluster = pFcb->entry.FirstCluster; Cluster = pFcb->entry.FirstCluster;
pFcb->entry.FirstCluster = 0; pFcb->entry.FirstCluster = 0;
pFcb->entry.FirstClusterHigh = 0; pFcb->entry.FirstClusterHigh = 0;
updEntry (DeviceExt, FileObject); // updEntry (DeviceExt, FileObject);
while (Cluster != 0xffffffff && Cluster > 1) while (Cluster != 0xffffffff && Cluster > 1)
{ {
NextCluster = GetNextCluster (DeviceExt, Cluster); NextCluster = GetNextCluster (DeviceExt, Cluster);

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.14 2000/12/29 23:17:12 dwelch Exp $ /* $Id: dirwr.c,v 1.15 2001/01/01 04:42:11 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,7 +19,7 @@
#include "vfat.h" #include "vfat.h"
#if 0
/* /*
* Copies a file name into a directory slot (long file name entry) * Copies a file name into a directory slot (long file name entry)
* and fills trailing slot space with 0xFFFF. This keeps scandisk * and fills trailing slot space with 0xFFFF. This keeps scandisk
@ -458,5 +458,6 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
DPRINT ("addentry ok\n"); DPRINT ("addentry ok\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#endif
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: iface.c,v 1.45 2000/12/29 23:17:12 dwelch Exp $ /* $Id: iface.c,v 1.46 2001/01/01 04:42:11 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -92,6 +92,19 @@ VfatMountDevice (PDEVICE_EXTENSION DeviceExt, PDEVICE_OBJECT DeviceToMount)
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
DeviceExt->Boot->BytesPerSector; DeviceExt->Boot->BytesPerSector;
if (DeviceExt->BytesPerCluster >= PAGESIZE &&
(DeviceExt->BytesPerCluster % PAGESIZE) != 0)
{
DbgPrint("Invalid cluster size\n");
KeBugCheck(0);
}
else if (DeviceExt->BytesPerCluster < PAGESIZE &&
(PAGESIZE % DeviceExt->BytesPerCluster) != 0)
{
DbgPrint("Invalid cluster size2\n");
KeBugCheck(0);
}
if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0) if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
{ {
DeviceExt->FatType = FAT12; DeviceExt->FatType = FAT12;

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.24 2000/12/29 13:45:01 ekohl Exp $ # $Id: makefile,v 1.25 2001/01/01 04:42:12 dwelch Exp $
# #
# #
PATH_TO_TOP = ../../.. PATH_TO_TOP = ../../..
@ -9,7 +9,7 @@ OBJECTS = blockdev.o close.o create.o dir.o dirwr.o iface.o string.o fat.o \
rw.o finfo.o volume.o shutdown.o $(TARGET).coff rw.o finfo.o volume.o shutdown.o $(TARGET).coff
LIBS = ../../../ntoskrnl/ntoskrnl.a LIBS = ../../../ntoskrnl/ntoskrnl.a
CFLAGS = CFLAGS = -g
all: $(TARGET).nostrip.sys $(TARGET).sys all: $(TARGET).nostrip.sys $(TARGET).sys

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.12 2000/12/29 23:17:12 dwelch Exp $ /* $Id: rw.c,v 1.13 2001/01/01 04:42:12 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,11 +19,42 @@
#include "vfat.h" #include "vfat.h"
/* FUNCTIONS ****************************************************************/ /* GLOBALS *******************************************************************/
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
/* FUNCTIONS *****************************************************************/
ULONG
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
ULONG FileOffset)
{
ULONG CurrentCluster;
ULONG i;
CurrentCluster = FirstCluster;
if (FirstCluster == 1)
{
/* root of FAT16 or FAT12 */
CurrentCluster = DeviceExt->rootStart + FileOffset
/ (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
}
else
{
for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
{
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
}
}
return(CurrentCluster);
}
NTSTATUS NTSTATUS
VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, VfatReadFileNoCache (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG ReadOffset, PULONG LengthRead) PVOID Buffer, ULONG Length, ULONG ReadOffset,
PULONG LengthRead)
/* /*
* FUNCTION: Reads data from a file * FUNCTION: Reads data from a file
*/ */
@ -45,15 +76,21 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
"Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer, "Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer,
Length, ReadOffset); Length, ReadOffset);
Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb; Fcb = ((PVFATCCB)FileObject->FsContext2)->pFcb;
/*
* Find the first cluster
*/
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster CurrentCluster = Fcb->entry.FirstCluster
+ Fcb->entry.FirstClusterHigh * 65536; + Fcb->entry.FirstClusterHigh * 65536;
else else
CurrentCluster = Fcb->entry.FirstCluster; CurrentCluster = Fcb->entry.FirstCluster;
FirstCluster = CurrentCluster; FirstCluster = CurrentCluster;
DPRINT ("DeviceExt->BytesPerCluster %x\n", DeviceExt->BytesPerCluster);
/*
* Truncate the read if necessary
*/
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{ {
if (ReadOffset >= Fcb->entry.FileSize) if (ReadOffset >= Fcb->entry.FileSize)
@ -65,14 +102,25 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Length = Fcb->entry.FileSize - ReadOffset; Length = Fcb->entry.FileSize - ReadOffset;
} }
} }
CHECKPOINT;
*LengthRead = 0; *LengthRead = 0;
/* FIXME: optimize by remembering the last cluster read and using if possible */
/*
* Allocate a buffer to hold partial clusters
*/
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster); Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
if (!Temp) if (!Temp)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
/*
* Find the cluster to start the read from
* FIXME: Optimize by remembering the last cluster read and using if
* possible.
*/
if (FirstCluster == 1) if (FirstCluster == 1)
{ //root of FAT16 or FAT12 {
/* root of FAT16 or FAT12 */
CurrentCluster = DeviceExt->rootStart + ReadOffset CurrentCluster = DeviceExt->rootStart + ReadOffset
/ (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster; / (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
} }
@ -82,7 +130,11 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
{ {
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
} }
CHECKPOINT;
/*
* If the read doesn't begin on a cluster boundary then read a full
* cluster and copy it.
*/
if ((ReadOffset % DeviceExt->BytesPerCluster) != 0) if ((ReadOffset % DeviceExt->BytesPerCluster) != 0)
{ {
if (FirstCluster == 1) if (FirstCluster == 1)
@ -154,6 +206,270 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return (STATUS_SUCCESS); return (STATUS_SUCCESS);
} }
NTSTATUS
VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PULONG CurrentCluster,
PVOID Destination)
{
if (FirstCluster == 1)
{
VFATReadSectors (DeviceExt->StorageDevice,
(*CurrentCluster),
DeviceExt->Boot->SectorsPerCluster,
Destination);
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATLoadCluster (DeviceExt, Destination, (*CurrentCluster));
(*CurrentCluster) = GetNextCluster (DeviceExt, (*CurrentCluster));
}
return(STATUS_SUCCESS);
}
NTSTATUS
VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG StartOffset,
ULONG FirstCluster,
PULONG CurrentCluster,
PVOID Destination,
ULONG Cached)
{
ULONG BytesPerCluster;
BOOLEAN Valid;
PVOID BaseAddress;
PCACHE_SEGMENT CacheSeg;
NTSTATUS Status;
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
if (BytesPerCluster >= PAGESIZE)
{
/*
* In this case the size of a cache segment is the same as a cluster
*/
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
StartOffset,
&BaseAddress,
&Valid,
&CacheSeg);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!Valid)
{
/*
* If necessary read the cluster from the disk
*/
Status = VfatRawReadCluster(DeviceExt, FirstCluster, CurrentCluster,
BaseAddress);
if (!NT_SUCCESS(Status))
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
return(Status);
}
}
else
{
/*
* Otherwise go on to the next cluster
*/
if (FirstCluster == 1)
{
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
}
else
{
(*CurrentCluster) = GetNextCluster(DeviceExt, (*CurrentCluster));
}
}
/*
* Copy the data from the cache to the caller
*/
memcpy(Destination, BaseAddress, BytesPerCluster);
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
}
else
{
ULONG i;
ULONG ReadOffset;
ULONG InternalOffset;
ReadOffset = ROUND_DOWN(StartOffset, PAGESIZE);
InternalOffset = StartOffset % PAGESIZE;
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
ReadOffset,
&BaseAddress,
&Valid,
&CacheSeg);
if (!NT_SUCCESS(Status))
{
return(Status);
}
/*
* If necessary read all the data for the page
*/
if (!Valid)
{
ULONG StartCluster;
StartCluster = OffsetToCluster(DeviceExt, FirstCluster, ReadOffset);
for (i = 0; i < (PAGESIZE / BytesPerCluster); i++)
{
Status = VfatRawReadCluster(DeviceExt,
FirstCluster,
&StartCluster,
BaseAddress + (i * BytesPerCluster));
if (!NT_SUCCESS(Status))
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
return(Status);
}
}
}
/*
* Go on to the next cluster
*/
if (FirstCluster == 1)
{
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
}
else
{
(*CurrentCluster) = GetNextCluster(DeviceExt, (*CurrentCluster));
}
/*
* Copy the data from the cache to the caller
*/
memcpy(Destination, BaseAddress + InternalOffset, BytesPerCluster);
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
}
return(STATUS_SUCCESS);
}
NTSTATUS
VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG ReadOffset,
PULONG LengthRead)
/*
* FUNCTION: Reads data from a file
*/
{
ULONG CurrentCluster;
ULONG FileOffset;
ULONG FirstCluster;
PVFATFCB Fcb;
PVOID Temp;
ULONG TempLength;
/* PRECONDITION */
assert (DeviceExt != NULL);
assert (DeviceExt->BytesPerCluster != 0);
assert (FileObject != NULL);
assert (FileObject->FsContext != NULL);
DPRINT ("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer,
Length, ReadOffset);
Fcb = ((PVFATCCB)FileObject->FsContext2)->pFcb;
/*
* Find the first cluster
*/
if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster
+ Fcb->entry.FirstClusterHigh * 65536;
else
CurrentCluster = Fcb->entry.FirstCluster;
FirstCluster = CurrentCluster;
/*
* Truncate the read if necessary
*/
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
if (ReadOffset >= Fcb->entry.FileSize)
{
return (STATUS_END_OF_FILE);
}
if ((ReadOffset + Length) > Fcb->entry.FileSize)
{
Length = Fcb->entry.FileSize - ReadOffset;
}
}
*LengthRead = 0;
/*
* Allocate a buffer to hold partial clusters
*/
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
if (!Temp)
return STATUS_UNSUCCESSFUL;
/*
* Find the cluster to start the read from
* FIXME: Optimize by remembering the last cluster read and using if
* possible.
*/
CurrentCluster = OffsetToCluster(DeviceExt, FirstCluster, ReadOffset);
/*
* If the read doesn't begin on a cluster boundary then read a full
* cluster and copy it.
*/
if ((ReadOffset % DeviceExt->BytesPerCluster) != 0)
{
VfatReadCluster(DeviceExt, Fcb,
ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster),
FirstCluster, &CurrentCluster, Temp, 1);
TempLength = min (Length, DeviceExt->BytesPerCluster -
(ReadOffset % DeviceExt->BytesPerCluster));
memcpy (Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
TempLength);
(*LengthRead) = (*LengthRead) + TempLength;
Length = Length - TempLength;
Buffer = Buffer + TempLength;
ReadOffset = ReadOffset + TempLength;
}
while (Length >= DeviceExt->BytesPerCluster)
{
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
FirstCluster, &CurrentCluster, Buffer, 1);
if (CurrentCluster == 0xffffffff)
{
ExFreePool (Temp);
return (STATUS_SUCCESS);
}
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
Buffer = Buffer + DeviceExt->BytesPerCluster;
Length = Length - DeviceExt->BytesPerCluster;
ReadOffset = ReadOffset + DeviceExt->BytesPerCluster;
}
if (Length > 0)
{
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
FirstCluster, &CurrentCluster, Temp, 1);
(*LengthRead) = (*LengthRead) + Length;
memcpy (Buffer, Temp, Length);
}
ExFreePool (Temp);
return (STATUS_SUCCESS);
}
#if 0
NTSTATUS NTSTATUS
VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG WriteOffset) PVOID Buffer, ULONG Length, ULONG WriteOffset)
@ -361,6 +677,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
ExFreePool (Temp); ExFreePool (Temp);
return (STATUS_SUCCESS); return (STATUS_SUCCESS);
} }
#endif
NTSTATUS STDCALL NTSTATUS STDCALL
VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp) VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
@ -382,7 +699,8 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart; Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset); /* Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset); */
Status = STATUS_MEDIA_WRITE_PROTECTED;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length; Irp->IoStatus.Information = Length;

View file

@ -1,25 +1,14 @@
#ifndef __INCLUDE_DDK_NTIFS_H #ifndef __INCLUDE_DDK_NTIFS_H
#define __INCLUDE_DDK_NTIFS_H #define __INCLUDE_DDK_NTIFS_H
#if 0
typedef struct
{
BOOLEAN Replace;
HANDLE RootDir;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
#endif
typedef struct _BCB typedef struct _BCB
{ {
LIST_ENTRY CacheSegmentListHead; LIST_ENTRY CacheSegmentListHead;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
KSPIN_LOCK BcbLock; KSPIN_LOCK BcbLock;
ULONG CacheSegmentSize;
} BCB, *PBCB; } BCB, *PBCB;
#define CACHE_SEGMENT_SIZE (0x1000)
struct _MEMORY_AREA; struct _MEMORY_AREA;
typedef struct _CACHE_SEGMENT typedef struct _CACHE_SEGMENT
@ -35,20 +24,21 @@ typedef struct _CACHE_SEGMENT
} CACHE_SEGMENT, *PCACHE_SEGMENT; } CACHE_SEGMENT, *PCACHE_SEGMENT;
NTSTATUS STDCALL NTSTATUS STDCALL
CcFlushCachePage (PCACHE_SEGMENT CacheSeg); CcFlushCacheSegment (PCACHE_SEGMENT CacheSeg);
NTSTATUS STDCALL NTSTATUS STDCALL
CcReleaseCachePage (PBCB Bcb, CcReleaseCacheSegment (PBCB Bcb,
PCACHE_SEGMENT CacheSeg, PCACHE_SEGMENT CacheSeg,
BOOLEAN Valid); BOOLEAN Valid);
NTSTATUS STDCALL NTSTATUS STDCALL
CcRequestCachePage (PBCB Bcb, CcRequestCacheSegment (PBCB Bcb,
ULONG FileOffset, ULONG FileOffset,
PVOID* BaseAddress, PVOID* BaseAddress,
PBOOLEAN UptoDate, PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg); PCACHE_SEGMENT* CacheSeg);
NTSTATUS STDCALL NTSTATUS STDCALL
CcInitializeFileCache (PFILE_OBJECT FileObject, CcInitializeFileCache (PFILE_OBJECT FileObject,
PBCB* Bcb); PBCB* Bcb,
ULONG CacheSegmentSize);
NTSTATUS STDCALL NTSTATUS STDCALL
CcReleaseFileCache (PFILE_OBJECT FileObject, CcReleaseFileCache (PFILE_OBJECT FileObject,
PBCB Bcb); PBCB Bcb);

View file

@ -1,3 +1,4 @@
/* /*
* ReactOS kernel * ReactOS kernel
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net> * Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>
@ -16,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: view.c,v 1.12 2000/12/23 02:37:38 dwelch Exp $ /* $Id: view.c,v 1.13 2001/01/01 04:42:11 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -59,10 +60,15 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS *******************************************************************/
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#define ROUND_DOWN(N, S) (ROUND_UP(N, S) - S)
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL NTSTATUS STDCALL
CcFlushCachePage(PCACHE_SEGMENT CacheSeg) CcFlushCacheSegment(PCACHE_SEGMENT CacheSeg)
/* /*
* FUNCTION: Asks the FSD to flush the contents of the page back to disk * FUNCTION: Asks the FSD to flush the contents of the page back to disk
*/ */
@ -78,7 +84,7 @@ CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
} }
NTSTATUS STDCALL NTSTATUS STDCALL
CcReleaseCachePage(PBCB Bcb, CcReleaseCacheSegment(PBCB Bcb,
PCACHE_SEGMENT CacheSeg, PCACHE_SEGMENT CacheSeg,
BOOLEAN Valid) BOOLEAN Valid)
{ {
@ -95,7 +101,7 @@ CcReleaseCachePage(PBCB Bcb,
} }
NTSTATUS STDCALL NTSTATUS STDCALL
CcRequestCachePage(PBCB Bcb, CcRequestCacheSegment(PBCB Bcb,
ULONG FileOffset, ULONG FileOffset,
PVOID* BaseAddress, PVOID* BaseAddress,
PBOOLEAN UptoDate, PBOOLEAN UptoDate,
@ -107,6 +113,12 @@ CcRequestCachePage(PBCB Bcb,
KIRQL oldirql; KIRQL oldirql;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PCACHE_SEGMENT current; PCACHE_SEGMENT current;
ULONG i;
if ((FileOffset % Bcb->CacheSegmentSize) != 0)
{
KeBugCheck(0);
}
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, " DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
"UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress, "UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
@ -118,7 +130,7 @@ CcRequestCachePage(PBCB Bcb,
while (current_entry != &Bcb->CacheSegmentListHead) while (current_entry != &Bcb->CacheSegmentListHead)
{ {
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset)) if (current->FileOffset == FileOffset)
{ {
DPRINT("Found existing segment at %x\n", current); DPRINT("Found existing segment at %x\n", current);
current->ReferenceCount++; current->ReferenceCount++;
@ -145,14 +157,14 @@ CcRequestCachePage(PBCB Bcb,
current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT)); current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT));
current->BaseAddress = NULL; current->BaseAddress = NULL;
MmCreateMemoryArea(KernelMode, MmCreateMemoryArea(KernelMode,
NULL, MmGetKernelAddressSpace(),
MEMORY_AREA_CACHE_SEGMENT, MEMORY_AREA_CACHE_SEGMENT,
&current->BaseAddress, &current->BaseAddress,
CACHE_SEGMENT_SIZE, Bcb->CacheSegmentSize,
PAGE_READWRITE, PAGE_READWRITE,
(PMEMORY_AREA*)&current->MemoryArea); (PMEMORY_AREA*)&current->MemoryArea);
current->Valid = FALSE; current->Valid = FALSE;
current->FileOffset = PAGE_ROUND_DOWN(FileOffset); current->FileOffset = FileOffset;
current->Bcb = Bcb; current->Bcb = Bcb;
KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
current->ReferenceCount = 1; current->ReferenceCount = 1;
@ -160,10 +172,13 @@ CcRequestCachePage(PBCB Bcb,
*UptoDate = current->Valid; *UptoDate = current->Valid;
*BaseAddress = current->BaseAddress; *BaseAddress = current->BaseAddress;
*CacheSeg = current; *CacheSeg = current;
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
{
MmCreateVirtualMapping(NULL, MmCreateVirtualMapping(NULL,
current->BaseAddress, current->BaseAddress + (i * PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)MmAllocPage(0)); (ULONG)MmAllocPage(0));
}
DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress); DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
@ -180,7 +195,7 @@ CcFreeCacheSegment(PBCB Bcb,
{ {
MmFreeMemoryArea(NULL, MmFreeMemoryArea(NULL,
CacheSeg->BaseAddress, CacheSeg->BaseAddress,
CACHE_SEGMENT_SIZE, Bcb->CacheSegmentSize,
TRUE); TRUE);
ExFreePool(CacheSeg); ExFreePool(CacheSeg);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -217,7 +232,8 @@ CcReleaseFileCache(PFILE_OBJECT FileObject,
NTSTATUS STDCALL NTSTATUS STDCALL
CcInitializeFileCache(PFILE_OBJECT FileObject, CcInitializeFileCache(PFILE_OBJECT FileObject,
PBCB* Bcb) PBCB* Bcb,
ULONG CacheSegmentSize)
/* /*
* FUNCTION: Initializes a BCB for a file object * FUNCTION: Initializes a BCB for a file object
*/ */
@ -233,6 +249,7 @@ CcInitializeFileCache(PFILE_OBJECT FileObject,
(*Bcb)->FileObject = FileObject; (*Bcb)->FileObject = FileObject;
InitializeListHead(&(*Bcb)->CacheSegmentListHead); InitializeListHead(&(*Bcb)->CacheSegmentListHead);
KeInitializeSpinLock(&(*Bcb)->BcbLock); KeInitializeSpinLock(&(*Bcb)->BcbLock);
(*Bcb)->CacheSegmentSize = CacheSegmentSize;
DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb); DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb);

View file

@ -1,14 +1,14 @@
; $Id: ntoskrnl.def,v 1.91 2000/12/30 01:41:52 ekohl Exp $ ; $Id: ntoskrnl.def,v 1.92 2001/01/01 04:42:11 dwelch Exp $
; ;
; reactos/ntoskrnl/ntoskrnl.def ; reactos/ntoskrnl/ntoskrnl.def
; ;
; ReactOS Operating System ; ReactOS Operating System
; ;
EXPORTS EXPORTS
CcInitializeFileCache@8 CcInitializeFileCache@12
CcMdlReadComplete@8 CcMdlReadComplete@8
CcRequestCachePage@20 CcRequestCacheSegment@20
CcReleaseCachePage@12 CcReleaseCacheSegment@12
CcReleaseFileCache@8 CcReleaseFileCache@8
DbgBreakPoint@0 DbgBreakPoint@0
DbgBreakPointWithStatus@4 DbgBreakPointWithStatus@4

View file

@ -1,14 +1,14 @@
; $Id: ntoskrnl.edf,v 1.78 2000/12/30 01:41:52 ekohl Exp $ ; $Id: ntoskrnl.edf,v 1.79 2001/01/01 04:42:11 dwelch Exp $
; ;
; reactos/ntoskrnl/ntoskrnl.def ; reactos/ntoskrnl/ntoskrnl.def
; ;
; ReactOS Operating System ; ReactOS Operating System
; ;
EXPORTS EXPORTS
CcInitializeFileCache=CcInitializeFileCache@8 CcInitializeFileCache=CcInitializeFileCache@12
CcMdlReadComplete=CcMdlReadComplete@8 CcMdlReadComplete=CcMdlReadComplete@8
CcRequestCachePage=CcRequestCachePage@20 CcRequestCacheSegment=CcRequestCacheSegment@20
CcReleaseCachePage=CcReleaseCachePage@12 CcReleaseCacheSegment=CcReleaseCacheSegment@12
CcReleaseFileCache=CcReleaseFileCache@8 CcReleaseFileCache=CcReleaseFileCache@8
DbgBreakPoint=DbgBreakPoint@0 DbgBreakPoint=DbgBreakPoint@0
DbgBreakPointWithStatus=DbgBreakPointWithStatus@4 DbgBreakPointWithStatus=DbgBreakPointWithStatus@4