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}};
134 UNIMPLEMENTED_DBGBREAK();
142 _CcpFlushCache(IN PNOCC_CACHE_MAP Map
,
143 IN OPTIONAL PLARGE_INTEGER FileOffset
,
145 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
,
150 PNOCC_BCB Bcb
= NULL
;
151 LARGE_INTEGER LowerBound
, UpperBound
;
152 PLIST_ENTRY ListEntry
;
153 IO_STATUS_BLOCK IOSB
;
155 RtlZeroMemory(&IOSB
, sizeof(IO_STATUS_BLOCK
));
157 DPRINT("CcFlushCache (while file) (%s:%d)\n", File
, Line
);
159 if (FileOffset
&& Length
)
161 LowerBound
.QuadPart
= FileOffset
->QuadPart
;
162 UpperBound
.QuadPart
= LowerBound
.QuadPart
+ Length
;
166 LowerBound
.QuadPart
= 0;
167 UpperBound
.QuadPart
= 0x7fffffffffffffffull
;
171 ListEntry
= Map
->AssociatedBcb
.Flink
;
173 while (ListEntry
!= &Map
->AssociatedBcb
)
175 Bcb
= CONTAINING_RECORD(ListEntry
, NOCC_BCB
, ThisFileList
);
176 CcpReferenceCache((ULONG
)(Bcb
- CcCacheSections
));
178 if (Bcb
->FileOffset
.QuadPart
+ Bcb
->Length
>= LowerBound
.QuadPart
&&
179 Bcb
->FileOffset
.QuadPart
< UpperBound
.QuadPart
)
181 DPRINT("Bcb #%x (@%08x%08x)\n",
182 Bcb
- CcCacheSections
,
183 Bcb
->FileOffset
.u
.HighPart
, Bcb
->FileOffset
.u
.LowPart
);
187 MiFlushMappedSection(Bcb
->BaseAddress
,
189 &Map
->FileSizes
.FileSize
,
196 ListEntry
= ListEntry
->Flink
;
197 if (Delete
&& Bcb
->RefCount
< 2)
200 CcpDereferenceCache((ULONG
)(Bcb
- CcCacheSections
), FALSE
);
204 CcpUnpinData(Bcb
, TRUE
);
209 ListEntry
= ListEntry
->Flink
;
210 CcpUnpinData(Bcb
, TRUE
);
213 DPRINT("End loop\n");
217 if (IoStatus
) *IoStatus
= IOSB
;
222 CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
223 IN OPTIONAL PLARGE_INTEGER FileOffset
,
225 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
)
227 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
234 IoStatus
->Status
= STATUS_SUCCESS
;
235 IoStatus
->Information
= 0;
240 CcpFlushCache(Map
, FileOffset
, Length
, IoStatus
, TRUE
);
245 CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer
,
246 MMFLUSH_TYPE FlushType
)
248 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
251 IO_STATUS_BLOCK IOSB
;
252 BOOLEAN Result
= TRUE
;
254 if (!Map
) return TRUE
;
256 for (Entry
= Map
->AssociatedBcb
.Flink
;
257 Entry
!= &Map
->AssociatedBcb
;
258 Entry
= Entry
->Flink
)
260 Bcb
= CONTAINING_RECORD(Entry
, NOCC_BCB
, ThisFileList
);
262 if (!Bcb
->Dirty
) continue;
266 case MmFlushForDelete
:
267 CcPurgeCacheSection(SectionObjectPointer
,
272 case MmFlushForWrite
:
273 CcFlushCache(SectionObjectPointer
,
284 /* Always succeeds for us */
287 CcRemapBcb(IN PVOID Bcb
)
289 ULONG Number
= (ULONG
)(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
291 ASSERT(RtlTestBit(CcCacheBitmap
, Number
));
292 CcpReferenceCache(Number
);
299 CcShutdownSystem(VOID
)
304 DPRINT1("CC: Shutdown\n");
306 for (i
= 0; i
< CACHE_NUM_SECTIONS
; i
++)
308 PNOCC_BCB Bcb
= &CcCacheSections
[i
];
309 if (Bcb
->SectionObject
)
311 DPRINT1("Evicting #%02x %08x%08x %wZ\n",
313 Bcb
->FileOffset
.u
.HighPart
,
314 Bcb
->FileOffset
.u
.LowPart
,
315 &MmGetFileObjectForSection((PROS_SECTION_OBJECT
)Bcb
->SectionObject
)->FileName
);
317 CcpFlushCache(Bcb
->Map
, NULL
, 0, NULL
, TRUE
);
322 /* Evict all section pages */
323 Status
= MiRosTrimCache(~0, 0, &Result
);
325 DPRINT1("Done (Evicted %d, Status %x)\n", Result
, Status
);
331 CcRepinBcb(IN PVOID Bcb
)
333 ULONG Number
= (ULONG
)(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
335 ASSERT(RtlTestBit(CcCacheBitmap
, Number
));
336 DPRINT("CcRepinBcb(#%x)\n", Number
);
337 CcpReferenceCache(Number
);
343 CcUnpinRepinnedBcb(IN PVOID Bcb
,
344 IN BOOLEAN WriteThrough
,
345 OUT PIO_STATUS_BLOCK IoStatus
)
347 PNOCC_BCB RealBcb
= (PNOCC_BCB
)Bcb
;
351 DPRINT("BCB #%x\n", RealBcb
- CcCacheSections
);
353 CcpFlushCache(RealBcb
->Map
,
354 &RealBcb
->FileOffset
,