[NTOS:CC]
[reactos.git] / reactos / ntoskrnl / cc / fs.c
index 27f6455..1bf5095 100644 (file)
@@ -38,6 +38,10 @@ CcGetDirtyPages (
     IN PVOID Context2)
 {
     LARGE_INTEGER i;
+
+    CCTRACE(CC_API_DEBUG, "LogHandle=%p DirtyPageRoutine=%p Context1=%p Context2=%p\n",
+        LogHandle, DirtyPageRoutine, Context1, Context2);
+
     UNIMPLEMENTED;
     i.QuadPart = 0;
     return i;
@@ -52,6 +56,9 @@ CcGetFileObjectFromBcb (
     IN PVOID Bcb)
 {
     PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
+
+    CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
+
     return iBcb->Vacb->SharedCacheMap->FileObject;
 }
 
@@ -65,6 +72,9 @@ CcGetLsnForFileObject (
     OUT PLARGE_INTEGER OldestLsn OPTIONAL)
 {
     LARGE_INTEGER i;
+
+    CCTRACE(CC_API_DEBUG, "FileObject=%p\n", FileObject);
+
     UNIMPLEMENTED;
     i.QuadPart = 0;
     return i;
@@ -82,13 +92,22 @@ CcInitializeCacheMap (
     IN PCACHE_MANAGER_CALLBACKS CallBacks,
     IN PVOID LazyWriterContext)
 {
+    NTSTATUS Status;
+
     ASSERT(FileObject);
     ASSERT(FileSizes);
 
+    CCTRACE(CC_API_DEBUG, "FileObject=%p FileSizes=%p PinAccess=%d CallBacks=%p LazyWriterContext=%p\n",
+        FileObject, FileSizes, PinAccess, CallBacks, LazyWriterContext);
+
     /* Call old ROS cache init function */
-    CcRosInitializeFileCache(FileObject,
-                             CallBacks,
-                             LazyWriterContext);
+    Status = CcRosInitializeFileCache(FileObject,
+                                      FileSizes,
+                                      PinAccess,
+                                      CallBacks,
+                                      LazyWriterContext);
+    if (!NT_SUCCESS(Status))
+        ExRaiseStatus(Status);
 }
 
 /*
@@ -99,6 +118,8 @@ NTAPI
 CcIsThereDirtyData (
     IN PVPB Vpb)
 {
+    CCTRACE(CC_API_DEBUG, "Vpb=%p\n", Vpb);
+
     UNIMPLEMENTED;
     return FALSE;
 }
@@ -114,7 +135,82 @@ CcPurgeCacheSection (
     IN ULONG Length,
     IN BOOLEAN UninitializeCacheMaps)
 {
-    //UNIMPLEMENTED;
+    PROS_SHARED_CACHE_MAP SharedCacheMap;
+    LONGLONG StartOffset;
+    LONGLONG EndOffset;
+    LIST_ENTRY FreeList;
+    KIRQL OldIrql;
+    PLIST_ENTRY ListEntry;
+    PROS_VACB Vacb;
+    LONGLONG ViewEnd;
+
+    CCTRACE(CC_API_DEBUG, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu UninitializeCacheMaps=%d",
+        SectionObjectPointer, FileOffset, Length, UninitializeCacheMaps);
+
+    if (UninitializeCacheMaps)
+    {
+        DPRINT1("FIXME: CcPurgeCacheSection not uninitializing private cache maps\n");
+    }
+
+    SharedCacheMap = SectionObjectPointer->SharedCacheMap;
+
+    StartOffset = FileOffset != NULL ? FileOffset->QuadPart : 0;
+    if (Length == 0 || FileOffset == NULL)
+    {
+        EndOffset = MAXLONGLONG;
+    }
+    else
+    {
+        EndOffset = StartOffset + Length;
+        ASSERT(EndOffset > StartOffset);
+    }
+
+    InitializeListHead(&FreeList);
+
+    KeAcquireGuardedMutex(&ViewLock);
+    KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql);
+    ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
+    while (ListEntry != &SharedCacheMap->CacheMapVacbListHead)
+    {
+        Vacb = CONTAINING_RECORD(ListEntry, ROS_VACB, CacheMapVacbListEntry);
+        ListEntry = ListEntry->Flink;
+
+        /* Skip VACBs outside the range, or only partially in range */
+        if (Vacb->FileOffset.QuadPart < StartOffset)
+        {
+            continue;
+        }
+        ViewEnd = min(Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY,
+                      SharedCacheMap->SectionSize.QuadPart);
+        if (ViewEnd >= EndOffset)
+        {
+            break;
+        }
+
+        ASSERT((Vacb->ReferenceCount == 0) ||
+               (Vacb->ReferenceCount == 1 && Vacb->Dirty));
+
+        /* This VACB is in range, so unlink it and mark for free */
+        RemoveEntryList(&Vacb->VacbLruListEntry);
+        if (Vacb->Dirty)
+        {
+            RemoveEntryList(&Vacb->DirtyVacbListEntry);
+            DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+        }
+        RemoveEntryList(&Vacb->CacheMapVacbListEntry);
+        InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry);
+    }
+    KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql);
+    KeReleaseGuardedMutex(&ViewLock);
+
+    while (!IsListEmpty(&FreeList))
+    {
+        Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
+                                 ROS_VACB,
+                                 CacheMapVacbListEntry);
+        CcRosInternalFreeVacb(Vacb);
+    }
+
     return FALSE;
 }
 
@@ -134,6 +230,9 @@ CcSetFileSizes (
     LIST_ENTRY FreeListHead;
     NTSTATUS Status;
 
+    CCTRACE(CC_API_DEBUG, "FileObject=%p FileSizes=%p\n",
+        FileObject, FileSizes);
+
     DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n",
            FileObject, FileSizes);
     DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n",
@@ -221,6 +320,9 @@ CcSetLogHandleForFile (
     IN PVOID LogHandle,
     IN PFLUSH_TO_LSN FlushToLsnRoutine)
 {
+    CCTRACE(CC_API_DEBUG, "FileObject=%p LogHandle=%p FlushToLsnRoutine=%p\n",
+        FileObject, LogHandle, FlushToLsnRoutine);
+
     UNIMPLEMENTED;
 }
 
@@ -234,12 +336,15 @@ CcUninitializeCacheMap (
     IN PLARGE_INTEGER TruncateSize OPTIONAL,
     IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL)
 {
-#if 0
-    UNIMPLEMENTED;
-    return FALSE;
-#else
-    return NT_SUCCESS(CcRosReleaseFileCache(FileObject));
-#endif
+    NTSTATUS Status;
+
+    CCTRACE(CC_API_DEBUG, "FileObject=%p TruncateSize=%p UninitializeCompleteEvent=%p\n",
+        FileObject, TruncateSize, UninitializeCompleteEvent);
+
+    Status = CcRosReleaseFileCache(FileObject);
+    if (UninitializeCompleteEvent)
+        KeSetEvent(&UninitializeCompleteEvent->Event, IO_NO_INCREMENT, FALSE);
+    return NT_SUCCESS(Status);
 }
 
 BOOLEAN