Index: ntoskrnl/cc/fs.c =================================================================== --- ntoskrnl/cc/fs.c (revision 17402) +++ ntoskrnl/cc/fs.c (working copy) @@ -11,7 +11,7 @@ /* INCLUDES ******************************************************************/ #include -#define NDEBUG +//#define NDEBUG #include #ifndef VACB_MAPPING_GRANULARITY @@ -133,6 +133,9 @@ PCACHE_SEGMENT current; LIST_ENTRY FreeListHead; NTSTATUS Status; + ULONG Count; + BOOLEAN BadRef; + LARGE_INTEGER WaitTime; DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n", FileObject, FileSizes); @@ -150,43 +153,66 @@ if (Bcb == NULL) return; + DPRINT("Bcb->AllocationSize->QuadPart=%lu\n", + (unsigned long)Bcb->AllocationSize.QuadPart ); + if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart) { InitializeListHead(&FreeListHead); - ExAcquireFastMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + Count = 0; + do + { + BadRef = FALSE; + ExAcquireFastMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - current_entry = current_entry->Flink; - if (current->FileOffset > FileSizes->AllocationSize.QuadPart) - { - if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty)) + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + if (current->FileOffset > FileSizes->AllocationSize.QuadPart) { - RemoveEntryList(¤t->BcbSegmentListEntry); - RemoveEntryList(¤t->CacheSegmentListEntry); - RemoveEntryList(¤t->CacheSegmentLRUListEntry); - if (current->Dirty) - { - RemoveEntryList(¤t->DirtySegmentListEntry); - DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; - } - InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry); + if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty)) + { + RemoveEntryList(¤t->BcbSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentLRUListEntry); + if (current->Dirty) + { + RemoveEntryList(¤t->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + } + InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry); + } + else + { + DPRINT1("CacheSegment 0x%p: RefCount: %d, Dirty %d, PageOut %d\n", current, current->ReferenceCount, current->Dirty, current->PageOut); + BadRef = TRUE; + } } - else - { - DPRINT1("Anyone has referenced a cache segment behind the new size.\n"); + } + if (!BadRef) + { + Bcb->AllocationSize = FileSizes->AllocationSize; + Bcb->FileSize = FileSizes->FileSize; + } + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + ExReleaseFastMutex(&ViewLock); + if (BadRef) + { + /* give CcRosFlushDirtyPages a chance to finish the write back of dirty pages */ + if (++Count >= 250) /* 1sec */ + { + DPRINT1("Anyone has referenced a cache segment behind the new size.\n"); KEBUGCHECKCC; - } - } + } + WaitTime.QuadPart = -200000LL; /* 20msec */ + KeDelayExecutionThread(KernelMode, FALSE, &WaitTime); + } } + while (BadRef); - Bcb->AllocationSize = FileSizes->AllocationSize; - Bcb->FileSize = FileSizes->FileSize; - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - ExReleaseFastMutex(&ViewLock); current_entry = FreeListHead.Flink; while(current_entry != &FreeListHead) Index: ntoskrnl/cc/view.c =================================================================== --- ntoskrnl/cc/view.c (revision 17402) +++ ntoskrnl/cc/view.c (working copy) @@ -1226,6 +1226,7 @@ return(STATUS_UNSUCCESSFUL); } memset(Bcb, 0, sizeof(BCB)); + Bcb->Trace = TRUE; ObReferenceObjectByPointer(FileObject, FILE_ALL_ACCESS, NULL, Index: drivers/fs/vfat/create.c =================================================================== --- drivers/fs/vfat/create.c (revision 17402) +++ drivers/fs/vfat/create.c (working copy) @@ -445,7 +445,7 @@ PDEVICE_EXTENSION DeviceExt; ULONG RequestedDisposition, RequestedOptions; PVFATCCB pCcb; - PVFATFCB pFcb; + PVFATFCB pFcb = NULL; PVFATFCB ParentFcb; PWCHAR c, last; BOOLEAN PagingFileCreate = FALSE; @@ -564,6 +564,10 @@ vfatReleaseFCB (DeviceExt, ParentFcb); if (NT_SUCCESS (Status)) { + #if defined(DBG) || defined(KDBG) + ASSERT( pFcb ); + CcRosTraceCacheMap ( pFcb->SectionObjectPointers.SharedCacheMap, TRUE ); + #endif Status = vfatAttachFCBToFileObject (DeviceExt, pFcb, FileObject); if ( !NT_SUCCESS(Status) ) { @@ -577,6 +581,9 @@ pFcb, DeviceExt, &Irp->Overlay.AllocationSize); + #if defined(DBG) || defined(KDBG) + CcRosTraceCacheMap ( FileObject->SectionObjectPointer->SharedCacheMap, FALSE ); + #endif VfatSetExtendedAttributes(FileObject, Irp->AssociatedIrp.SystemBuffer, Stack->Parameters.Create.EaLength);