Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencachesub.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel 00004 * FILE: ntoskrnl/cache/cachesup.c 00005 * PURPOSE: Logging and configuration routines 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Art Yerkes 00008 */ 00009 00010 /* INCLUDES *******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #include "newcc.h" 00014 #include "section/newmm.h" 00015 #define NDEBUG 00016 #include <debug.h> 00017 00018 /* STRUCTURES *****************************************************************/ 00019 00020 typedef struct _WORK_QUEUE_WITH_READ_AHEAD 00021 { 00022 WORK_QUEUE_ITEM WorkItem; 00023 PFILE_OBJECT FileObject; 00024 LARGE_INTEGER FileOffset; 00025 ULONG Length; 00026 } WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD; 00027 00028 /* FUNCTIONS ******************************************************************/ 00029 00030 PDEVICE_OBJECT 00031 NTAPI 00032 MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject); 00033 00034 VOID 00035 NTAPI 00036 CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, 00037 IN ULONG Granularity) 00038 { 00039 PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; 00040 if (Map) 00041 { 00042 Map->ReadAheadGranularity = Granularity; 00043 } 00044 } 00045 00046 VOID 00047 NTAPI 00048 CcpReadAhead(PVOID Context) 00049 { 00050 LARGE_INTEGER Offset; 00051 PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context; 00052 PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap; 00053 00054 DPRINT1("Reading ahead %08x%08x:%x %wZ\n", 00055 WorkItem->FileOffset.HighPart, 00056 WorkItem->FileOffset.LowPart, 00057 WorkItem->Length, 00058 &WorkItem->FileObject->FileName); 00059 00060 Offset.HighPart = WorkItem->FileOffset.HighPart; 00061 Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart); 00062 if (Map) 00063 { 00064 PLIST_ENTRY ListEntry; 00065 volatile char *chptr; 00066 PNOCC_BCB Bcb; 00067 for (ListEntry = Map->AssociatedBcb.Flink; 00068 ListEntry != &Map->AssociatedBcb; 00069 ListEntry = ListEntry->Flink) 00070 { 00071 Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList); 00072 if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) || 00073 (Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart)) 00074 continue; 00075 for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset; 00076 chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length && 00077 Offset.QuadPart < 00078 WorkItem->FileOffset.QuadPart + WorkItem->Length; 00079 chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE) 00080 { 00081 *chptr ^= 0; 00082 } 00083 } 00084 } 00085 ObDereferenceObject(WorkItem->FileObject); 00086 ExFreePool(WorkItem); 00087 DPRINT("Done\n"); 00088 } 00089 00090 VOID 00091 NTAPI 00092 CcScheduleReadAhead(IN PFILE_OBJECT FileObject, 00093 IN PLARGE_INTEGER FileOffset, 00094 IN ULONG Length) 00095 { 00096 PWORK_QUEUE_WITH_READ_AHEAD WorkItem; 00097 00098 DPRINT("Schedule read ahead %08x%08x:%x %wZ\n", 00099 FileOffset->HighPart, 00100 FileOffset->LowPart, 00101 Length, 00102 &FileObject->FileName); 00103 00104 WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem)); 00105 if (!WorkItem) KeBugCheck(0); 00106 ObReferenceObject(FileObject); 00107 WorkItem->FileObject = FileObject; 00108 WorkItem->FileOffset = *FileOffset; 00109 WorkItem->Length = Length; 00110 00111 ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), 00112 (PWORKER_THREAD_ROUTINE)CcpReadAhead, 00113 WorkItem); 00114 00115 ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); 00116 DPRINT("Done\n"); 00117 } 00118 00119 VOID 00120 NTAPI 00121 CcSetDirtyPinnedData(IN PVOID BcbVoid, 00122 IN OPTIONAL PLARGE_INTEGER Lsn) 00123 { 00124 PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid; 00125 Bcb->Dirty = TRUE; 00126 } 00127 00128 LARGE_INTEGER 00129 NTAPI 00130 CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, 00131 IN BOOLEAN CcInternalCaller) 00132 { 00133 LARGE_INTEGER Result = {{0}}; 00134 UNIMPLEMENTED; 00135 while (TRUE); 00136 return Result; 00137 } 00138 00139 00140 00141 VOID 00142 NTAPI 00143 _CcpFlushCache(IN PNOCC_CACHE_MAP Map, 00144 IN OPTIONAL PLARGE_INTEGER FileOffset, 00145 IN ULONG Length, 00146 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus, 00147 BOOLEAN Delete, 00148 const char *File, 00149 int Line) 00150 { 00151 PNOCC_BCB Bcb = NULL; 00152 LARGE_INTEGER LowerBound, UpperBound; 00153 PLIST_ENTRY ListEntry; 00154 IO_STATUS_BLOCK IOSB; 00155 00156 RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK)); 00157 00158 DPRINT("CcFlushCache (while file) (%s:%d)\n", File, Line); 00159 00160 if (FileOffset && Length) 00161 { 00162 LowerBound.QuadPart = FileOffset->QuadPart; 00163 UpperBound.QuadPart = LowerBound.QuadPart + Length; 00164 } 00165 else 00166 { 00167 LowerBound.QuadPart = 0; 00168 UpperBound.QuadPart = 0x7fffffffffffffffull; 00169 } 00170 00171 CcpLock(); 00172 ListEntry = Map->AssociatedBcb.Flink; 00173 00174 while (ListEntry != &Map->AssociatedBcb) 00175 { 00176 Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList); 00177 CcpReferenceCache((ULONG)(Bcb - CcCacheSections)); 00178 00179 if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart && 00180 Bcb->FileOffset.QuadPart < UpperBound.QuadPart) 00181 { 00182 DPRINT("Bcb #%x (@%08x%08x)\n", 00183 Bcb - CcCacheSections, 00184 Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart); 00185 00186 Bcb->RefCount++; 00187 CcpUnlock(); 00188 MiFlushMappedSection(Bcb->BaseAddress, 00189 &Bcb->FileOffset, 00190 &Map->FileSizes.FileSize, 00191 Bcb->Dirty); 00192 CcpLock(); 00193 Bcb->RefCount--; 00194 00195 Bcb->Dirty = FALSE; 00196 00197 ListEntry = ListEntry->Flink; 00198 if (Delete && Bcb->RefCount < 2) 00199 { 00200 Bcb->RefCount = 1; 00201 CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE); 00202 } 00203 else 00204 { 00205 CcpUnpinData(Bcb, TRUE); 00206 } 00207 } 00208 else 00209 { 00210 ListEntry = ListEntry->Flink; 00211 CcpUnpinData(Bcb, TRUE); 00212 } 00213 00214 DPRINT("End loop\n"); 00215 } 00216 CcpUnlock(); 00217 00218 if (IoStatus) *IoStatus = IOSB; 00219 } 00220 00221 VOID 00222 NTAPI 00223 CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, 00224 IN OPTIONAL PLARGE_INTEGER FileOffset, 00225 IN ULONG Length, 00226 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus) 00227 { 00228 PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap; 00229 00230 /* Not cached */ 00231 if (!Map) 00232 { 00233 if (IoStatus) 00234 { 00235 IoStatus->Status = STATUS_SUCCESS; 00236 IoStatus->Information = 0; 00237 } 00238 return; 00239 } 00240 00241 CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE); 00242 } 00243 00244 BOOLEAN 00245 NTAPI 00246 CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, 00247 MMFLUSH_TYPE FlushType) 00248 { 00249 PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap; 00250 PNOCC_BCB Bcb; 00251 PLIST_ENTRY Entry; 00252 IO_STATUS_BLOCK IOSB; 00253 BOOLEAN Result = TRUE; 00254 00255 if (!Map) return TRUE; 00256 00257 for (Entry = Map->AssociatedBcb.Flink; 00258 Entry != &Map->AssociatedBcb; 00259 Entry = Entry->Flink) 00260 { 00261 Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList); 00262 00263 if (!Bcb->Dirty) continue; 00264 00265 switch (FlushType) 00266 { 00267 case MmFlushForDelete: 00268 CcPurgeCacheSection(SectionObjectPointer, 00269 &Bcb->FileOffset, 00270 Bcb->Length, 00271 FALSE); 00272 break; 00273 case MmFlushForWrite: 00274 CcFlushCache(SectionObjectPointer, 00275 &Bcb->FileOffset, 00276 Bcb->Length, 00277 &IOSB); 00278 break; 00279 } 00280 } 00281 00282 return Result; 00283 } 00284 00285 /* Always succeeds for us */ 00286 PVOID 00287 NTAPI 00288 CcRemapBcb(IN PVOID Bcb) 00289 { 00290 ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections); 00291 CcpLock(); 00292 ASSERT(RtlTestBit(CcCacheBitmap, Number)); 00293 CcpReferenceCache(Number); 00294 CcpUnlock(); 00295 return Bcb; 00296 } 00297 00298 VOID 00299 NTAPI 00300 CcShutdownSystem(VOID) 00301 { 00302 ULONG i, Result; 00303 NTSTATUS Status; 00304 00305 DPRINT1("CC: Shutdown\n"); 00306 00307 for (i = 0; i < CACHE_NUM_SECTIONS; i++) 00308 { 00309 PNOCC_BCB Bcb = &CcCacheSections[i]; 00310 if (Bcb->SectionObject) 00311 { 00312 DPRINT1("Evicting #%02x %08x%08x %wZ\n", 00313 i, 00314 Bcb->FileOffset.u.HighPart, 00315 Bcb->FileOffset.u.LowPart, 00316 &MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName); 00317 00318 CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE); 00319 Bcb->Dirty = FALSE; 00320 } 00321 } 00322 00323 /* Evict all section pages */ 00324 Status = MiRosTrimCache(~0, 0, &Result); 00325 00326 DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status); 00327 } 00328 00329 00330 VOID 00331 NTAPI 00332 CcRepinBcb(IN PVOID Bcb) 00333 { 00334 ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections); 00335 CcpLock(); 00336 ASSERT(RtlTestBit(CcCacheBitmap, Number)); 00337 DPRINT("CcRepinBcb(#%x)\n", Number); 00338 CcpReferenceCache(Number); 00339 CcpUnlock(); 00340 } 00341 00342 VOID 00343 NTAPI 00344 CcUnpinRepinnedBcb(IN PVOID Bcb, 00345 IN BOOLEAN WriteThrough, 00346 OUT PIO_STATUS_BLOCK IoStatus) 00347 { 00348 PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb; 00349 00350 if (WriteThrough) 00351 { 00352 DPRINT("BCB #%x\n", RealBcb - CcCacheSections); 00353 00354 CcpFlushCache(RealBcb->Map, 00355 &RealBcb->FileOffset, 00356 RealBcb->Length, 00357 IoStatus, 00358 RealBcb->Dirty); 00359 } 00360 00361 CcUnpinData(Bcb); 00362 } 00363 00364 /* EOF */ Generated on Fri May 25 2012 04:35:27 for ReactOS by
1.7.6.1
|