Index: dirwr.c =================================================================== --- drivers/filesystems/fastfat/dirwr.c (revision 74351) +++ drivers/filesystems/fastfat/dirwr.c (working copy) @@ -132,7 +132,7 @@ Status = vfatUpdateFCB(DeviceExt, pFcb, &DirContext, pFcb->parentFcb); if (NT_SUCCESS(Status)) { - CcPurgeCacheSection(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, FALSE); + CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL); } return Status; @@ -987,7 +987,7 @@ } OldParent = pFcb->parentFcb; - CcPurgeCacheSection(&OldParent->SectionObjectPointers, NULL, 0, FALSE); + CcFlushCache(&OldParent->SectionObjectPointers, NULL, 0, NULL); MoveContext.InPlace = (OldParent == ParentFcb); /* Add our new entry with our cluster */ @@ -999,7 +999,7 @@ *pFcb->Attributes, &MoveContext); - CcPurgeCacheSection(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, FALSE); + CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL); return Status; } Index: cc/fs.c =================================================================== --- ntoskrnl/cc/fs.c (revision 74317) +++ ntoskrnl/cc/fs.c (working copy) @@ -269,7 +269,7 @@ CCTRACE(CC_API_DEBUG, "FileObject=%p TruncateSize=%p UninitializeCompleteEvent=%p\n", FileObject, TruncateSize, UninitializeCompleteEvent); - Status = CcRosReleaseFileCache(FileObject); + Status = CcRosReleaseFileCache(FileObject, TruncateSize); if (UninitializeCompleteEvent) KeSetEvent(&UninitializeCompleteEvent->Event, IO_NO_INCREMENT, FALSE); return NT_SUCCESS(Status); Index: cc/view.c =================================================================== --- ntoskrnl/cc/view.c (revision 74317) +++ ntoskrnl/cc/view.c (working copy) @@ -129,6 +129,25 @@ #endif } +static +VOID +CcRosPurgeVacb ( + _Inout_ PROS_VACB Vacb) +{ + KIRQL oldIrql; + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Vacb->SharedCacheMap->CacheMapLock, &oldIrql); + + Vacb->Dirty = FALSE; + RemoveEntryList(&Vacb->DirtyVacbListEntry); + DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE; + CcRosVacbDecRefCount(Vacb); + + KeReleaseSpinLock(&Vacb->SharedCacheMap->CacheMapLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); +} + NTSTATUS NTAPI CcRosFlushVacb ( @@ -885,6 +904,70 @@ return STATUS_SUCCESS; } +static +NTSTATUS +CcRosFlushOrPurge( + _Inout_ PROS_SHARED_CACHE_MAP SharedCacheMap, + _In_opt_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ LONGLONG TruncateSize) +{ + NTSTATUS Status; + NTSTATUS FlushStatus; + LARGE_INTEGER Offset; + LONGLONG RemainingLength; + PROS_VACB current; + KIRQL oldIrql; + + if (FileOffset) + { + Offset = *FileOffset; + RemainingLength = Length; + } + else + { + Offset.QuadPart = 0; + RemainingLength = SharedCacheMap->FileSize.QuadPart; + } + + Status = STATUS_SUCCESS; + while (RemainingLength > 0) + { + current = CcRosLookupVacb(SharedCacheMap, Offset.QuadPart); + if (current != NULL) + { + if (current->Dirty) + { + if (current->FileOffset.QuadPart < TruncateSize) + { + FlushStatus = CcRosFlushVacb(current); + if (!NT_SUCCESS(FlushStatus)) + { + Status = FlushStatus; + } + } + else + { + CcRosPurgeVacb(current); + } + } + + CcRosReleaseVacbLock(current); + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); + CcRosVacbDecRefCount(current); + KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + } + + Offset.QuadPart += VACB_MAPPING_GRANULARITY; + RemainingLength -= min(RemainingLength, VACB_MAPPING_GRANULARITY); + } + + return Status; +} + /* * @implemented */ @@ -896,12 +979,7 @@ IN ULONG Length, OUT PIO_STATUS_BLOCK IoStatus) { - PROS_SHARED_CACHE_MAP SharedCacheMap; - LARGE_INTEGER Offset; - LONGLONG RemainingLength; - PROS_VACB current; NTSTATUS Status; - KIRQL oldIrql; CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=%p Length=%lu\n", SectionObjectPointers, FileOffset, Length); @@ -911,51 +989,15 @@ if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap) { - SharedCacheMap = SectionObjectPointers->SharedCacheMap; - ASSERT(SharedCacheMap); - if (FileOffset) - { - Offset = *FileOffset; - RemainingLength = Length; - } - else - { - Offset.QuadPart = 0; - RemainingLength = SharedCacheMap->FileSize.QuadPart; - } - + Status = CcRosFlushOrPurge(SectionObjectPointers->SharedCacheMap, + FileOffset, + Length, + MAXLONGLONG); if (IoStatus) { - IoStatus->Status = STATUS_SUCCESS; + IoStatus->Status = Status; IoStatus->Information = 0; } - - while (RemainingLength > 0) - { - current = CcRosLookupVacb(SharedCacheMap, Offset.QuadPart); - if (current != NULL) - { - if (current->Dirty) - { - Status = CcRosFlushVacb(current); - if (!NT_SUCCESS(Status) && IoStatus != NULL) - { - IoStatus->Status = Status; - } - } - - CcRosReleaseVacbLock(current); - - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); - CcRosVacbDecRefCount(current); - KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); - KeReleaseGuardedMutex(&ViewLock); - } - - Offset.QuadPart += VACB_MAPPING_GRANULARITY; - RemainingLength -= min(RemainingLength, VACB_MAPPING_GRANULARITY); - } } else { @@ -969,8 +1011,9 @@ NTSTATUS NTAPI CcRosDeleteFileCache ( - PFILE_OBJECT FileObject, - PROS_SHARED_CACHE_MAP SharedCacheMap) + _Inout_ PFILE_OBJECT FileObject, + _Inout_ PROS_SHARED_CACHE_MAP SharedCacheMap, + _In_opt_ PLARGE_INTEGER TruncateSize) /* * FUNCTION: Releases the shared cache map associated with a file object */ @@ -985,7 +1028,10 @@ SharedCacheMap->RefCount++; KeReleaseGuardedMutex(&ViewLock); - CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL); + (VOID)CcRosFlushOrPurge(SharedCacheMap, + NULL, + 0, + TruncateSize ? TruncateSize->QuadPart : MAXLONGLONG); KeAcquireGuardedMutex(&ViewLock); SharedCacheMap->RefCount--; @@ -1056,7 +1102,7 @@ SharedCacheMap = SectionObjectPointer->SharedCacheMap; if (SharedCacheMap && SharedCacheMap->RefCount == 0) { - CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap); + CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, NULL); } KeReleaseGuardedMutex(&ViewLock); } @@ -1077,7 +1123,7 @@ if (SharedCacheMap->RefCount == 0) { MmFreeSectionSegments(SharedCacheMap->FileObject); - CcRosDeleteFileCache(FileObject, SharedCacheMap); + CcRosDeleteFileCache(FileObject, SharedCacheMap, NULL); } } KeReleaseGuardedMutex(&ViewLock); @@ -1086,7 +1132,8 @@ NTSTATUS NTAPI CcRosReleaseFileCache ( - PFILE_OBJECT FileObject) + _Inout_ PFILE_OBJECT FileObject, + _In_opt_ PLARGE_INTEGER TruncateSize) /* * FUNCTION: Called by the file system when a handle to a file object * has been closed. @@ -1108,7 +1155,7 @@ if (SharedCacheMap->RefCount == 0) { MmFreeSectionSegments(SharedCacheMap->FileObject); - CcRosDeleteFileCache(FileObject, SharedCacheMap); + CcRosDeleteFileCache(FileObject, SharedCacheMap, TruncateSize); } } } Index: include/internal/cc.h =================================================================== --- ntoskrnl/include/internal/cc.h (revision 74317) +++ ntoskrnl/include/internal/cc.h (working copy) @@ -334,7 +334,8 @@ NTSTATUS NTAPI CcRosReleaseFileCache( - PFILE_OBJECT FileObject + _Inout_ PFILE_OBJECT FileObject, + _In_opt_ PLARGE_INTEGER TruncateSize ); NTSTATUS