ReactOS  0.4.15-dev-3207-ga415bd4
cacheman.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/cc/cacheman.c
5  * PURPOSE: Cache manager
6  *
7  * PROGRAMMERS: David Welch (welch@cwcom.net)
8  * Pierre Schweitzer (pierre@reactos.org)
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
20 
21 static ULONG BugCheckFileId = 0x4 << 16;
22 
23 /* FUNCTIONS *****************************************************************/
24 
25 CODE_SEG("INIT")
26 VOID
27 NTAPI
29 {
30  /* Notify debugger */
33  "CCPF: InitializePrefetecher()\n");
34 
35  /* Setup the Prefetcher Data */
39 
40  /* FIXME: Setup the rest of the prefetecher */
41 }
42 
43 CODE_SEG("INIT")
44 BOOLEAN
46 {
47  ULONG Thread;
48 
49  CcInitView();
50 
51  /* Initialize lazy-writer lists */
56 
57  /* Define lazy writer threshold and the amount of workers,
58  * depending on the system type
59  */
61  switch (CcCapturedSystemSize)
62  {
63  case MmSmallSystem:
66  break;
67 
68  case MmMediumSystem:
71  break;
72 
73  case MmLargeSystem:
76  break;
77 
78  default:
81  break;
82  }
83 
84  /* Allocate a work item for all our threads */
86  {
88 
90  if (Item == NULL)
91  {
92  CcBugCheck(0, 0, 0);
93  }
94 
95  /* By default, it's obviously idle */
98  }
99 
100  /* Initialize our lazy writer */
103  /* Delay activation of the lazy writer */
106 
107  /* Lookaside list for our work items */
109 
110  return TRUE;
111 }
112 
113 VOID
114 NTAPI
116 {
117  /* NOTHING TO DO */
118 }
119 
120 /*
121  * @unimplemented
122  */
124 NTAPI
127  IN BOOLEAN BcbListHeld
128  )
129 {
131 
133 
134  i.QuadPart = 0;
135  return i;
136 }
137 
138 /*
139  * @unimplemented
140  */
141 PVOID
142 NTAPI
144  IN PVOID Bcb
145  )
146 {
148 
149  return 0;
150 }
151 
152 /*
153  * @unimplemented
154  */
155 VOID
156 NTAPI
160  IN ULONG Length
161  )
162 {
163  KIRQL OldIrql;
164  LARGE_INTEGER NewOffset;
165  PROS_SHARED_CACHE_MAP SharedCacheMap;
166  PPRIVATE_CACHE_MAP PrivateCacheMap;
167 
168  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
169  PrivateCacheMap = FileObject->PrivateCacheMap;
170 
171  /* If file isn't cached, or if read ahead is disabled, this is no op */
172  if (SharedCacheMap == NULL || PrivateCacheMap == NULL ||
173  BooleanFlagOn(SharedCacheMap->Flags, READAHEAD_DISABLED))
174  {
175  return;
176  }
177 
178  /* Round read length with read ahead mask */
179  Length = ROUND_UP(Length, PrivateCacheMap->ReadAheadMask + 1);
180  /* Compute the offset we'll reach */
181  NewOffset.QuadPart = FileOffset->QuadPart + Length;
182 
183  /* Lock read ahead spin lock */
184  KeAcquireSpinLock(&PrivateCacheMap->ReadAheadSpinLock, &OldIrql);
185  /* Easy case: the file is sequentially read */
187  {
188  /* If we went backward, this is no go! */
189  if (NewOffset.QuadPart < PrivateCacheMap->ReadAheadOffset[1].QuadPart)
190  {
191  KeReleaseSpinLock(&PrivateCacheMap->ReadAheadSpinLock, OldIrql);
192  return;
193  }
194 
195  /* FIXME: hackish, but will do the job for now */
196  PrivateCacheMap->ReadAheadOffset[1].QuadPart = NewOffset.QuadPart;
197  PrivateCacheMap->ReadAheadLength[1] = Length;
198  }
199  /* Other cases: try to find some logic in that mess... */
200  else
201  {
202  /* Let's check if we always read the same way (like going down in the file)
203  * and pretend it's enough for now
204  */
205  if (PrivateCacheMap->FileOffset2.QuadPart >= PrivateCacheMap->FileOffset1.QuadPart &&
206  FileOffset->QuadPart >= PrivateCacheMap->FileOffset2.QuadPart)
207  {
208  /* FIXME: hackish, but will do the job for now */
209  PrivateCacheMap->ReadAheadOffset[1].QuadPart = NewOffset.QuadPart;
210  PrivateCacheMap->ReadAheadLength[1] = Length;
211  }
212  else
213  {
214  /* FIXME: handle the other cases */
215  KeReleaseSpinLock(&PrivateCacheMap->ReadAheadSpinLock, OldIrql);
217  return;
218  }
219  }
220 
221  /* If read ahead isn't active yet */
222  if (!PrivateCacheMap->Flags.ReadAheadActive)
223  {
225 
226  /* It's active now!
227  * Be careful with the mask, you don't want to mess with node code
228  */
229  InterlockedOr((volatile long *)&PrivateCacheMap->UlongFlags, PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE);
230  KeReleaseSpinLock(&PrivateCacheMap->ReadAheadSpinLock, OldIrql);
231 
232  /* Get a work item */
233  WorkItem = ExAllocateFromNPagedLookasideList(&CcTwilightLookasideList);
234  if (WorkItem != NULL)
235  {
236  /* Reference our FO so that it doesn't go in between */
238 
239  /* We want to do read ahead! */
240  WorkItem->Function = ReadAhead;
241  WorkItem->Parameters.Read.FileObject = FileObject;
242 
243  /* Queue in the read ahead dedicated queue */
245 
246  return;
247  }
248 
249  /* Fail path: lock again, and revert read ahead active */
250  KeAcquireSpinLock(&PrivateCacheMap->ReadAheadSpinLock, &OldIrql);
251  InterlockedAnd((volatile long *)&PrivateCacheMap->UlongFlags, ~PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE);
252  }
253 
254  /* Done (fail) */
255  KeReleaseSpinLock(&PrivateCacheMap->ReadAheadSpinLock, OldIrql);
256 }
257 
258 /*
259  * @implemented
260  */
261 VOID
262 NTAPI
265  IN BOOLEAN DisableReadAhead,
266  IN BOOLEAN DisableWriteBehind
267  )
268 {
269  KIRQL OldIrql;
270  PROS_SHARED_CACHE_MAP SharedCacheMap;
271 
272  CCTRACE(CC_API_DEBUG, "FileObject=%p DisableReadAhead=%d DisableWriteBehind=%d\n",
273  FileObject, DisableReadAhead, DisableWriteBehind);
274 
275  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
276 
278 
279  if (DisableReadAhead)
280  {
281  SetFlag(SharedCacheMap->Flags, READAHEAD_DISABLED);
282  }
283  else
284  {
285  ClearFlag(SharedCacheMap->Flags, READAHEAD_DISABLED);
286  }
287 
288  if (DisableWriteBehind)
289  {
290  /* FIXME: also set flag 0x200 */
291  SetFlag(SharedCacheMap->Flags, WRITEBEHIND_DISABLED);
292  }
293  else
294  {
295  ClearFlag(SharedCacheMap->Flags, WRITEBEHIND_DISABLED);
296  }
298 }
299 
300 /*
301  * @unimplemented
302  */
303 VOID
304 NTAPI
306  IN PVOID Bcb,
307  IN PVOID Owner
308  )
309 {
311 
312  CCTRACE(CC_API_DEBUG, "Bcb=%p Owner=%p\n",
313  Bcb, Owner);
314 
316  {
317  DPRINT1("Current thread doesn't own resource!\n");
318  return;
319  }
320 
322 }
323 
324 /*
325  * @implemented
326  */
327 VOID
328 NTAPI
331  IN ULONG DirtyPageThreshold
332  )
333 {
335  PROS_SHARED_CACHE_MAP SharedCacheMap;
336 
337  CCTRACE(CC_API_DEBUG, "FileObject=%p DirtyPageThreshold=%lu\n",
338  FileObject, DirtyPageThreshold);
339 
340  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
341  if (SharedCacheMap != NULL)
342  {
343  SharedCacheMap->DirtyPageThreshold = DirtyPageThreshold;
344  }
345 
346  Fcb = FileObject->FsContext;
348  {
350  }
351 }
352 
353 /*
354  * @implemented
355  */
356 VOID
357 NTAPI
360  IN ULONG Granularity
361  )
362 {
363  PPRIVATE_CACHE_MAP PrivateMap;
364 
365  CCTRACE(CC_API_DEBUG, "FileObject=%p Granularity=%lu\n",
366  FileObject, Granularity);
367 
368  PrivateMap = FileObject->PrivateCacheMap;
369  PrivateMap->ReadAheadMask = Granularity - 1;
370 }
VOID CcPostWorkQueue(IN PWORK_QUEUE_ENTRY WorkItem, IN PLIST_ENTRY WorkQueue)
Definition: lazywrite.c:53
#define IN
Definition: typedefs.h:39
#define InterlockedAnd
Definition: interlocked.h:62
ULONG CcDirtyPageThreshold
Definition: view.c:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
FAST_MUTEX CompletedTracesLock
Definition: cc.h:164
PFSN_PREFETCHER_GLOBALS CcPfGlobals
Definition: cacheman.c:18
ULONG CcNumberWorkerThreads
Definition: lazywrite.c:48
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:411
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
VOID NTAPI CcPfInitializePrefetcher(VOID)
Definition: cacheman.c:28
#define TRUE
Definition: types.h:120
Definition: cdstruc.h:902
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
#define InsertTailList(ListHead, Entry)
VOID NTAPI CcSetBcbOwnerPointer(IN PVOID Bcb, IN PVOID Owner)
Definition: cacheman.c:305
VOID NTAPI CcShutdownSystem(VOID)
Definition: cacheman.c:115
ULONG ReadAheadMask
Definition: cctypes.h:75
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
enum _MM_SYSTEM_SIZE MM_SYSTEMSIZE
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: cacheman.c:263
LIST_ENTRY CcIdleWorkerThreadList
Definition: lazywrite.c:41
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
KDPC ScanDpc
Definition: cc.h:244
LIST_ENTRY CcRegularWorkQueue
Definition: lazywrite.c:40
unsigned char BOOLEAN
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
KTIMER ScanTimer
Definition: cc.h:245
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
VOID NTAPI CcInitView(VOID)
Definition: view.c:1355
#define WRITEBEHIND_DISABLED
Definition: cc.h:202
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1780
KIRQL OldIrql
Definition: mm.h:1502
KSPIN_LOCK ReadAheadSpinLock
Definition: cctypes.h:83
#define CC_API_DEBUG
Definition: cc.h:11
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
LIST_ENTRY CompletedTraces
Definition: cc.h:163
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
MM_SYSTEMSIZE NTAPI MmQuerySystemSize(VOID)
Definition: mmsup.c:257
VOID NTAPI CcScheduleReadAhead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: cacheman.c:157
LARGE_INTEGER NTAPI CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN BcbListHeld)
Definition: cacheman.c:125
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
Definition: cc.h:251
VOID NTAPI CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject, IN ULONG DirtyPageThreshold)
Definition: cacheman.c:329
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES
Definition: fsrtltypes.h:47
ULONG Flags
Definition: ntfs.h:536
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI CcWorkerThread(IN PVOID Parameter)
Definition: lazywrite.c:226
BOOLEAN CcPfEnablePrefetcher
Definition: cacheman.c:17
LARGE_INTEGER FileOffset1
Definition: cctypes.h:77
#define InterlockedOr
Definition: interlocked.h:224
MM_SYSTEMSIZE CcCapturedSystemSize
Definition: cacheman.c:19
PRIVATE_CACHE_MAP_FLAGS Flags
Definition: cctypes.h:72
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2045
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
LIST_ENTRY CcExpressWorkQueue
Definition: lazywrite.c:39
#define READAHEAD_DISABLED
Definition: cc.h:201
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
BOOLEAN CcInitializeCacheManager(VOID)
Definition: cacheman.c:45
PVOID NTAPI CcRemapBcb(IN PVOID Bcb)
Definition: cacheman.c:143
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cacheman.c:358
LARGE_INTEGER ReadAheadOffset[2]
Definition: cctypes.h:81
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1556
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER FileOffset2
Definition: cctypes.h:79
#define CcBugCheck(A, B, C)
Definition: cc.h:469
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
Definition: cc.h:278
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1658
ULONG ExCriticalWorkerThreads
Definition: work.c:34
#define UNIMPLEMENTED
Definition: debug.h:115
ERESOURCE Lock
Definition: cc.h:233
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID NTAPI CcScanDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: lazywrite.c:95
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
LIST_ENTRY ActiveTraces
Definition: cc.h:160
static ULONG BugCheckFileId
Definition: cacheman.c:21
_In_ PFCB Fcb
Definition: cdprocs.h:159
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
ULONG UlongFlags
Definition: cctypes.h:73
#define PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE
Definition: cctypes.h:64
LIST_ENTRY CcPostTickWorkQueue
Definition: lazywrite.c:42
#define DPFLTR_TRACE_LEVEL
Definition: kdtypes.h:32
ULONG DirtyPageThreshold
Definition: cc.h:188
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
LIST_ENTRY WorkQueue
Definition: cc.h:243
ULONG ReadAheadLength[2]
Definition: cctypes.h:82
NPAGED_LOOKASIDE_LIST CcTwilightLookasideList
Definition: lazywrite.c:38
LONGLONG QuadPart
Definition: typedefs.h:114