/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/cc/fs.c * PURPOSE: Implements cache managers functions useful for File Systems * * PROGRAMMERS: Alex Ionescu */ /* INCLUDES ******************************************************************/ #include #define NDEBUG #include #ifndef VACB_MAPPING_GRANULARITY #define VACB_MAPPING_GRANULARITY (256 * 1024) #endif /* GLOBALS *****************************************************************/ extern KGUARDED_MUTEX ViewLock; extern ULONG DirtyPageCount; NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb); /* FUNCTIONS *****************************************************************/ /* * @unimplemented */ LARGE_INTEGER NTAPI CcGetDirtyPages ( IN PVOID LogHandle, IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine, IN PVOID Context1, IN PVOID Context2) { LARGE_INTEGER i; UNIMPLEMENTED; i.QuadPart = 0; return i; } /* * @implemented */ PFILE_OBJECT NTAPI CcGetFileObjectFromBcb ( IN PVOID Bcb) { PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb; return iBcb->Vacb->SharedCacheMap->FileObject; } /* * @unimplemented */ LARGE_INTEGER NTAPI CcGetLsnForFileObject ( IN PFILE_OBJECT FileObject, OUT PLARGE_INTEGER OldestLsn OPTIONAL) { LARGE_INTEGER i; UNIMPLEMENTED; i.QuadPart = 0; return i; } /* * @unimplemented */ VOID NTAPI CcInitializeCacheMap ( IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS CallBacks, IN PVOID LazyWriterContext) { ASSERT(FileObject); ASSERT(FileSizes); /* Call old ROS cache init function */ CcRosInitializeFileCache(FileObject, CallBacks, LazyWriterContext); } /* * @unimplemented */ BOOLEAN NTAPI CcIsThereDirtyData ( IN PVPB Vpb) { UNIMPLEMENTED; return FALSE; } /* * @unimplemented */ BOOLEAN NTAPI CcPurgeCacheSection ( IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER FileOffset OPTIONAL, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps) { //UNIMPLEMENTED; return FALSE; } /* * @implemented */ VOID NTAPI CcSetFileSizes ( IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes) { KIRQL oldirql; PROS_SHARED_CACHE_MAP SharedCacheMap; PLIST_ENTRY current_entry; PROS_VACB current; LIST_ENTRY FreeListHead; NTSTATUS Status; DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n", FileObject, FileSizes); DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n", FileSizes->AllocationSize.QuadPart, FileSizes->FileSize.QuadPart, FileSizes->ValidDataLength.QuadPart); SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; /* * It is valid to call this function on file objects that weren't * initialized for caching. In this case it's simple no-op. */ if (SharedCacheMap == NULL) return; if (FileSizes->AllocationSize.QuadPart < SharedCacheMap->SectionSize.QuadPart) { InitializeListHead(&FreeListHead); KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql); current_entry = SharedCacheMap->CacheMapVacbListHead.Flink; while (current_entry != &SharedCacheMap->CacheMapVacbListHead) { current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry); current_entry = current_entry->Flink; if (current->FileOffset.QuadPart >= FileSizes->AllocationSize.QuadPart) { if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty)) { RemoveEntryList(¤t->CacheMapVacbListEntry); RemoveEntryList(¤t->VacbLruListEntry); if (current->Dirty) { RemoveEntryList(¤t->DirtyVacbListEntry); DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE; } InsertHeadList(&FreeListHead, ¤t->CacheMapVacbListEntry); } else { DPRINT1("Someone has referenced a VACB behind the new size.\n"); KeBugCheck(CACHE_MANAGER); } } } SharedCacheMap->SectionSize = FileSizes->AllocationSize; SharedCacheMap->FileSize = FileSizes->FileSize; KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql); KeReleaseGuardedMutex(&ViewLock); current_entry = FreeListHead.Flink; while(current_entry != &FreeListHead) { current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry); current_entry = current_entry->Flink; Status = CcRosInternalFreeVacb(current); if (!NT_SUCCESS(Status)) { DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status); KeBugCheck(CACHE_MANAGER); } } } else { KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql); SharedCacheMap->SectionSize = FileSizes->AllocationSize; SharedCacheMap->FileSize = FileSizes->FileSize; KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql); } } /* * @unimplemented */ VOID NTAPI CcSetLogHandleForFile ( IN PFILE_OBJECT FileObject, IN PVOID LogHandle, IN PFLUSH_TO_LSN FlushToLsnRoutine) { UNIMPLEMENTED; } /* * @unimplemented */ BOOLEAN NTAPI CcUninitializeCacheMap ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER TruncateSize OPTIONAL, IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL) { #if 0 UNIMPLEMENTED; return FALSE; #else return NT_SUCCESS(CcRosReleaseFileCache(FileObject)); #endif } BOOLEAN NTAPI CcGetFileSizes ( IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes) { PROS_SHARED_CACHE_MAP SharedCacheMap; SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; if (!SharedCacheMap) return FALSE; FileSizes->AllocationSize = SharedCacheMap->SectionSize; FileSizes->FileSize = FileSizes->ValidDataLength = SharedCacheMap->FileSize; return TRUE; }