pagecach.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /*++
  2. Copyright (c) 2016 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. pagecach.h
  5. Abstract:
  6. This header contains definitions for integrating the page cache throughout
  7. the rest of I/O.
  8. Author:
  9. Evan Green 29-Jan-2016
  10. --*/
  11. //
  12. // ------------------------------------------------------------------- Includes
  13. //
  14. //
  15. // ---------------------------------------------------------------- Definitions
  16. //
  17. //
  18. // This flag is set to indicate that the page cache eviction operation is
  19. // executing as a result of a truncate.
  20. //
  21. #define PAGE_CACHE_EVICTION_FLAG_TRUNCATE 0x00000001
  22. //
  23. // This flag is set to indicate that the page cache eviction operation is
  24. // executing as a result of a delete. There should be no outstanding references
  25. // on the device or file.
  26. //
  27. #define PAGE_CACHE_EVICTION_FLAG_DELETE 0x00000002
  28. //
  29. // This flag is set to indicate that the page cache eviction operation is
  30. // executing as a result of a remove. There may be outstanding references on
  31. // the device or file, but all of its cache entries should be aggressively
  32. // removed.
  33. //
  34. #define PAGE_CACHE_EVICTION_FLAG_REMOVE 0x00000004
  35. //
  36. // Define the number of pages to clean if a random write stumbles into a page
  37. // cache that is too dirty.
  38. //
  39. #define PAGE_CACHE_DIRTY_PENANCE_PAGES 128
  40. //
  41. // ------------------------------------------------------ Data Type Definitions
  42. //
  43. //
  44. // -------------------------------------------------------------------- Globals
  45. //
  46. //
  47. // Store the global list of dirty file objects.
  48. //
  49. extern LIST_ENTRY IoFileObjectsDirtyList;
  50. //
  51. // -------------------------------------------------------- Function Prototypes
  52. //
  53. KSTATUS
  54. IopInitializePageCache (
  55. VOID
  56. );
  57. /*++
  58. Routine Description:
  59. This routine initializes the page cache.
  60. Arguments:
  61. None.
  62. Return Value:
  63. Status code.
  64. --*/
  65. PPAGE_CACHE_ENTRY
  66. IopLookupPageCacheEntry (
  67. PFILE_OBJECT FileObject,
  68. IO_OFFSET Offset
  69. );
  70. /*++
  71. Routine Description:
  72. This routine searches for a page cache entry based on the file object and
  73. offset. If found, this routine takes a reference on the page cache entry.
  74. Arguments:
  75. FileObject - Supplies a pointer to a file object for the device or file.
  76. Offset - Supplies an offset into the file or device.
  77. Return Value:
  78. Returns a pointer to the found page cache entry on success, or NULL on
  79. failure.
  80. --*/
  81. PPAGE_CACHE_ENTRY
  82. IopCreateOrLookupPageCacheEntry (
  83. PFILE_OBJECT FileObject,
  84. PVOID VirtualAddress,
  85. PHYSICAL_ADDRESS PhysicalAddress,
  86. IO_OFFSET Offset,
  87. PPAGE_CACHE_ENTRY LinkEntry,
  88. PBOOL EntryCreated
  89. );
  90. /*++
  91. Routine Description:
  92. This routine creates a page cache entry and inserts it into the cache. Or,
  93. if a page cache entry already exists for the supplied file object and
  94. offset, it returns the existing entry. The file object lock must be held
  95. exclusive already.
  96. Arguments:
  97. FileObject - Supplies a pointer to a file object for the device or file
  98. that owns the contents of the physical page.
  99. VirtualAddress - Supplies an optional virtual address of the page.
  100. PhysicalAddress - Supplies the physical address of the page.
  101. Offset - Supplies the offset into the file or device where the page is
  102. from.
  103. LinkEntry - Supplies an optional pointer to a page cache entry that is
  104. to share the physical address with this new page cache entry if it gets
  105. inserted.
  106. EntryCreated - Supplies an optional pointer that receives a boolean
  107. indicating whether or not a new page cache entry was created.
  108. Return Value:
  109. Returns a pointer to a page cache entry on success, or NULL on failure.
  110. --*/
  111. PPAGE_CACHE_ENTRY
  112. IopCreateAndInsertPageCacheEntry (
  113. PFILE_OBJECT FileObject,
  114. PVOID VirtualAddress,
  115. PHYSICAL_ADDRESS PhysicalAddress,
  116. IO_OFFSET Offset,
  117. PPAGE_CACHE_ENTRY LinkEntry
  118. );
  119. /*++
  120. Routine Description:
  121. This routine creates a page cache entry and inserts it into the cache. The
  122. caller should be certain that there is not another entry in the cache for
  123. the same file object and offset and that nothing else is in contention to
  124. create the same entry.
  125. Arguments:
  126. FileObject - Supplies a pointer to a file object for the device or file
  127. that owns the contents of the physical page.
  128. VirtualAddress - Supplies an optional virtual address of the page.
  129. PhysicalAddress - Supplies the physical address of the page.
  130. Offset - Supplies the offset into the file or device where the page is
  131. from.
  132. LinkEntry - Supplies an optional pointer to a page cache entry that is to
  133. share the physical address with the new page cache entry.
  134. Return Value:
  135. Returns a pointer to a page cache entry on success, or NULL on failure.
  136. --*/
  137. KSTATUS
  138. IopCopyAndCacheIoBuffer (
  139. PFILE_OBJECT FileObject,
  140. IO_OFFSET FileOffset,
  141. PIO_BUFFER Destination,
  142. UINTN CopySize,
  143. PIO_BUFFER Source,
  144. UINTN SourceSize,
  145. UINTN SourceCopyOffset,
  146. PUINTN BytesCopied
  147. );
  148. /*++
  149. Routine Description:
  150. This routine iterates over the source buffer, caching each page and copying
  151. the pages to the destination buffer starting at the given copy offsets and
  152. up to the given copy size. The file object lock must be held exclusive
  153. already.
  154. Arguments:
  155. FileObject - Supplies a pointer to the file object for the device or file
  156. that owns the data.
  157. FileOffset - Supplies an offset into the file that corresponds to the
  158. beginning of the source I/O buffer.
  159. Destination - Supplies a pointer to the destination I/O buffer.
  160. CopySize - Supplies the maximum number of bytes that can be copied
  161. to the destination.
  162. Source - Supplies a pointer to the source I/O buffer.
  163. SourceSize - Supplies the number of bytes in the source that should be
  164. cached.
  165. SourceCopyOffset - Supplies the offset into the source buffer where the
  166. copy to the destination should start.
  167. BytesCopied - Supplies a pointer that receives the number of bytes copied
  168. to the destination buffer.
  169. Return Value:
  170. Status code.
  171. --*/
  172. KSTATUS
  173. IopFlushPageCacheEntries (
  174. PFILE_OBJECT FileObject,
  175. IO_OFFSET Offset,
  176. ULONGLONG Size,
  177. ULONG Flags,
  178. PUINTN PageCount
  179. );
  180. /*++
  181. Routine Description:
  182. This routine flushes the page cache entries for the given file object
  183. starting at the given offset for the requested size. This routine does not
  184. return until all file data has successfully been written to disk. It does
  185. not guarantee that file meta-data has been flushed to disk.
  186. Arguments:
  187. FileObject - Supplies a pointer to a file object for the device or file.
  188. Offset - Supplies the offset from the beginning of the file or device where
  189. the flush should be done.
  190. Size - Supplies the size, in bytes, of the region to flush. Supply a value
  191. of -1 to flush from the given offset to the end of the file.
  192. Flags - Supplies a bitmask of I/O flags. See IO_FLAG_* for definitions.
  193. PageCount - Supplies an optional pointer describing how many pages to flush.
  194. On output this value will be decreased by the number of pages actually
  195. flushed. Supply NULL to flush all pages in the size range.
  196. Return Value:
  197. Status code.
  198. --*/
  199. VOID
  200. IopEvictPageCacheEntries (
  201. PFILE_OBJECT FileObject,
  202. IO_OFFSET Offset,
  203. ULONG Flags
  204. );
  205. /*++
  206. Routine Description:
  207. This routine attempts to evict the page cache entries for a given file or
  208. device, as specified by the file object. The flags specify how aggressive
  209. this routine should be. The file object lock must already be held exclusive.
  210. Arguments:
  211. FileObject - Supplies a pointer to a file object for the device or file.
  212. Offset - Supplies the starting offset into the file or device after which
  213. all page cache entries should be evicted.
  214. Flags - Supplies a bitmask of eviction flags. See
  215. PAGE_CACHE_EVICTION_FLAG_* for definitions.
  216. Return Value:
  217. None.
  218. --*/
  219. BOOL
  220. IopIsIoBufferPageCacheBacked (
  221. PFILE_OBJECT FileObject,
  222. PIO_BUFFER IoBuffer,
  223. IO_OFFSET Offset,
  224. UINTN SizeInBytes
  225. );
  226. /*++
  227. Routine Description:
  228. This routine determines whether or not the given I/O buffer with data
  229. targeting the given file object at the given offset is currently backed by
  230. the page cache. The caller is expected to synchronize with eviction via
  231. truncate.
  232. Arguments:
  233. FileObject - Supplies a pointer to a file object.
  234. IoBuffer - Supplies a pointer to an I/O buffer.
  235. Offset - Supplies an offset into the file or device object.
  236. SizeInBytes - Supplied the number of bytes in the I/O buffer that should be
  237. cache backed.
  238. Return Value:
  239. Returns TRUE if the I/O buffer is backed by valid page cache entries, or
  240. FALSE otherwise.
  241. --*/
  242. VOID
  243. IopSchedulePageCacheThread (
  244. VOID
  245. );
  246. /*++
  247. Routine Description:
  248. This routine schedules a cleaning of the page cache for some time in the
  249. future.
  250. Arguments:
  251. None.
  252. Return Value:
  253. None.
  254. --*/
  255. IO_OFFSET
  256. IopGetPageCacheEntryOffset (
  257. PPAGE_CACHE_ENTRY PageCacheEntry
  258. );
  259. /*++
  260. Routine Description:
  261. This routine gets the file or device offset of the given page cache entry.
  262. Arguments:
  263. PageCacheEntry - Supplies a pointer to a page cache entry.
  264. Return Value:
  265. Returns the file or device offset of the given page cache entry.
  266. --*/
  267. BOOL
  268. IopMarkPageCacheEntryClean (
  269. PPAGE_CACHE_ENTRY PageCacheEntry,
  270. BOOL MoveToCleanList
  271. );
  272. /*++
  273. Routine Description:
  274. This routine marks the given page cache entry as clean.
  275. Arguments:
  276. PageCacheEntry - Supplies a pointer to a page cache entry.
  277. MoveToCleanList - Supplies a boolean indicating if the page cache entry
  278. should be moved to the list of clean page cache entries.
  279. Return Value:
  280. Returns TRUE if it marked the entry clean or FALSE if the entry was already
  281. clean.
  282. --*/
  283. BOOL
  284. IopMarkPageCacheEntryDirty (
  285. PPAGE_CACHE_ENTRY PageCacheEntry
  286. );
  287. /*++
  288. Routine Description:
  289. This routine marks the given page cache entry as dirty. The file object
  290. lock must already be held.
  291. Arguments:
  292. PageCacheEntry - Supplies a pointer to a page cache entry.
  293. Return Value:
  294. Returns TRUE if it marked the entry dirty or FALSE if the entry was already
  295. dirty.
  296. --*/
  297. KSTATUS
  298. IopCopyIoBufferToPageCacheEntry (
  299. PPAGE_CACHE_ENTRY PageCacheEntry,
  300. ULONG PageOffset,
  301. PIO_BUFFER SourceBuffer,
  302. UINTN SourceOffset,
  303. ULONG ByteCount
  304. );
  305. /*++
  306. Routine Description:
  307. This routine copies up to a page from the given source buffer to the given
  308. page cache entry.
  309. Arguments:
  310. PageCacheEntry - Supplies a pointer to a page cache entry.
  311. PageOffset - Supplies an offset into the page where the copy should begin.
  312. SourceBuffer - Supplies a pointer to the source buffer where the data
  313. originates.
  314. SourceOffset - Supplies an offset into the the source buffer where the data
  315. copy should begin.
  316. ByteCount - Supplies the number of bytes to copy.
  317. Return Value:
  318. Status code.
  319. --*/
  320. BOOL
  321. IopCanLinkPageCacheEntry (
  322. PPAGE_CACHE_ENTRY PageCacheEntry,
  323. PFILE_OBJECT FileObject
  324. );
  325. /*++
  326. Routine Description:
  327. This routine determines if the given page cache entry could link with a
  328. page cache entry for the given file object.
  329. Arguments:
  330. PageCacheEntry - Supplies a pointer to a page cache entry.
  331. FileObject - Supplied a pointer to a file object.
  332. Return Value:
  333. Returns TRUE if the page cache entry could be linked to a page cache entry
  334. with the given file object or FALSE otherwise.
  335. --*/
  336. BOOL
  337. IopLinkPageCacheEntries (
  338. PPAGE_CACHE_ENTRY LowerEntry,
  339. PPAGE_CACHE_ENTRY UpperEntry
  340. );
  341. /*++
  342. Routine Description:
  343. This routine attempts to link the given link entry to the page cache entry
  344. so that they can begin sharing a physical page that is currently used by
  345. the link entry.
  346. Arguments:
  347. LowerEntry - Supplies a pointer to the lower (disk) level page cache entry
  348. whose physical address is to be modified. The caller should ensure that
  349. its reference on this entry does not come from an I/O buffer or else
  350. the physical address in the I/O buffer would be invalid. The file
  351. object lock for this entry must already be held exclusive.
  352. UpperEntry - Supplies a pointer to the upper (file) page cache entry
  353. that currently owns the physical page to be shared.
  354. Return Value:
  355. Returns TRUE if the two page cache entries are already connected or if the
  356. routine is successful. It returns FALSE otherwise and both page cache
  357. entries should continue to use their own physical pages.
  358. --*/
  359. VOID
  360. IopTrimPageCache (
  361. BOOL TimidEffort
  362. );
  363. /*++
  364. Routine Description:
  365. This routine removes as many clean page cache entries as is necessary to
  366. bring the size of the page cache back down to a reasonable level. It evicts
  367. the page cache entries in LRU order.
  368. Arguments:
  369. TimidEffort - Supplies a boolean indicating whether or not this function
  370. should only try once to acquire a file object lock before moving on.
  371. Set this to TRUE if this thread might already be holding file object
  372. locks.
  373. Return Value:
  374. None.
  375. --*/
  376. BOOL
  377. IopIsPageCacheTooDirty (
  378. VOID
  379. );
  380. /*++
  381. Routine Description:
  382. This routine determines if the page cache has an uncomfortable number of
  383. entries in it that are dirty. Dirty entries are dangerous because they
  384. prevent the page cache from shrinking if memory gets tight.
  385. Arguments:
  386. None.
  387. Return Value:
  388. TRUE if the page cache has too many dirty entries and adding new ones
  389. should generally be avoided.
  390. FALSE if the page cache is relatively clean.
  391. --*/
  392. COMPARISON_RESULT
  393. IopComparePageCacheEntries (
  394. PRED_BLACK_TREE Tree,
  395. PRED_BLACK_TREE_NODE FirstNode,
  396. PRED_BLACK_TREE_NODE SecondNode
  397. );
  398. /*++
  399. Routine Description:
  400. This routine compares two Red-Black tree nodes contained inside file
  401. objects.
  402. Arguments:
  403. Tree - Supplies a pointer to the Red-Black tree that owns both nodes.
  404. FirstNode - Supplies a pointer to the left side of the comparison.
  405. SecondNode - Supplies a pointer to the second side of the comparison.
  406. Return Value:
  407. Same if the two nodes have the same value.
  408. Ascending if the first node is less than the second node.
  409. Descending if the second node is less than the first node.
  410. --*/