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
;
53 DPRINT("Reading ahead %08x%08x:%x %wZ\n",
54 WorkItem
->FileOffset
.HighPart
,
55 WorkItem
->FileOffset
.LowPart
,
57 &WorkItem
->FileObject
->FileName
);
58 Offset
.HighPart
= WorkItem
->FileOffset
.HighPart
;
59 Offset
.LowPart
= PAGE_ROUND_DOWN(WorkItem
->FileOffset
.LowPart
);
62 PLIST_ENTRY ListEntry
;
65 for (ListEntry
= Map
->AssociatedBcb
.Flink
;
66 ListEntry
!= &Map
->AssociatedBcb
;
67 ListEntry
= ListEntry
->Flink
)
69 Bcb
= CONTAINING_RECORD(ListEntry
, NOCC_BCB
, ThisFileList
);
70 if ((Offset
.QuadPart
+ WorkItem
->Length
< Bcb
->FileOffset
.QuadPart
) ||
71 (Bcb
->FileOffset
.QuadPart
+ Bcb
->Length
< Offset
.QuadPart
))
73 for (chptr
= Bcb
->BaseAddress
, Offset
= Bcb
->FileOffset
;
74 chptr
< ((PCHAR
)Bcb
->BaseAddress
) + Bcb
->Length
&&
76 WorkItem
->FileOffset
.QuadPart
+ WorkItem
->Length
;
77 chptr
+= PAGE_SIZE
, Offset
.QuadPart
+= PAGE_SIZE
)
83 ObDereferenceObject(WorkItem
->FileObject
);
90 CcScheduleReadAhead(IN PFILE_OBJECT FileObject
,
91 IN PLARGE_INTEGER FileOffset
,
94 PWORK_QUEUE_WITH_READ_AHEAD WorkItem
;
95 DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
99 &FileObject
->FileName
);
100 WorkItem
= ExAllocatePool(NonPagedPool
, sizeof(*WorkItem
));
101 if (!WorkItem
) KeBugCheck(0);
102 ObReferenceObject(FileObject
);
103 WorkItem
->FileObject
= FileObject
;
104 WorkItem
->FileOffset
= *FileOffset
;
105 WorkItem
->Length
= Length
;
106 ExInitializeWorkItem(((PWORK_QUEUE_ITEM
)WorkItem
), (PWORKER_THREAD_ROUTINE
)CcpReadAhead
, WorkItem
);
107 ExQueueWorkItem((PWORK_QUEUE_ITEM
)WorkItem
, DelayedWorkQueue
);
113 CcSetDirtyPinnedData(IN PVOID BcbVoid
,
114 IN OPTIONAL PLARGE_INTEGER Lsn
)
116 PNOCC_BCB Bcb
= (PNOCC_BCB
)BcbVoid
;
122 CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
123 IN BOOLEAN CcInternalCaller
)
125 LARGE_INTEGER Result
= {{0}};
135 _CcpFlushCache(IN PNOCC_CACHE_MAP Map
,
136 IN OPTIONAL PLARGE_INTEGER FileOffset
,
138 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
,
143 PNOCC_BCB Bcb
= NULL
;
144 LARGE_INTEGER LowerBound
, UpperBound
;
145 PLIST_ENTRY ListEntry
;
146 IO_STATUS_BLOCK IOSB
= { };
148 DPRINT1("CcFlushCache (while file) (%s:%d)\n", File
, Line
);
150 if (FileOffset
&& Length
)
152 LowerBound
.QuadPart
= FileOffset
->QuadPart
;
153 UpperBound
.QuadPart
= LowerBound
.QuadPart
+ Length
;
157 LowerBound
.QuadPart
= 0;
158 UpperBound
.QuadPart
= 0x7fffffffffffffffull
;
162 ListEntry
= Map
->AssociatedBcb
.Flink
;
164 while (ListEntry
!= &Map
->AssociatedBcb
)
166 Bcb
= CONTAINING_RECORD(ListEntry
, NOCC_BCB
, ThisFileList
);
167 CcpReferenceCache(Bcb
- CcCacheSections
);
169 if (Bcb
->FileOffset
.QuadPart
+ Bcb
->Length
>= LowerBound
.QuadPart
&&
170 Bcb
->FileOffset
.QuadPart
< UpperBound
.QuadPart
)
173 ("Bcb #%x (@%08x%08x)\n",
174 Bcb
- CcCacheSections
,
175 Bcb
->FileOffset
.u
.HighPart
, Bcb
->FileOffset
.u
.LowPart
);
179 MiFlushMappedSection(Bcb
->BaseAddress
, &Bcb
->FileOffset
, &Map
->FileSizes
.FileSize
, Bcb
->Dirty
);
185 ListEntry
= ListEntry
->Flink
;
186 if (Delete
&& Bcb
->RefCount
< 2)
189 CcpDereferenceCache(Bcb
- CcCacheSections
, FALSE
);
192 CcpUnpinData(Bcb
, TRUE
);
196 ListEntry
= ListEntry
->Flink
;
197 CcpUnpinData(Bcb
, TRUE
);
200 DPRINT("End loop\n");
204 if (IoStatus
) *IoStatus
= IOSB
;
209 CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
210 IN OPTIONAL PLARGE_INTEGER FileOffset
,
212 OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
)
214 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
221 IoStatus
->Status
= STATUS_SUCCESS
;
222 IoStatus
->Information
= 0;
227 CcpFlushCache(Map
, FileOffset
, Length
, IoStatus
, TRUE
);
233 (PSECTION_OBJECT_POINTERS SectionObjectPointer
,
234 MMFLUSH_TYPE FlushType
)
236 PNOCC_CACHE_MAP Map
= (PNOCC_CACHE_MAP
)SectionObjectPointer
->SharedCacheMap
;
239 IO_STATUS_BLOCK IOSB
;
240 BOOLEAN Result
= TRUE
;
242 if (!Map
) return TRUE
;
244 for (Entry
= Map
->AssociatedBcb
.Flink
;
245 Entry
!= &Map
->AssociatedBcb
;
246 Entry
= Entry
->Flink
)
248 Bcb
= CONTAINING_RECORD(Entry
, NOCC_BCB
, ThisFileList
);
250 if (!Bcb
->Dirty
) continue;
254 case MmFlushForDelete
:
256 (SectionObjectPointer
,
261 case MmFlushForWrite
:
263 (SectionObjectPointer
,
274 // Always succeeds for us
277 CcRemapBcb(IN PVOID Bcb
)
280 ASSERT(RtlTestBit(CcCacheBitmap
, ((PNOCC_BCB
)Bcb
) - CcCacheSections
));
281 CcpReferenceCache(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
292 DPRINT1("CC: Shutdown\n");
294 for (i
= 0; i
< CACHE_NUM_SECTIONS
; i
++)
296 PNOCC_BCB Bcb
= &CcCacheSections
[i
];
297 if (Bcb
->SectionObject
)
300 ("Evicting #%02x %08x%08x %wZ\n",
302 Bcb
->FileOffset
.u
.HighPart
, Bcb
->FileOffset
.u
.LowPart
,
303 &MmGetFileObjectForSection
304 ((PROS_SECTION_OBJECT
)Bcb
->SectionObject
)->FileName
);
305 CcpFlushCache(Bcb
->Map
, NULL
, 0, NULL
, TRUE
);
316 CcRepinBcb(IN PVOID Bcb
)
319 ASSERT(RtlTestBit(CcCacheBitmap
, ((PNOCC_BCB
)Bcb
) - CcCacheSections
));
320 DPRINT("CcRepinBcb(#%x)\n", ((PNOCC_BCB
)Bcb
) - CcCacheSections
);
321 CcpReferenceCache(((PNOCC_BCB
)Bcb
) - CcCacheSections
);
327 CcUnpinRepinnedBcb(IN PVOID Bcb
,
328 IN BOOLEAN WriteThrough
,
329 OUT PIO_STATUS_BLOCK IoStatus
)
331 PNOCC_BCB RealBcb
= (PNOCC_BCB
)Bcb
;
335 DPRINT("BCB #%x\n", RealBcb
- CcCacheSections
);
339 &RealBcb
->FileOffset
,
341 IoStatus
, RealBcb
->Dirty
);