2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/cache/cachesup.c
5 * PURPOSE: Logging and configuration routines
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
10 /* INCLUDES *******************************************************************/
14 #include "section/newmm.h"
18 /* STRUCTURES *****************************************************************/
20 typedef struct _WORK_QUEUE_WITH_READ_AHEAD
22 WORK_QUEUE_ITEM WorkItem
;
23 PFILE_OBJECT FileObject
;
24 LARGE_INTEGER FileOffset
;
26 } WORK_QUEUE_WITH_READ_AHEAD
, *PWORK_QUEUE_WITH_READ_AHEAD
;
28 /* FUNCTIONS ******************************************************************/
32 MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject
);
36 CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject
,
39 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)FileObject
->SectionObjectPointer
->SharedCacheMap
;
42 Map
->ReadAheadGranularity
= Granularity
;
48 CcpReadAhead(PVOID Context
)
51 PWORK_QUEUE_WITH_READ_AHEAD WorkItem
= (PWORK_QUEUE_WITH_READ_AHEAD
)Context
;
52 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)WorkItem
->FileObject
->SectionObjectPointer
->SharedCacheMap
;
54 DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
55 WorkItem
->FileOffset
.HighPart
,
56 WorkItem
->FileOffset
.LowPart
,
58 &WorkItem
->FileObject
->FileName
);
60 Offset
.HighPart
= WorkItem
->FileOffset
.HighPart
;
61 Offset
.LowPart
= PAGE_ROUND_DOWN(WorkItem
->FileOffset
.LowPart
);
64 PLIST_ENTRY ListEntry
;
67 for (ListEntry
= Map
->AssociatedBcb
.Flink
;
68 ListEntry
!= &Map
->AssociatedBcb
;
69 ListEntry
= ListEntry
->Flink
)
71 Bcb
= CONTAINING_RECORD(ListEntry
, NOCC_BCB
, ThisFileList
);
72 if ((Offset
.QuadPart
+ WorkItem
->Length
< Bcb
->FileOffset
.QuadPart
) ||
73 (Bcb
->FileOffset
.QuadPart
+ Bcb
->Length
< Offset
.QuadPart
))
75 for (chptr
= Bcb
->BaseAddress
, Offset
= Bcb
->FileOffset
;
76 chptr
< ((PCHAR
)Bcb
->BaseAddress
) + Bcb
->Length
&&
78 WorkItem
->FileOffset
.QuadPart
+ WorkItem
->Length
;
79 chptr
+= PAGE_SIZE
, Offset
.QuadPart
+= PAGE_SIZE
)
85 ObDereferenceObject(WorkItem
->FileObject
);
92 CcScheduleReadAhead(IN PFILE_OBJECT FileObject
,
93 IN PLARGE_INTEGER FileOffset
,
96 PWORK_QUEUE_WITH_READ_AHEAD WorkItem
;
98 DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
102 &FileObject
->FileName
);
104 WorkItem
= ExAllocatePool(NonPagedPool
, sizeof(*WorkItem
));
105 if (!WorkItem
) KeBugCheck(0);
106 ObReferenceObject(FileObject
);
107 WorkItem
->FileObject
= FileObject
;
108 WorkItem
->FileOffset
= *FileOffset
;
109 WorkItem
->Length
= Length
;
111 ExInitializeWorkItem(((PWORK_QUEUE_ITEM
)WorkItem
),
112 (PWORKER_THREAD_ROUTINE
)CcpReadAhead
,
115 ExQueueWorkItem((PWORK_QUEUE_ITEM
)WorkItem
, DelayedWorkQueue
);
121 CcSetDirtyPinnedData(IN PVOID BcbVoid
,
122 IN OPTIONAL PLARGE_INTEGER Lsn
)
124 PNOCC_BCB Bcb
= (PNOCC_BCB
)BcbVoid
;
130 CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
131 IN BOOLEAN CcInternalCaller
)
133 LARGE_INTEGER Result
= {{0}};
135 ASSERT(FALSE
); // while (TRUE);
143 _CcpFlushCache(IN PNOCC_CACHE_MAP Map
,
144 IN OPTIONAL PLARGE_INTEGER FileOffset
,
146 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
,
151 PNOCC_BCB Bcb
= NULL
;
152 LARGE_INTEGER LowerBound
, UpperBound
;
153 PLIST_ENTRY ListEntry
;
154 IO_STATUS_BLOCK IOSB
;
156 RtlZeroMemory(&IOSB
, sizeof(IO_STATUS_BLOCK
));
158 DPRINT("CcFlushCache (while file) (%s:%d)\n", File
, Line
);
160 if (FileOffset
&& Length
)
162 LowerBound
.QuadPart
= FileOffset
->QuadPart
;
163 UpperBound
.QuadPart
= LowerBound
.QuadPart
+ Length
;
167 LowerBound
.QuadPart
= 0;
168 UpperBound
.QuadPart
= 0x7fffffffffffffffull
;
172 ListEntry
= Map
->AssociatedBcb
.Flink
;
174 while (ListEntry
!= &Map
->AssociatedBcb
)
176 Bcb
= CONTAINING_RECORD(ListEntry
, NOCC_BCB
, ThisFileList
);
177 CcpReferenceCache((ULONG
)(Bcb
- CcCacheSections
));
179 if (Bcb
->FileOffset
.QuadPart
+ Bcb
->Length
>= LowerBound
.QuadPart
&&
180 Bcb
->FileOffset
.QuadPart
< UpperBound
.QuadPart
)
182 DPRINT("Bcb #%x (@%08x%08x)\n",
183 Bcb
- CcCacheSections
,
184 Bcb
->FileOffset
.u
.HighPart
, Bcb
->FileOffset
.u
.LowPart
);
188 MiFlushMappedSection(Bcb
->BaseAddress
,
190 &Map
->FileSizes
.FileSize
,
197 ListEntry
= ListEntry
->Flink
;
198 if (Delete
&& Bcb
->RefCount
< 2)
201 CcpDereferenceCache((ULONG
)(Bcb
- CcCacheSections
), FALSE
);
205 CcpUnpinData(Bcb
, TRUE
);
210 ListEntry
= ListEntry
->Flink
;
211 CcpUnpinData(Bcb
, TRUE
);
214 DPRINT("End loop\n");
218 if (IoStatus
) *IoStatus
= IOSB
;
223 CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
224 IN OPTIONAL PLARGE_INTEGER FileOffset
,
226 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
)
228 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
235 IoStatus
->Status
= STATUS_SUCCESS
;
236 IoStatus
->Information
= 0;
241 CcpFlushCache(Map
, FileOffset
, Length
, IoStatus
, TRUE
);
246 CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer
,
247 MMFLUSH_TYPE FlushType
)
249 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
252 IO_STATUS_BLOCK IOSB
;
253 BOOLEAN Result
= TRUE
;
255 if (!Map
) return TRUE
;
257 for (Entry
= Map
->AssociatedBcb
.Flink
;
258 Entry
!= &Map
->AssociatedBcb
;
259 Entry
= Entry
->Flink
)
261 Bcb
= CONTAINING_RECORD(Entry
, NOCC_BCB
, ThisFileList
);
263 if (!Bcb
->Dirty
) continue;
267 case MmFlushForDelete
:
268 CcPurgeCacheSection(SectionObjectPointer
,
273 case MmFlushForWrite
:
274 CcFlushCache(SectionObjectPointer
,
285 /* Always succeeds for us */
288 CcRemapBcb(IN PVOID Bcb
)
290 ULONG Number
= (ULONG
)(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
292 ASSERT(RtlTestBit(CcCacheBitmap
, Number
));
293 CcpReferenceCache(Number
);
300 CcShutdownSystem(VOID
)
305 DPRINT1("CC: Shutdown\n");
307 for (i
= 0; i
< CACHE_NUM_SECTIONS
; i
++)
309 PNOCC_BCB Bcb
= &CcCacheSections
[i
];
310 if (Bcb
->SectionObject
)
312 DPRINT1("Evicting #%02x %08x%08x %wZ\n",
314 Bcb
->FileOffset
.u
.HighPart
,
315 Bcb
->FileOffset
.u
.LowPart
,
316 &MmGetFileObjectForSection((PROS_SECTION_OBJECT
)Bcb
->SectionObject
)->FileName
);
318 CcpFlushCache(Bcb
->Map
, NULL
, 0, NULL
, TRUE
);
323 /* Evict all section pages */
324 Status
= MiRosTrimCache(~0, 0, &Result
);
326 DPRINT1("Done (Evicted %d, Status %x)\n", Result
, Status
);
332 CcRepinBcb(IN PVOID Bcb
)
334 ULONG Number
= (ULONG
)(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
336 ASSERT(RtlTestBit(CcCacheBitmap
, Number
));
337 DPRINT("CcRepinBcb(#%x)\n", Number
);
338 CcpReferenceCache(Number
);
344 CcUnpinRepinnedBcb(IN PVOID Bcb
,
345 IN BOOLEAN WriteThrough
,
346 OUT PIO_STATUS_BLOCK IoStatus
)
348 PNOCC_BCB RealBcb
= (PNOCC_BCB
)Bcb
;
352 DPRINT("BCB #%x\n", RealBcb
- CcCacheSections
);
354 CcpFlushCache(RealBcb
->Map
,
355 &RealBcb
->FileOffset
,