[FORMATTING]

* Addendum to r56262.

svn path=/trunk/; revision=56273
This commit is contained in:
Amine Khaldi 2012-03-29 12:14:58 +00:00
parent 4d61c55638
commit aabb4465a0
13 changed files with 1259 additions and 1151 deletions

View file

@ -19,10 +19,10 @@
typedef struct _WORK_QUEUE_WITH_READ_AHEAD
{
WORK_QUEUE_ITEM WorkItem;
PFILE_OBJECT FileObject;
LARGE_INTEGER FileOffset;
ULONG Length;
WORK_QUEUE_ITEM WorkItem;
PFILE_OBJECT FileObject;
LARGE_INTEGER FileOffset;
ULONG Length;
} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
/* FUNCTIONS ******************************************************************/
@ -37,52 +37,54 @@ CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
IN ULONG Granularity)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
if (Map)
{
Map->ReadAheadGranularity = Granularity;
}
if (Map)
{
Map->ReadAheadGranularity = Granularity;
}
}
VOID
NTAPI
CcpReadAhead(PVOID Context)
{
LARGE_INTEGER Offset;
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
WorkItem->FileOffset.HighPart,
WorkItem->FileOffset.LowPart,
WorkItem->Length,
&WorkItem->FileObject->FileName);
Offset.HighPart = WorkItem->FileOffset.HighPart;
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
if (Map)
{
PLIST_ENTRY ListEntry;
volatile char *chptr;
PNOCC_BCB Bcb;
for (ListEntry = Map->AssociatedBcb.Flink;
ListEntry != &Map->AssociatedBcb;
ListEntry = ListEntry->Flink)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
continue;
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
Offset.QuadPart <
WorkItem->FileOffset.QuadPart + WorkItem->Length;
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
{
*chptr ^= 0;
}
}
}
ObDereferenceObject(WorkItem->FileObject);
ExFreePool(WorkItem);
DPRINT("Done\n");
LARGE_INTEGER Offset;
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
WorkItem->FileOffset.HighPart,
WorkItem->FileOffset.LowPart,
WorkItem->Length,
&WorkItem->FileObject->FileName);
Offset.HighPart = WorkItem->FileOffset.HighPart;
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
if (Map)
{
PLIST_ENTRY ListEntry;
volatile char *chptr;
PNOCC_BCB Bcb;
for (ListEntry = Map->AssociatedBcb.Flink;
ListEntry != &Map->AssociatedBcb;
ListEntry = ListEntry->Flink)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
continue;
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
Offset.QuadPart <
WorkItem->FileOffset.QuadPart + WorkItem->Length;
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
{
*chptr ^= 0;
}
}
}
ObDereferenceObject(WorkItem->FileObject);
ExFreePool(WorkItem);
DPRINT("Done\n");
}
VOID
@ -91,30 +93,36 @@ CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length)
{
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
FileOffset->HighPart,
FileOffset->LowPart,
Length,
&FileObject->FileName);
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
if (!WorkItem) KeBugCheck(0);
ObReferenceObject(FileObject);
WorkItem->FileObject = FileObject;
WorkItem->FileOffset = *FileOffset;
WorkItem->Length = Length;
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem);
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
DPRINT("Done\n");
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
FileOffset->HighPart,
FileOffset->LowPart,
Length,
&FileObject->FileName);
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
if (!WorkItem) KeBugCheck(0);
ObReferenceObject(FileObject);
WorkItem->FileObject = FileObject;
WorkItem->FileOffset = *FileOffset;
WorkItem->Length = Length;
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem),
(PWORKER_THREAD_ROUTINE)CcpReadAhead,
WorkItem);
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
DPRINT("Done\n");
}
VOID
NTAPI
CcSetDirtyPinnedData(IN PVOID BcbVoid,
IN OPTIONAL PLARGE_INTEGER Lsn)
{
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
Bcb->Dirty = TRUE;
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
Bcb->Dirty = TRUE;
}
LARGE_INTEGER
@ -128,80 +136,84 @@ CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
return Result;
}
VOID
NTAPI
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
BOOLEAN Delete,
const char *File,
int Line)
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
BOOLEAN Delete,
const char *File,
int Line)
{
PNOCC_BCB Bcb = NULL;
LARGE_INTEGER LowerBound, UpperBound;
PLIST_ENTRY ListEntry;
IO_STATUS_BLOCK IOSB;
LARGE_INTEGER LowerBound, UpperBound;
PLIST_ENTRY ListEntry;
IO_STATUS_BLOCK IOSB;
RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK));
RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK));
DPRINT("CcFlushCache (while file) (%s:%d)\n", File, Line);
DPRINT("CcFlushCache (while file) (%s:%d)\n", File, Line);
if (FileOffset && Length)
{
LowerBound.QuadPart = FileOffset->QuadPart;
UpperBound.QuadPart = LowerBound.QuadPart + Length;
}
else
{
LowerBound.QuadPart = 0;
UpperBound.QuadPart = 0x7fffffffffffffffull;
}
if (FileOffset && Length)
{
LowerBound.QuadPart = FileOffset->QuadPart;
UpperBound.QuadPart = LowerBound.QuadPart + Length;
}
else
{
LowerBound.QuadPart = 0;
UpperBound.QuadPart = 0x7fffffffffffffffull;
}
CcpLock();
ListEntry = Map->AssociatedBcb.Flink;
CcpLock();
ListEntry = Map->AssociatedBcb.Flink;
while (ListEntry != &Map->AssociatedBcb)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
while (ListEntry != &Map->AssociatedBcb)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT
("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
Bcb->RefCount++;
CcpUnlock();
MiFlushMappedSection(Bcb->BaseAddress, &Bcb->FileOffset, &Map->FileSizes.FileSize, Bcb->Dirty);
CcpLock();
Bcb->RefCount--;
Bcb->RefCount++;
CcpUnlock();
MiFlushMappedSection(Bcb->BaseAddress,
&Bcb->FileOffset,
&Map->FileSizes.FileSize,
Bcb->Dirty);
CcpLock();
Bcb->RefCount--;
Bcb->Dirty = FALSE;
Bcb->Dirty = FALSE;
ListEntry = ListEntry->Flink;
if (Delete && Bcb->RefCount < 2)
{
Bcb->RefCount = 1;
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
}
else
CcpUnpinData(Bcb, TRUE);
}
else
{
ListEntry = ListEntry->Flink;
CcpUnpinData(Bcb, TRUE);
}
ListEntry = ListEntry->Flink;
if (Delete && Bcb->RefCount < 2)
{
Bcb->RefCount = 1;
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
}
else
{
CcpUnpinData(Bcb, TRUE);
}
}
else
{
ListEntry = ListEntry->Flink;
CcpUnpinData(Bcb, TRUE);
}
DPRINT("End loop\n");
}
CcpUnlock();
DPRINT("End loop\n");
}
CcpUnlock();
if (IoStatus) *IoStatus = IOSB;
}
@ -215,25 +227,24 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
// Not cached
if (!Map)
{
if (IoStatus)
{
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = 0;
}
return;
}
/* Not cached */
if (!Map)
{
if (IoStatus)
{
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = 0;
}
return;
}
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
}
BOOLEAN
NTAPI
CcFlushImageSection
(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType)
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
PNOCC_BCB Bcb;
@ -241,93 +252,91 @@ CcFlushImageSection
IO_STATUS_BLOCK IOSB;
BOOLEAN Result = TRUE;
if (!Map) return TRUE;
if (!Map) return TRUE;
for (Entry = Map->AssociatedBcb.Flink;
Entry != &Map->AssociatedBcb;
Entry = Entry->Flink)
Entry != &Map->AssociatedBcb;
Entry = Entry->Flink)
{
Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
if (!Bcb->Dirty) continue;
if (!Bcb->Dirty) continue;
switch (FlushType)
{
case MmFlushForDelete:
CcPurgeCacheSection
(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
FALSE);
break;
case MmFlushForWrite:
CcFlushCache
(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
&IOSB);
break;
}
switch (FlushType)
{
case MmFlushForDelete:
CcPurgeCacheSection(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
FALSE);
break;
case MmFlushForWrite:
CcFlushCache(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
&IOSB);
break;
}
}
return Result;
}
// Always succeeds for us
/* Always succeeds for us */
PVOID
NTAPI
CcRemapBcb(IN PVOID Bcb)
{
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
CcpLock();
ASSERT(RtlTestBit(CcCacheBitmap, Number));
CcpReferenceCache(Number);
CcpUnlock();
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
CcpLock();
ASSERT(RtlTestBit(CcCacheBitmap, Number));
CcpReferenceCache(Number);
CcpUnlock();
return Bcb;
}
VOID
NTAPI
CcShutdownSystem()
CcShutdownSystem(VOID)
{
ULONG i, Result;
NTSTATUS Status;
ULONG i, Result;
NTSTATUS Status;
DPRINT1("CC: Shutdown\n");
DPRINT1("CC: Shutdown\n");
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
PNOCC_BCB Bcb = &CcCacheSections[i];
if (Bcb->SectionObject)
{
DPRINT1
("Evicting #%02x %08x%08x %wZ\n",
i,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart,
&MmGetFileObjectForSection
((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
Bcb->Dirty = FALSE;
}
}
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
PNOCC_BCB Bcb = &CcCacheSections[i];
if (Bcb->SectionObject)
{
DPRINT1("Evicting #%02x %08x%08x %wZ\n",
i,
Bcb->FileOffset.u.HighPart,
Bcb->FileOffset.u.LowPart,
&MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
// Evict all section pages
Status = MiRosTrimCache(~0, 0, &Result);
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
Bcb->Dirty = FALSE;
}
}
DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
/* Evict all section pages */
Status = MiRosTrimCache(~0, 0, &Result);
DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
}
VOID
NTAPI
CcRepinBcb(IN PVOID Bcb)
{
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
CcpLock();
ASSERT(RtlTestBit(CcCacheBitmap, Number));
DPRINT("CcRepinBcb(#%x)\n", Number);
CcpReferenceCache(Number);
CcpUnlock();
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
CcpLock();
ASSERT(RtlTestBit(CcCacheBitmap, Number));
DPRINT("CcRepinBcb(#%x)\n", Number);
CcpReferenceCache(Number);
CcpUnlock();
}
VOID
@ -340,13 +349,13 @@ CcUnpinRepinnedBcb(IN PVOID Bcb,
if (WriteThrough)
{
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
CcpFlushCache
(RealBcb->Map,
&RealBcb->FileOffset,
RealBcb->Length,
IoStatus, RealBcb->Dirty);
CcpFlushCache(RealBcb->Map,
&RealBcb->FileOffset,
RealBcb->Length,
IoStatus,
RealBcb->Dirty);
}
CcUnpinData(Bcb);

View file

@ -53,53 +53,55 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
PCHAR BufferTarget = (PCHAR)Buffer;
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
DPRINT
("CcCopyRead(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
Wait,
Buffer);
DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
Wait,
Buffer);
CacheOffset.QuadPart = FileOffset->QuadPart;
EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
{
NextOffset.QuadPart = CacheOffset.QuadPart;
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
{
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
}
NextOffset.QuadPart = CacheOffset.QuadPart;
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
{
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
}
DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
ReadLen,
CacheOffset.HighPart,
CacheOffset.LowPart);
if (!CcPinRead
(FileObject,
&CacheOffset,
ReadLen,
Wait ? PIN_WAIT : PIN_IF_BCB,
&Bcb,
(PVOID*)&ReadBuffer))
{
IoStatus->Status = STATUS_UNSUCCESSFUL;
IoStatus->Information = 0;
DPRINT("Failed CcCopyRead\n");
return FALSE;
}
if (!CcPinRead(FileObject,
&CacheOffset,
ReadLen,
Wait ? PIN_WAIT : PIN_IF_BCB,
&Bcb,
(PVOID*)&ReadBuffer))
{
IoStatus->Status = STATUS_UNSUCCESSFUL;
IoStatus->Information = 0;
DPRINT("Failed CcCopyRead\n");
return FALSE;
}
DPRINT("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
RtlCopyMemory
(BufferTarget,
ReadBuffer,
ReadLen);
DPRINT("Copying %d bytes at %08x%08x\n",
ReadLen,
CacheOffset.HighPart,
CacheOffset.LowPart);
BufferTarget += ReadLen;
RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
CacheOffset = NextOffset;
CcUnpinData(Bcb);
BufferTarget += ReadLen;
CacheOffset = NextOffset;
CcUnpinData(Bcb);
}
IoStatus->Status = STATUS_SUCCESS;
@ -131,58 +133,72 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID Buffer)
{
INT Count = 0;
BOOLEAN Result;
PNOCC_BCB Bcb;
PVOID WriteBuf;
ULONG WriteLen;
LARGE_INTEGER CurrentOffset = *FileOffset;
LARGE_INTEGER EndOffset;
LARGE_INTEGER NextOffset;
INT Count = 0;
BOOLEAN Result;
PNOCC_BCB Bcb;
PVOID WriteBuf;
ULONG WriteLen;
LARGE_INTEGER CurrentOffset = *FileOffset;
LARGE_INTEGER EndOffset;
LARGE_INTEGER NextOffset;
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
DPRINT
("CcCopyWrite(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
Wait,
Buffer);
DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
Wait,
Buffer);
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
{
NextOffset.HighPart = CurrentOffset.HighPart;
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
DPRINT("Copying %x bytes from %08x%08x\n",
WriteLen,
CurrentOffset.u.HighPart, CurrentOffset.u.LowPart);
DPRINT("CcPreparePinWrite\n");
Result = CcPreparePinWrite
(FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB,
(PVOID *)&Bcb, &WriteBuf);
DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
if (!Result)
{
DPRINT1("CcPreparePinWrite Failed?\n");
if (Wait) RtlRaiseStatus(STATUS_NOT_MAPPED_DATA); else return FALSE;
}
DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n", Bcb - CcCacheSections, WriteBuf, Bcb->BaseAddress);
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
{
NextOffset.HighPart = CurrentOffset.HighPart;
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
//MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
Count += WriteLen;
Length -= WriteLen;
CurrentOffset = NextOffset;
Bcb->Dirty = TRUE;
CcUnpinData(Bcb);
}
DPRINT("Copying %x bytes from %08x%08x\n",
WriteLen,
CurrentOffset.u.HighPart,
CurrentOffset.u.LowPart);
DPRINT("Done with CcCopyWrite\n");
DPRINT("CcPreparePinWrite\n");
return TRUE;
Result = CcPreparePinWrite(FileObject,
&CurrentOffset,
WriteLen,
FALSE,
Wait ? PIN_WAIT : PIN_IF_BCB,
(PVOID *)&Bcb, &WriteBuf);
DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
if (!Result)
{
DPRINT1("CcPreparePinWrite Failed?\n");
if (Wait)
RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
else
return FALSE;
}
DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
Bcb - CcCacheSections,
WriteBuf,
Bcb->BaseAddress);
//MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
Count += WriteLen;
Length -= WriteLen;
CurrentOffset = NextOffset;
Bcb->Dirty = TRUE;
CcUnpinData(Bcb);
}
DPRINT("Done with CcCopyWrite\n");
return TRUE;
}
VOID

