return(Status);
}
-VOID CcRosRemoveUnusedFiles(VOID);
-
-
NTSTATUS
CcRosFlushDirtyPages(ULONG Target, PULONG Count)
{
*/
{
PLIST_ENTRY current_entry;
- PCACHE_SEGMENT current;
+ PCACHE_SEGMENT current, last = NULL;
ULONG PagesPerSegment;
ULONG PagesFreed;
KIRQL oldIrql;
RemoveEntryList(¤t->CacheSegmentListEntry);
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
+ PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
+ PagesFreed = min(PagesPerSegment, Target);
+ Target -= PagesFreed;
+ (*NrFreed) += PagesFreed;
}
else
{
- KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
+ if (last != current && current->MappedCount > 0 && !current->Dirty)
+ {
+ ULONG i;
+ NTSTATUS Status;
+
+ current->ReferenceCount++;
+ last = current;
+ KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
+ ExReleaseFastMutex(&ViewLock);
+ for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
+ {
+ PHYSICAL_ADDRESS Page;
+ Page = MmGetPhysicalAddress(current->BaseAddress + i * PAGE_SIZE);
+ Status = MmPageOutPhysicalAddress(Page);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+ }
+ ExAcquireFastMutex(&ViewLock);
+ KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
+ current->ReferenceCount--;
+ KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
+ current_entry = ¤t->CacheSegmentLRUListEntry;
+ continue;
+ }
+ KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
}
}
ExReleaseFastMutex(&ViewLock);
current_entry = RemoveHeadList(&FreeList);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
- PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
- PagesFreed = min(PagesPerSegment, Target);
- Target -= PagesFreed;
- (*NrFreed) += PagesFreed;
CcRosInternalFreeCacheSegment(current);
}
{
current->ReferenceCount++;
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
+ ExAcquireFastMutex(¤t->Lock);
return(current);
}
current_entry = current_entry->Flink;
CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
if (CacheSeg == NULL)
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
- ExAcquireFastMutex(&CacheSeg->Lock);
if (!CacheSeg->Dirty)
{
ExAcquireFastMutex(&ViewLock);
{
return(STATUS_UNSUCCESSFUL);
}
- ExAcquireFastMutex(&CacheSeg->Lock);
WasDirty = CacheSeg->Dirty;
CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
NTSTATUS STATIC
CcRosCreateCacheSegment(PBCB Bcb,
ULONG FileOffset,
- PCACHE_SEGMENT* CacheSeg,
- BOOLEAN Lock)
+ PCACHE_SEGMENT* CacheSeg)
{
ULONG i;
PCACHE_SEGMENT current;
+ PCACHE_SEGMENT previous;
PLIST_ENTRY current_entry;
NTSTATUS Status;
KIRQL oldIrql;
DPRINT("CcRosCreateCacheSegment()\n");
+ if (FileOffset >= Bcb->FileSize.u.LowPart)
+ {
+ CacheSeg = NULL;
+ return STATUS_INVALID_PARAMETER;
+ }
+
current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList);
current->Valid = FALSE;
current->Dirty = FALSE;
*/
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
current_entry = Bcb->BcbSegmentListHead.Flink;
+ previous = NULL;
while (current_entry != &Bcb->BcbSegmentListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
ExReleaseFastMutex(&ViewLock);
ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
*CacheSeg = current;
- if (Lock)
+ ExAcquireFastMutex(¤t->Lock);
+ return STATUS_SUCCESS;
+ }
+ if (current->FileOffset < FileOffset)
+ {
+ if (previous == NULL)
{
- ExAcquireFastMutex(¤t->Lock);
+ previous = current;
+ }
+ else
+ {
+ if (previous->FileOffset < current->FileOffset)
+ {
+ previous = current;
+ }
}
- return STATUS_SUCCESS;
}
current_entry = current_entry->Flink;
}
/* There was no existing segment. */
current = *CacheSeg;
- InsertTailList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry);
+ if (previous)
+ {
+ InsertHeadList(&previous->BcbSegmentListEntry, ¤t->BcbSegmentListEntry);
+ }
+ else
+ {
+ InsertHeadList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry);
+ }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry);
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
if (StartingOffset == 0xffffffff)
{
DPRINT1("Out of CacheSeg mapping space\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE;
Bcb->CacheSegmentSize,
PAGE_READWRITE,
(PMEMORY_AREA*)¤t->MemoryArea,
+ FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
#endif
for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++)
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
Status = MmCreateVirtualMapping(NULL,
TRUE);
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
}
- if (!Lock)
- {
- ExReleaseFastMutex(¤t->Lock);
- }
-
return(STATUS_SUCCESS);
}
}
else
{
- CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t, FALSE);
+ CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t);
CacheSegList[i] = current;
}
}
for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++)
{
- ExAcquireFastMutex(&CacheSegList[i]->Lock);
if (i == 0)
{
*CacheSeg = CacheSegList[i];
* Look for a cache segment already mapping the same data.
*/
current = CcRosLookupCacheSegment(Bcb, FileOffset);
- if (current != NULL)
- {
- ExAcquireFastMutex(¤t->Lock);
- }
- else
+ if (current == NULL)
{
/*
* Otherwise create a new segment.
*/
- Status = CcRosCreateCacheSegment(Bcb, FileOffset, ¤t, TRUE);
+ Status = CcRosCreateCacheSegment(Bcb, FileOffset, ¤t);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
}
/*
* Return information about the segment to the caller.
{
CPRINT("Bad fileoffset %x should be multiple of %x",
FileOffset, Bcb->CacheSegmentSize);
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
return(CcRosGetCacheSegment(Bcb,
return(Status);
}
+/*
+ * @implemented
+ */
VOID STDCALL
CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
IN PLARGE_INTEGER FileOffset OPTIONAL,
current = CcRosLookupCacheSegment (Bcb, Offset.u.LowPart);
if (current != NULL)
{
- ExAcquireFastMutex(¤t->Lock);
if (current->Dirty)
{
Status = CcRosFlushCacheSegment(current);
Bcb->RefCount++;
ExReleaseFastMutex(&ViewLock);
- CcFlushCache(FileObject->SectionObjectPointers, NULL, 0, NULL);
+ CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
ExAcquireFastMutex(&ViewLock);
Bcb->RefCount--;
Bcb->BcbRemoveListEntry.Flink = NULL;
}
- FileObject->SectionObjectPointers->SharedCacheMap = NULL;
+ FileObject->SectionObjectPointer->SharedCacheMap = NULL;
/*
* Release all cache segments.
{
PBCB Bcb;
ExAcquireFastMutex(&ViewLock);
- Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap;
+ Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
assert(Bcb);
+ if (Bcb->RefCount == 0)
+ {
+ assert(Bcb->BcbRemoveListEntry.Flink != NULL);
+ RemoveEntryList(&Bcb->BcbRemoveListEntry);
+ Bcb->BcbRemoveListEntry.Flink = NULL;
+
+ }
+ else
+ {
+ assert(Bcb->BcbRemoveListEntry.Flink == NULL);
+ }
Bcb->RefCount++;
ExReleaseFastMutex(&ViewLock);
}
VOID CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
{
PBCB Bcb;
-// DPRINT1("CcRosSetRemoveOnClose()\n");
+ DPRINT("CcRosSetRemoveOnClose()\n");
ExAcquireFastMutex(&ViewLock);
Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
if (Bcb)
{
PBCB Bcb;
ExAcquireFastMutex(&ViewLock);
- Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap;
+ Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
assert(Bcb);
if (Bcb->RefCount > 0)
{
ExAcquireFastMutex(&ViewLock);
- if (FileObject->SectionObjectPointers->SharedCacheMap != NULL)
+ if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
{
- Bcb = FileObject->SectionObjectPointers->SharedCacheMap;
+ Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
if (FileObject->PrivateCacheMap != NULL)
{
FileObject->PrivateCacheMap = NULL;
return(STATUS_SUCCESS);
}
+NTSTATUS
+CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
+{
+ PBCB Bcb;
+ NTSTATUS Status;
+
+ ExAcquireFastMutex(&ViewLock);
+
+ Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+ if (Bcb == NULL)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ if (FileObject->PrivateCacheMap == NULL)
+ {
+ FileObject->PrivateCacheMap = Bcb;
+ Bcb->RefCount++;
+ }
+ if (Bcb->BcbRemoveListEntry.Flink != NULL)
+ {
+ RemoveEntryList(&Bcb->BcbRemoveListEntry);
+ Bcb->BcbRemoveListEntry.Flink = NULL;
+ }
+ Status = STATUS_SUCCESS;
+ }
+ ExReleaseFastMutex(&ViewLock);
+
+ return Status;
+}
+
+
NTSTATUS STDCALL
CcRosInitializeFileCache(PFILE_OBJECT FileObject,
ULONG CacheSegmentSize)
ExAcquireFastMutex(&ViewLock);
- Bcb = FileObject->SectionObjectPointers->SharedCacheMap;
+ Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
if (Bcb == NULL)
{
Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList);
if (FileObject->FsContext)
{
Bcb->AllocationSize =
- ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->AllocationSize;
+ ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize;
Bcb->FileSize =
- ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->FileSize;
+ ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
}
KeInitializeSpinLock(&Bcb->BcbLock);
InitializeListHead(&Bcb->BcbSegmentListHead);
- FileObject->SectionObjectPointers->SharedCacheMap = Bcb;
+ FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
}
if (FileObject->PrivateCacheMap == NULL)
{
return(STATUS_SUCCESS);
}
+/*
+ * @implemented
+ */
PFILE_OBJECT STDCALL
CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers)
{
if (!NT_SUCCESS(Status))
{
DbgPrint("LazyCloseThread: Wait failed\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
break;
}
if (LazyCloseThreadShouldTerminate)
CI_CACHESEG_MAPPING_REGION_SIZE,
0,
&marea,
+ FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
Buffer = ExAllocatePool(NonPagedPool, CI_CACHESEG_MAPPING_REGION_SIZE / (PAGE_SIZE * 8));