X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fcc%2Fview.c;h=7e7e85cc857dfa64a498011a379400296038a327;hp=be8e239b80bd71f36be0d18582451381d63bc7fc;hb=HEAD;hpb=7c0db166f81fbe8c8b913d7f26048e337d383605 diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index be8e239..7e7e85c 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -132,9 +132,6 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment) return(Status); } -VOID CcRosRemoveUnusedFiles(VOID); - - NTSTATUS CcRosFlushDirtyPages(ULONG Target, PULONG Count) { @@ -231,7 +228,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) */ { PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; + PCACHE_SEGMENT current, last = NULL; ULONG PagesPerSegment; ULONG PagesFreed; KIRQL oldIrql; @@ -259,10 +256,40 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) 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); @@ -272,10 +299,6 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) 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); } @@ -353,6 +376,7 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) { current->ReferenceCount++; KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + ExAcquireFastMutex(¤t->Lock); return(current); } current_entry = current_entry->Flink; @@ -374,9 +398,8 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); if (CacheSeg == NULL) { - KeBugCheck(0); + KEBUGCHECK(0); } - ExAcquireFastMutex(&CacheSeg->Lock); if (!CacheSeg->Dirty) { ExAcquireFastMutex(&ViewLock); @@ -415,7 +438,6 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) { return(STATUS_UNSUCCESSFUL); } - ExAcquireFastMutex(&CacheSeg->Lock); WasDirty = CacheSeg->Dirty; CacheSeg->Dirty = CacheSeg->Dirty || NowDirty; @@ -449,11 +471,11 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN 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; @@ -465,6 +487,12 @@ CcRosCreateCacheSegment(PBCB Bcb, DPRINT("CcRosCreateCacheSegment()\n"); + if (FileOffset >= Bcb->FileSize.u.LowPart) + { + CacheSeg = NULL; + return STATUS_INVALID_PARAMETER; + } + current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList); current->Valid = FALSE; current->Dirty = FALSE; @@ -486,6 +514,7 @@ CcRosCreateCacheSegment(PBCB Bcb, */ KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); current_entry = Bcb->BcbSegmentListHead.Flink; + previous = NULL; while (current_entry != &Bcb->BcbSegmentListHead) { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, @@ -499,17 +528,35 @@ CcRosCreateCacheSegment(PBCB Bcb, 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); @@ -522,7 +569,7 @@ CcRosCreateCacheSegment(PBCB Bcb, if (StartingOffset == 0xffffffff) { DPRINT1("Out of CacheSeg mapping space\n"); - KeBugCheck(0); + KEBUGCHECK(0); } current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE; @@ -543,11 +590,12 @@ CcRosCreateCacheSegment(PBCB Bcb, 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++) @@ -557,7 +605,7 @@ CcRosCreateCacheSegment(PBCB Bcb, Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page); if (!NT_SUCCESS(Status)) { - KeBugCheck(0); + KEBUGCHECK(0); } Status = MmCreateVirtualMapping(NULL, @@ -567,14 +615,9 @@ CcRosCreateCacheSegment(PBCB Bcb, TRUE); if (!NT_SUCCESS(Status)) { - KeBugCheck(0); + KEBUGCHECK(0); } } - if (!Lock) - { - ExReleaseFastMutex(¤t->Lock); - } - return(STATUS_SUCCESS); } @@ -611,14 +654,13 @@ CcRosGetCacheSegmentChain(PBCB Bcb, } 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]; @@ -654,16 +696,16 @@ CcRosGetCacheSegment(PBCB Bcb, * 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. @@ -694,7 +736,7 @@ CcRosRequestCacheSegment(PBCB Bcb, { CPRINT("Bad fileoffset %x should be multiple of %x", FileOffset, Bcb->CacheSegmentSize); - KeBugCheck(0); + KEBUGCHECK(0); } return(CcRosGetCacheSegment(Bcb, @@ -796,6 +838,9 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) return(Status); } +/* + * @implemented + */ VOID STDCALL CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, IN PLARGE_INTEGER FileOffset OPTIONAL, @@ -836,7 +881,6 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, current = CcRosLookupCacheSegment (Bcb, Offset.u.LowPart); if (current != NULL) { - ExAcquireFastMutex(¤t->Lock); if (current->Dirty) { Status = CcRosFlushCacheSegment(current); @@ -888,7 +932,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) Bcb->RefCount++; ExReleaseFastMutex(&ViewLock); - CcFlushCache(FileObject->SectionObjectPointers, NULL, 0, NULL); + CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL); ExAcquireFastMutex(&ViewLock); Bcb->RefCount--; @@ -900,7 +944,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) Bcb->BcbRemoveListEntry.Flink = NULL; } - FileObject->SectionObjectPointers->SharedCacheMap = NULL; + FileObject->SectionObjectPointer->SharedCacheMap = NULL; /* * Release all cache segments. @@ -943,8 +987,19 @@ VOID CcRosReferenceCache(PFILE_OBJECT FileObject) { 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); } @@ -952,7 +1007,7 @@ VOID CcRosReferenceCache(PFILE_OBJECT FileObject) VOID CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer) { PBCB Bcb; -// DPRINT1("CcRosSetRemoveOnClose()\n"); + DPRINT("CcRosSetRemoveOnClose()\n"); ExAcquireFastMutex(&ViewLock); Bcb = (PBCB)SectionObjectPointer->SharedCacheMap; if (Bcb) @@ -971,7 +1026,7 @@ VOID CcRosDereferenceCache(PFILE_OBJECT FileObject) { PBCB Bcb; ExAcquireFastMutex(&ViewLock); - Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap; + Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; assert(Bcb); if (Bcb->RefCount > 0) { @@ -1004,9 +1059,9 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject) 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; @@ -1032,6 +1087,39 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject) 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) @@ -1045,7 +1133,7 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, ExAcquireFastMutex(&ViewLock); - Bcb = FileObject->SectionObjectPointers->SharedCacheMap; + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; if (Bcb == NULL) { Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList); @@ -1064,13 +1152,13 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, 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) { @@ -1087,6 +1175,9 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, return(STATUS_SUCCESS); } +/* + * @implemented + */ PFILE_OBJECT STDCALL CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers) { @@ -1125,7 +1216,7 @@ CmLazyCloseThreadMain(PVOID Ignored) if (!NT_SUCCESS(Status)) { DbgPrint("LazyCloseThread: Wait failed\n"); - KeBugCheck(0); + KEBUGCHECK(0); break; } if (LazyCloseThreadShouldTerminate) @@ -1178,11 +1269,12 @@ CcInitView(VOID) 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));