ReactOS  0.4.14-dev-49-gfb4591c
blocklist.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for blocklist.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (CACHE)
 
PCACHE_BLOCK CacheInternalGetBlockPointer (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
PCACHE_BLOCK CacheInternalFindBlock (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
PCACHE_BLOCK CacheInternalAddBlockToCache (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
BOOLEAN CacheInternalFreeBlock (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalCheckCacheSizeLimits (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalDumpBlockList (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalOptimizeBlockList (PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
 

Function Documentation

◆ CacheInternalAddBlockToCache()

PCACHE_BLOCK CacheInternalAddBlockToCache ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 91 of file blocklist.c.

92 {
93  PCACHE_BLOCK CacheBlock = NULL;
94 
95  TRACE("CacheInternalAddBlockToCache() BlockNumber = %d\n", BlockNumber);
96 
97  // Check the size of the cache so we don't exceed our limits
99 
100  // We will need to add the block to the
101  // drive's list of cached blocks. So allocate
102  // the block memory.
103  CacheBlock = FrLdrTempAlloc(sizeof(CACHE_BLOCK), TAG_CACHE_BLOCK);
104  if (CacheBlock == NULL)
105  {
106  return NULL;
107  }
108 
109  // Now initialize the structure and
110  // allocate room for the block data
111  RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK));
112  CacheBlock->BlockNumber = BlockNumber;
113  CacheBlock->BlockData = FrLdrTempAlloc(CacheDrive->BlockSize * CacheDrive->BytesPerSector,
115  if (CacheBlock->BlockData ==NULL)
116  {
117  FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
118  return NULL;
119  }
120 
121  // Now try to read in the block
122  if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer))
123  {
124  FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA);
125  FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
126  return NULL;
127  }
128  RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
129 
130  // Add it to our list of blocks managed by the cache
131  InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
132 
133  // Update the cache data
134  CacheBlockCount++;
135  CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
136 
137  CacheInternalDumpBlockList(CacheDrive);
138 
139  return CacheBlock;
140 }
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:126
#define TAG_CACHE_BLOCK
Definition: cache.h:24
ULONG CacheBlockCount
Definition: cache.c:33
VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:194
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define DiskReadBuffer
Definition: hardware.h:33
#define InsertTailList(ListHead, Entry)
VOID CacheInternalCheckCacheSizeLimits(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:177
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
PVOID BlockData
Definition: cache.h:43
#define TRACE(s)
Definition: solgame.cpp:4
ULONG BlockSize
Definition: cache.h:59
UCHAR DriveNumber
Definition: cache.h:56
LIST_ENTRY ListEntry
Definition: cache.h:37
#define TAG_CACHE_DATA
Definition: cache.h:23
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
SIZE_T CacheSizeCurrent
Definition: cache.c:35
ULONG BlockNumber
Definition: cache.h:39
ULONG BytesPerSector
Definition: cache.h:57
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by CacheInternalGetBlockPointer().

◆ CacheInternalCheckCacheSizeLimits()

VOID CacheInternalCheckCacheSizeLimits ( PCACHE_DRIVE  CacheDrive)

Definition at line 177 of file blocklist.c.

178 {
179  SIZE_T NewCacheSize;
180 
181  TRACE("CacheInternalCheckCacheSizeLimits()\n");
182 
183  // Calculate the size of the cache if we added a block
184  NewCacheSize = (CacheBlockCount + 1) * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
185 
186  // Check the new size against the cache size limit
187  if (NewCacheSize > CacheSizeLimit)
188  {
189  CacheInternalFreeBlock(CacheDrive);
190  CacheInternalDumpBlockList(CacheDrive);
191  }
192 }
ULONG CacheBlockCount
Definition: cache.c:33
VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:194
BOOLEAN CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:142
#define TRACE(s)
Definition: solgame.cpp:4
ULONG BlockSize
Definition: cache.h:59
ULONG_PTR SIZE_T
Definition: typedefs.h:78
ULONG CacheSizeLimit
Definition: cache.c:34
ULONG BytesPerSector
Definition: cache.h:57

Referenced by CacheInternalAddBlockToCache().

◆ CacheInternalDumpBlockList()

VOID CacheInternalDumpBlockList ( PCACHE_DRIVE  CacheDrive)

Definition at line 194 of file blocklist.c.

195 {
196  PCACHE_BLOCK CacheBlock;
197 
198  TRACE("Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber);
199  TRACE("BytesPerSector: %d.\n", CacheDrive->BytesPerSector);
200  TRACE("BlockSize: %d.\n", CacheDrive->BlockSize);
201  TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit);
202  TRACE("CacheSizeCurrent: %d.\n", CacheSizeCurrent);
203  TRACE("CacheBlockCount: %d.\n", CacheBlockCount);
204 
205  CacheBlock = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Flink, CACHE_BLOCK, ListEntry);
206  while (&CacheBlock->ListEntry != &CacheDrive->CacheBlockHead)
207  {
208  TRACE("Cache Block: CacheBlock: 0x%x\n", CacheBlock);
209  TRACE("Cache Block: Block Number: %d\n", CacheBlock->BlockNumber);
210  TRACE("Cache Block: Access Count: %d\n", CacheBlock->AccessCount);
211  TRACE("Cache Block: Block Data: 0x%x\n", CacheBlock->BlockData);
212  TRACE("Cache Block: Locked In Cache: %d\n", CacheBlock->LockedInCache);
213 
214  if (CacheBlock->BlockData == NULL)
215  {
216  BugCheck("CacheBlock->BlockData == NULL\n");
217  }
218 
219  CacheBlock = CONTAINING_RECORD(CacheBlock->ListEntry.Flink, CACHE_BLOCK, ListEntry);
220  }
221 }
ULONG CacheBlockCount
Definition: cache.c:33
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
smooth NULL
Definition: ftsmooth.c:416
PVOID BlockData
Definition: cache.h:43
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
ULONG AccessCount
Definition: cache.h:41
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define TRACE(s)
Definition: solgame.cpp:4
ULONG BlockSize
Definition: cache.h:59
UCHAR DriveNumber
Definition: cache.h:56
#define BugCheck(fmt,...)
Definition: debug.h:117
BOOLEAN LockedInCache
Definition: cache.h:40
LIST_ENTRY ListEntry
Definition: cache.h:37
ULONG CacheSizeLimit
Definition: cache.c:34
SIZE_T CacheSizeCurrent
Definition: cache.c:35
ULONG BlockNumber
Definition: cache.h:39
ULONG BytesPerSector
Definition: cache.h:57

Referenced by CacheInternalAddBlockToCache(), and CacheInternalCheckCacheSizeLimits().

◆ CacheInternalFindBlock()

PCACHE_BLOCK CacheInternalFindBlock ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 53 of file blocklist.c.

54 {
55  PCACHE_BLOCK CacheBlock = NULL;
56 
57  TRACE("CacheInternalFindBlock() BlockNumber = %d\n", BlockNumber);
58 
59  //
60  // Make sure the block list has entries before I start searching it.
61  //
62  if (!IsListEmpty(&CacheDrive->CacheBlockHead))
63  {
64  //
65  // Search the list and find the BIOS drive number
66  //
67  CacheBlock = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Flink, CACHE_BLOCK, ListEntry);
68 
69  while (&CacheBlock->ListEntry != &CacheDrive->CacheBlockHead)
70  {
71  //
72  // We found the block, so return it
73  //
74  if (CacheBlock->BlockNumber == BlockNumber)
75  {
76  //
77  // Increment the blocks access count
78  //
79  CacheBlock->AccessCount++;
80 
81  return CacheBlock;
82  }
83 
84  CacheBlock = CONTAINING_RECORD(CacheBlock->ListEntry.Flink, CACHE_BLOCK, ListEntry);
85  }
86  }
87 
88  return NULL;
89 }
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
smooth NULL
Definition: ftsmooth.c:416
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
ULONG AccessCount
Definition: cache.h:41
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define TRACE(s)
Definition: solgame.cpp:4
LIST_ENTRY ListEntry
Definition: cache.h:37
ULONG BlockNumber
Definition: cache.h:39

Referenced by CacheInternalGetBlockPointer().

◆ CacheInternalFreeBlock()

BOOLEAN CacheInternalFreeBlock ( PCACHE_DRIVE  CacheDrive)

Definition at line 142 of file blocklist.c.

143 {
144  PCACHE_BLOCK CacheBlockToFree;
145 
146  TRACE("CacheInternalFreeBlock()\n");
147 
148  // Get a pointer to the last item in the block list
149  // that isn't forced to be in the cache and remove
150  // it from the list
151  CacheBlockToFree = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Blink, CACHE_BLOCK, ListEntry);
152  while (&CacheBlockToFree->ListEntry != &CacheDrive->CacheBlockHead && CacheBlockToFree->LockedInCache)
153  {
154  CacheBlockToFree = CONTAINING_RECORD(CacheBlockToFree->ListEntry.Blink, CACHE_BLOCK, ListEntry);
155  }
156 
157  // No blocks left in cache that can be freed
158  // so just return
159  if (IsListEmpty(&CacheDrive->CacheBlockHead))
160  {
161  return FALSE;
162  }
163 
164  RemoveEntryList(&CacheBlockToFree->ListEntry);
165 
166  // Free the block memory and the block structure
167  FrLdrTempFree(CacheBlockToFree->BlockData, TAG_CACHE_DATA);
168  FrLdrTempFree(CacheBlockToFree, TAG_CACHE_BLOCK);
169 
170  // Update the cache data
171  CacheBlockCount--;
172  CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
173 
174  return TRUE;
175 }
#define TAG_CACHE_BLOCK
Definition: cache.h:24
ULONG CacheBlockCount
Definition: cache.c:33
#define TRUE
Definition: types.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
PVOID BlockData
Definition: cache.h:43
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
#define TRACE(s)
Definition: solgame.cpp:4
ULONG BlockSize
Definition: cache.h:59
BOOLEAN LockedInCache
Definition: cache.h:40
LIST_ENTRY ListEntry
Definition: cache.h:37
#define TAG_CACHE_DATA
Definition: cache.h:23
SIZE_T CacheSizeCurrent
Definition: cache.c:35
ULONG BytesPerSector
Definition: cache.h:57
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by CacheInternalCheckCacheSizeLimits(), and CacheReleaseMemory().

◆ CacheInternalGetBlockPointer()

PCACHE_BLOCK CacheInternalGetBlockPointer ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 28 of file blocklist.c.

29 {
30  PCACHE_BLOCK CacheBlock = NULL;
31 
32  TRACE("CacheInternalGetBlockPointer() BlockNumber = %d\n", BlockNumber);
33 
34  CacheBlock = CacheInternalFindBlock(CacheDrive, BlockNumber);
35 
36  if (CacheBlock != NULL)
37  {
38  TRACE("Cache hit! BlockNumber: %d CacheBlock->BlockNumber: %d\n", BlockNumber, CacheBlock->BlockNumber);
39 
40  return CacheBlock;
41  }
42 
43  TRACE("Cache miss! BlockNumber: %d\n", BlockNumber);
44 
45  CacheBlock = CacheInternalAddBlockToCache(CacheDrive, BlockNumber);
46 
47  // Optimize the block list so it has a LRU structure
48  CacheInternalOptimizeBlockList(CacheDrive, CacheBlock);
49 
50  return CacheBlock;
51 }
VOID CacheInternalOptimizeBlockList(PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
Definition: blocklist.c:223
PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
Definition: blocklist.c:91
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
PCACHE_BLOCK CacheInternalFindBlock(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
Definition: blocklist.c:53
ULONG BlockNumber
Definition: cache.h:39

Referenced by CacheReadDiskSectors().

◆ CacheInternalOptimizeBlockList()

VOID CacheInternalOptimizeBlockList ( PCACHE_DRIVE  CacheDrive,
PCACHE_BLOCK  CacheBlock 
)

Definition at line 223 of file blocklist.c.

224 {
225 
226  TRACE("CacheInternalOptimizeBlockList()\n");
227 
228  // Don't do this if this block is already at the head of the list
229  if (&CacheBlock->ListEntry != CacheDrive->CacheBlockHead.Flink)
230  {
231  // Remove this item from the block list
232  RemoveEntryList(&CacheBlock->ListEntry);
233 
234  // Re-insert it at the head of the list
235  InsertHeadList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
236  }
237 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define TRACE(s)
Definition: solgame.cpp:4
LIST_ENTRY ListEntry
Definition: cache.h:37

Referenced by CacheInternalGetBlockPointer().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( CACHE  )