View file

@ -68,9 +68,9 @@ what shared cache map it associates with.
*/
typedef struct _NOCC_PRIVATE_CACHE_MAP
{
LIST_ENTRY ListEntry;
PFILE_OBJECT FileObject;
PNOCC_CACHE_MAP Map;
LIST_ENTRY ListEntry;
PFILE_OBJECT FileObject;
PNOCC_CACHE_MAP Map;
} NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
LIST_ENTRY CcpAllSharedCacheMaps;
@ -81,25 +81,28 @@ BOOLEAN
NTAPI
CcInitializeCacheManager(VOID)
{
int i;
int i;
DPRINT("Initialize\n");
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
InitializeListHead(&CcCacheSections[i].ThisFileList);
}
DPRINT("Initialize\n");
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait,
SynchronizationEvent,
FALSE);
InitializeListHead(&CcpAllSharedCacheMaps);
InitializeListHead(&CcCacheSections[i].ThisFileList);
}
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
InitializeListHead(&CcpAllSharedCacheMaps);
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
ExInitializeFastMutex(&CcMutex);
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
ExInitializeFastMutex(&CcMutex);
return TRUE;
}
@ -125,16 +128,16 @@ BOOLEAN
NTAPI
CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
{
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
}
VOID
NTAPI
CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
{
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
}
/*
@ -150,37 +153,41 @@ a stream file object and a sibling file object in the file object struct
itself.
*/
// Must have CcpLock()
/* Must have CcpLock() */
PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
{
PLIST_ENTRY Entry, Private;
for (Entry = CcpAllSharedCacheMaps.Flink;
Entry != &CcpAllSharedCacheMaps;
Entry = Entry->Flink)
{
// 'Identical' test for other stream file object
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
for (Private = Map->PrivateCacheMaps.Flink;
Private != &Map->PrivateCacheMaps;
Private = Private->Flink)
{
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private, NOCC_PRIVATE_CACHE_MAP, ListEntry);
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
1)
{
return PrivateMap->FileObject;
}
}
}
return 0;
PLIST_ENTRY Entry, Private;
for (Entry = CcpAllSharedCacheMaps.Flink;
Entry != &CcpAllSharedCacheMaps;
Entry = Entry->Flink)
{
/* 'Identical' test for other stream file object */
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
for (Private = Map->PrivateCacheMaps.Flink;
Private != &Map->PrivateCacheMaps;
Private = Private->Flink)
{
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private,
NOCC_PRIVATE_CACHE_MAP,
ListEntry);
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
1)
{
return PrivateMap->FileObject;
}
}
}
return 0;
}
// Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html
/* Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */
VOID
NTAPI
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
@ -189,55 +196,64 @@ CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
IN PCACHE_MANAGER_CALLBACKS Callbacks,
IN PVOID LazyWriteContext)
{
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
CcpLock();
/* We don't have a shared cache map. First find out if we have a sibling
stream file object we can take it from. */
if (!Map && FileObject->Flags & FO_STREAM_FILE)
{
PFILE_OBJECT IdenticalStreamFileObject =
CcpFindOtherStreamFileObject(FileObject);
if (IdenticalStreamFileObject)
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
if (Map)
{
DPRINT1
("Linking SFO %x to previous SFO %x through cache map %x #\n",
FileObject, IdenticalStreamFileObject, Map);
}
}
if (!Map && FileObject->Flags & FO_STREAM_FILE)
{
PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
if (IdenticalStreamFileObject)
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
if (Map)
{
DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
FileObject,
IdenticalStreamFileObject,
Map);
}
}
/* We still don't have a shared cache map. We need to create one. */
if (!Map)
{
DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName);
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
FileObject->SectionObjectPointer->SharedCacheMap = Map;
Map->FileSizes = *FileSizes;
Map->LazyContext = LazyWriteContext;
Map->ReadAheadGranularity = PAGE_SIZE;
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
// For now ...
DPRINT("FileSizes->ValidDataLength %08x%08x\n", FileSizes->ValidDataLength.HighPart, FileSizes->ValidDataLength.LowPart);
InitializeListHead(&Map->AssociatedBcb);
InitializeListHead(&Map->PrivateCacheMaps);
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
DPRINT("New Map %x\n", Map);
DPRINT("Initializing file object for (%p) %wZ\n",
FileObject,
&FileObject->FileName);
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
FileObject->SectionObjectPointer->SharedCacheMap = Map;
Map->FileSizes = *FileSizes;
Map->LazyContext = LazyWriteContext;
Map->ReadAheadGranularity = PAGE_SIZE;
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
/* For now ... */
DPRINT("FileSizes->ValidDataLength %08x%08x\n",
FileSizes->ValidDataLength.HighPart,
FileSizes->ValidDataLength.LowPart);
InitializeListHead(&Map->AssociatedBcb);
InitializeListHead(&Map->PrivateCacheMaps);
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
DPRINT("New Map %x\n", Map);
}
/* We don't have a private cache map. Link it with the shared cache map
to serve as a held reference. When the list in the shared cache map
is empty, we know we can delete it. */
if (!PrivateCacheMap)
{
PrivateCacheMap = ExAllocatePool(NonPagedPool, sizeof(*PrivateCacheMap));
FileObject->PrivateCacheMap = PrivateCacheMap;
PrivateCacheMap->FileObject = FileObject;
ObReferenceObject(PrivateCacheMap->FileObject);
}
if (!PrivateCacheMap)
{
PrivateCacheMap = ExAllocatePool(NonPagedPool,
sizeof(*PrivateCacheMap));
PrivateCacheMap->Map = Map;
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
FileObject->PrivateCacheMap = PrivateCacheMap;
PrivateCacheMap->FileObject = FileObject;
ObReferenceObject(PrivateCacheMap->FileObject);
}
PrivateCacheMap->Map = Map;
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
CcpUnlock();
}
@ -254,12 +270,14 @@ ULONG
NTAPI
CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
{
PLIST_ENTRY Entry;
ULONG Count;
PLIST_ENTRY Entry;
ULONG Count;
for (Count = 0, Entry = Map->AssociatedBcb.Flink; Entry != &Map->AssociatedBcb; Entry = Entry->Flink, Count++);
for (Count = 0, Entry = Map->AssociatedBcb.Flink;
Entry != &Map->AssociatedBcb;
Entry = Entry->Flink, Count++);
return Count;
return Count;
}
BOOLEAN
@ -268,58 +286,62 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
IN OPTIONAL PLARGE_INTEGER TruncateSize,
IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
{
BOOLEAN LastMap = FALSE;
BOOLEAN LastMap = FALSE;
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n", &FileObject->FileName, FileObject->SectionObjectPointer);
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n",
&FileObject->FileName,
FileObject->SectionObjectPointer);
ASSERT(UninitializeEvent == NULL);
/* It may not be strictly necessary to flush here, but we do just for
kicks. */
if (Map)
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
if (Map)
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
CcpLock();
CcpLock();
/* We have a private cache map, so we've been initialized and haven't been
* uninitialized. */
if (PrivateCacheMap)
{
ASSERT(!Map || Map == PrivateCacheMap->Map);
ASSERT(PrivateCacheMap->FileObject == FileObject);
if (PrivateCacheMap)
{
ASSERT(!Map || Map == PrivateCacheMap->Map);
ASSERT(PrivateCacheMap->FileObject == FileObject);
RemoveEntryList(&PrivateCacheMap->ListEntry);
RemoveEntryList(&PrivateCacheMap->ListEntry);
/* That was the last private cache map. It's time to delete all
cache stripes and all aspects of caching on the file. */
if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
{
if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
{
/* Get rid of all the cache stripes. */
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
Bcb->RefCount = 1;
CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
}
RemoveEntryList(&PrivateCacheMap->Map->Entry);
ExFreePool(PrivateCacheMap->Map);
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
LastMap = TRUE;
}
ObDereferenceObject(PrivateCacheMap->FileObject);
FileObject->PrivateCacheMap = NULL;
ExFreePool(PrivateCacheMap);
}
CcpUnlock();
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink,
NOCC_BCB,
ThisFileList);
DPRINT("Uninit complete\n");
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
Bcb->RefCount = 1;
CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
}
RemoveEntryList(&PrivateCacheMap->Map->Entry);
ExFreePool(PrivateCacheMap->Map);
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
LastMap = TRUE;
}
ObDereferenceObject(PrivateCacheMap->FileObject);
FileObject->PrivateCacheMap = NULL;
ExFreePool(PrivateCacheMap);
}
CcpUnlock();
/* The return from CcUninitializeCacheMap means that 'caching was stopped'.
*/
DPRINT("Uninit complete\n");
/* The return from CcUninitializeCacheMap means that 'caching was stopped'. */
return LastMap;
}
/*
CcSetFileSizes is used to tell the cache manager that the file changed
@ -338,20 +360,19 @@ CcSetFileSizes(IN PFILE_OBJECT FileObject,
if (!Map) return;
Map->FileSizes = *FileSizes;
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
if (!Bcb) return;
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
if (!Bcb) return;
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
}
BOOLEAN
NTAPI
CcGetFileSizes
(IN PFILE_OBJECT FileObject,
IN PCC_FILE_SIZES FileSizes)
CcGetFileSizes(IN PFILE_OBJECT FileObject,
IN PCC_FILE_SIZES FileSizes)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
if (!Map) return FALSE;
@ -366,10 +387,10 @@ CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN ULONG Length,
IN BOOLEAN UninitializeCacheMaps)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
if (!Map) return TRUE;
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
return TRUE;
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
if (!Map) return TRUE;
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
return TRUE;
}
VOID
@ -380,7 +401,7 @@ CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
UNIMPLEMENTED;
while (TRUE);
}
/*
This could be implemented much more intelligently by mapping instances
@ -396,156 +417,212 @@ CcZeroData(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait)
{
PNOCC_BCB Bcb = NULL;
PLIST_ENTRY ListEntry = NULL;
LARGE_INTEGER LowerBound = *StartOffset;
LARGE_INTEGER UpperBound = *EndOffset;
LARGE_INTEGER Target, End;
PVOID PinnedBcb, PinnedBuffer;
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
PLIST_ENTRY ListEntry = NULL;
LARGE_INTEGER LowerBound = *StartOffset;
LARGE_INTEGER UpperBound = *EndOffset;
LARGE_INTEGER Target, End;
PVOID PinnedBcb, PinnedBuffer;
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
DPRINT
("S %08x%08x E %08x%08x\n",
StartOffset->u.HighPart, StartOffset->u.LowPart,
EndOffset->u.HighPart, EndOffset->u.LowPart);
DPRINT("S %08x%08x E %08x%08x\n",
StartOffset->u.HighPart,
StartOffset->u.LowPart,
EndOffset->u.HighPart,
EndOffset->u.LowPart);
if (!Map)
{
NTSTATUS Status;
IO_STATUS_BLOCK IOSB;
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
ULONG ToWrite;
if (!Map)
{
NTSTATUS Status;
IO_STATUS_BLOCK IOSB;
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
ULONG ToWrite;
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
// Handle leading page
if (LowerBound.QuadPart != Target.QuadPart)
{
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE,UpperBound.QuadPart-Target.QuadPart), &IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
// Handle leading page
if (LowerBound.QuadPart != Target.QuadPart)
{
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
(PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
DPRINT("Zero last half %08x%08x %x\n",
Target.u.HighPart,
Target.u.LowPart,
ToWrite);
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
{
DPRINT("Zero full page %08x%08x\n", Target.u.HighPart, Target.u.LowPart);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
Status = MiSimpleRead(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
TRUE,
&IOSB);
if (UpperBound.QuadPart > Target.QuadPart)
{
ToWrite = UpperBound.QuadPart - Target.QuadPart;
DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
RtlZeroMemory(ZeroBuf, ToWrite);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
ExFreePool(ZeroBuf);
return TRUE;
}
DPRINT1("RtlZeroMemory(%x,%x)\n",
ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
ToWrite);
CcpLock();
ListEntry = Map->AssociatedBcb.Flink;
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
ToWrite);
while (ListEntry != &Map->AssociatedBcb)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
CcpReferenceCache(Bcb - CcCacheSections);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
MIN(PAGE_SIZE,
UpperBound.QuadPart-Target.QuadPart),
&IOSB);
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT
("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart);
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart);
End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length);
CcpUnlock();
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
if (!CcPreparePinWrite
(FileObject,
&Target,
End.QuadPart - Target.QuadPart,
TRUE,
Wait,
&PinnedBcb,
&PinnedBuffer))
{
return FALSE;
}
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
{
DPRINT("Zero full page %08x%08x\n",
Target.u.HighPart,
Target.u.LowPart);
ASSERT(PinnedBcb == Bcb);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
&IOSB);
CcpLock();
ListEntry = ListEntry->Flink;
// Return from pin state
CcpUnpinData(PinnedBcb, TRUE);
}
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
CcpUnpinData(Bcb, TRUE);
}
if (UpperBound.QuadPart > Target.QuadPart)
{
ToWrite = UpperBound.QuadPart - Target.QuadPart;
DPRINT("Zero first half %08x%08x %x\n",
Target.u.HighPart,
Target.u.LowPart,
ToWrite);
CcpUnlock();
Status = MiSimpleRead(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
TRUE,
&IOSB);
return TRUE;
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
RtlZeroMemory(ZeroBuf, ToWrite);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
MIN(PAGE_SIZE,
UpperBound.QuadPart-Target.QuadPart),
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
Target.QuadPart += PAGE_SIZE;
}
ExFreePool(ZeroBuf);
return TRUE;
}
CcpLock();
ListEntry = Map->AssociatedBcb.Flink;
while (ListEntry != &Map->AssociatedBcb)
{
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
CcpReferenceCache(Bcb - CcCacheSections);
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart,
Bcb->FileOffset.u.LowPart);
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
LowerBound.QuadPart);
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
UpperBound.QuadPart);
End.QuadPart = MIN(End.QuadPart,
Bcb->FileOffset.QuadPart + Bcb->Length);
CcpUnlock();
if (!CcPreparePinWrite(FileObject,
&Target,
End.QuadPart - Target.QuadPart,
TRUE,
Wait,
&PinnedBcb,
&PinnedBuffer))
{
return FALSE;
}
ASSERT(PinnedBcb == Bcb);
CcpLock();
ListEntry = ListEntry->Flink;
/* Return from pin state */
CcpUnpinData(PinnedBcb, TRUE);
}
CcpUnpinData(Bcb, TRUE);
}
CcpUnlock();
return TRUE;
}
PFILE_OBJECT
NTAPI
CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
{
PFILE_OBJECT Result = NULL;
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
CcpLock();
if (!IsListEmpty(&Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
}
CcpUnlock();
PFILE_OBJECT Result = NULL;
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
CcpLock();
if (!IsListEmpty(&Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink,
NOCC_BCB,
ThisFileList);
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
}
CcpUnlock();
return Result;
}
@ -553,9 +630,9 @@ PFILE_OBJECT
NTAPI
CcGetFileObjectFromBcb(PVOID Bcb)
{
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
}
/* EOF */

View file

@ -22,7 +22,7 @@ KEVENT CcpLazyWriteEvent;
VOID NTAPI
CcpLazyWriteThread(PVOID Unused)
{
/* Not implemented */
/* Not implemented */
}
NTSTATUS

View file

@ -33,10 +33,10 @@ CcSetLogHandleForFile(IN PFILE_OBJECT FileObject,
IN PVOID LogHandle,
IN PFLUSH_TO_LSN FlushToLsnRoutine)
{
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
if (!Map) return;
Map->LogHandle = LogHandle;
Map->FlushToLsn = FlushToLsnRoutine;
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
if (!Map) return;
Map->LogHandle = LogHandle;
Map->FlushToLsn = FlushToLsnRoutine;
}
LARGE_INTEGER

View file

@ -16,55 +16,47 @@
/* GLOBALS ********************************************************************/
/* FUNCTIONS ******************************************************************/
PMDL
NTAPI
CcpBuildCacheMdl
(PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
PIO_STATUS_BLOCK IOSB)
CcpBuildCacheMdl(PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
PIO_STATUS_BLOCK IOSB)
{
PMDL Mdl;
PVOID Bcb, Buffer;
PMDL Mdl;
PVOID Bcb, Buffer;
BOOLEAN Result = CcMapData
(FileObject,
FileOffset,
Length,
PIN_WAIT,
&Bcb,
&Buffer);
BOOLEAN Result = CcMapData(FileObject,
FileOffset,
Length,
PIN_WAIT,
&Bcb,
&Buffer);
if (!Result)
{
IOSB->Information = 0;
IOSB->Status = STATUS_UNSUCCESSFUL;
return NULL;
}
if (!Result)
{
IOSB->Information = 0;
IOSB->Status = STATUS_UNSUCCESSFUL;
return NULL;
}
IOSB->Information = Length;
IOSB->Status = STATUS_SUCCESS;
IOSB->Information = Length;
IOSB->Status = STATUS_SUCCESS;
Mdl = IoAllocateMdl
(Buffer,
Length,
FALSE,
FALSE,
NULL);
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
if (!Mdl)
{
IOSB->Information = 0;
IOSB->Status = STATUS_NO_MEMORY;
return NULL;
}
if (!Mdl)
{
IOSB->Information = 0;
IOSB->Status = STATUS_NO_MEMORY;
return NULL;
}
IOSB->Information = Length;
IOSB->Status = STATUS_SUCCESS;
IOSB->Information = Length;
IOSB->Status = STATUS_SUCCESS;
return Mdl;
return Mdl;
}
VOID
@ -75,29 +67,25 @@ CcMdlRead(IN PFILE_OBJECT FileObject,
OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus)
{
*MdlChain = CcpBuildCacheMdl
(FileObject,
FileOffset,
Length,
IoStatus);
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
}
VOID
NTAPI
CcMdlReadComplete(IN PFILE_OBJECT FileObject,
IN PMDL MdlChain)
{
IoFreeMdl(MdlChain);
IoFreeMdl(MdlChain);
}
VOID
NTAPI
CcMdlReadComplete2(IN PMDL MdlChain,
IN PFILE_OBJECT FileObject)
IN PFILE_OBJECT FileObject)
{
UNIMPLEMENTED
UNIMPLEMENTED
}
VOID
NTAPI
CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
@ -106,11 +94,7 @@ CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus)
{
*MdlChain = CcpBuildCacheMdl
(FileObject,
FileOffset,
Length,
IoStatus);
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
}
VOID
@ -119,7 +103,7 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain)
{
IoFreeMdl(MdlChain);
IoFreeMdl(MdlChain);
}
VOID
@ -128,7 +112,7 @@ CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain)
{
UNIMPLEMENTED
UNIMPLEMENTED
}
VOID
@ -136,8 +120,8 @@ NTAPI
CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
IN PMDL MdlChain)
{
ASSERT(FALSE);
IoFreeMdl(MdlChain);
ASSERT(FALSE);
IoFreeMdl(MdlChain);
}
/* EOF */

View file

@ -5,7 +5,7 @@ typedef struct _NOCC_BCB
/* Public part */
PUBLIC_BCB Bcb;
struct _NOCC_CACHE_MAP *Map;
struct _NOCC_CACHE_MAP *Map;
PROS_SECTION_OBJECT SectionObject;
LARGE_INTEGER FileOffset;
ULONG Length;
@ -25,39 +25,33 @@ typedef struct _NOCC_BCB
typedef struct _NOCC_CACHE_MAP
{
LIST_ENTRY Entry;
LIST_ENTRY Entry;
LIST_ENTRY AssociatedBcb;
LIST_ENTRY PrivateCacheMaps;
LIST_ENTRY PrivateCacheMaps;
ULONG NumberOfMaps;
ULONG RefCount;
CC_FILE_SIZES FileSizes;
CACHE_MANAGER_CALLBACKS Callbacks;
PVOID LazyContext;
PVOID LogHandle;
PFLUSH_TO_LSN FlushToLsn;
ULONG ReadAheadGranularity;
CACHE_MANAGER_CALLBACKS Callbacks;
PVOID LazyContext;
PVOID LogHandle;
PFLUSH_TO_LSN FlushToLsn;
ULONG ReadAheadGranularity;
} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
VOID
NTAPI
CcPfInitializePrefetcher(
VOID
);
CcPfInitializePrefetcher(VOID);
VOID
NTAPI
CcMdlReadComplete2(
IN PMDL MemoryDescriptorList,
IN PFILE_OBJECT FileObject
);
CcMdlReadComplete2(IN PMDL MemoryDescriptorList,
IN PFILE_OBJECT FileObject);
VOID
NTAPI
CcMdlWriteComplete2(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain
);
CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain);
VOID
NTAPI
@ -65,7 +59,8 @@ CcInitView(VOID);
BOOLEAN
NTAPI
CcpUnpinData(PNOCC_BCB Bcb, BOOLEAN ActuallyRelease);
CcpUnpinData(PNOCC_BCB Bcb,
BOOLEAN ActuallyRelease);
BOOLEAN
NTAPI
@ -82,24 +77,25 @@ CcInitCacheZeroPage(VOID);
/* Called by section.c */
BOOLEAN
NTAPI
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE FlushType);
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType);
VOID
NTAPI
_CcpFlushCache
(IN PNOCC_CACHE_MAP Map,
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
BOOLEAN Delete,
const char *File,
int Line);
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
BOOLEAN Delete,
const char *File,
int Line);
#define CcpFlushCache(M,F,L,I,D) _CcpFlushCache(M,F,L,I,D,__FILE__,__LINE__)
BOOLEAN
NTAPI
CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
CcGetFileSizes(PFILE_OBJECT FileObject,
PCC_FILE_SIZES FileSizes);
ULONG
NTAPI
@ -125,13 +121,13 @@ CcpReleaseFileLock(PNOCC_CACHE_MAP Map);
/* Private data */
#define CACHE_SINGLE_FILE_MAX (16)
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
#define CACHE_SHIFT 18
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
#define INVALID_CACHE ((ULONG)~0)
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
#define CACHE_SHIFT 18
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
#define INVALID_CACHE ((ULONG)~0)
extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
extern PRTL_BITMAP CcCacheBitmap;
@ -149,20 +145,20 @@ extern VOID _CcpUnlock(const char *file, int line);
extern VOID CcpReferenceCache(ULONG Sector);
extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
BOOLEAN
NTAPI
CcpMapData
(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
OUT PVOID *BcbResult,
OUT PVOID *Buffer);
CcpMapData(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
OUT PVOID *BcbResult,
OUT PVOID *Buffer);
BOOLEAN
NTAPI
CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
IN OUT PVOID *Bcb);
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
IN OUT PVOID *Bcb);

File diff suppressed because it is too large Load diff