Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

418 lines
7.5 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. StrucSup.c
  5. Abstract:
  6. This module provides support routines for creation and deletion
  7. of Lfs structures.
  8. Author:
  9. Brian Andrew [BrianAn] 20-June-1991
  10. Revision History:
  11. --*/
  12. #include "lfsprocs.h"
  13. //
  14. // The debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_STRUC_SUP)
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text(PAGE, LfsAllocateLbcb)
  19. #pragma alloc_text(PAGE, LfsAllocateLfcb)
  20. #pragma alloc_text(PAGE, LfsDeallocateLbcb)
  21. #pragma alloc_text(PAGE, LfsDeallocateLfcb)
  22. #endif
  23. PLFCB
  24. LfsAllocateLfcb (
  25. )
  26. /*++
  27. Routine Description:
  28. This routine allocates and initializes a log file control block.
  29. Arguments:
  30. Return Value:
  31. PLFCB - A pointer to the log file control block just
  32. allocated and initialized.
  33. --*/
  34. {
  35. PLFCB Lfcb = NULL;
  36. ULONG Count;
  37. PLBCB NextLbcb;
  38. PAGED_CODE();
  39. DebugTrace( +1, Dbg, "LfsAllocateLfcb: Entered\n", 0 );
  40. //
  41. // Use a try-finally to facilitate cleanup.
  42. //
  43. try {
  44. //
  45. // Allocate and zero the structure for the Lfcb.
  46. //
  47. Lfcb = FsRtlAllocatePool( PagedPool, sizeof( LFCB ));
  48. //
  49. // Zero out the structure initially.
  50. //
  51. RtlZeroMemory( Lfcb, sizeof( LFCB ));
  52. //
  53. // Initialize the log file control block.
  54. //
  55. Lfcb->NodeTypeCode = LFS_NTC_LFCB;
  56. Lfcb->NodeByteSize = sizeof( LFCB );
  57. //
  58. // Initialize the client links.
  59. //
  60. InitializeListHead( &Lfcb->LchLinks );
  61. //
  62. // Initialize the Lbcb links.
  63. //
  64. InitializeListHead( &Lfcb->LbcbWorkque );
  65. InitializeListHead( &Lfcb->LbcbActive );
  66. //
  67. // Initialize and allocate the spare Lbcb queue.
  68. //
  69. InitializeListHead( &Lfcb->SpareLbcbList );
  70. for (Count = 0; Count < LFCB_RESERVE_LBCB_COUNT; Count++ ) {
  71. NextLbcb = ExAllocatePoolWithTag( PagedPool, sizeof( LBCB ), ' sfL' );
  72. if (NextLbcb != NULL) {
  73. InsertHeadList( &Lfcb->SpareLbcbList, (PLIST_ENTRY) NextLbcb );
  74. Lfcb->SpareLbcbCount += 1;
  75. }
  76. }
  77. //
  78. // Allocate the Lfcb synchronization event.
  79. //
  80. Lfcb->Sync = FsRtlAllocatePool( NonPagedPool, sizeof( LFCB_SYNC ));
  81. ExInitializeResource( &Lfcb->Sync->Resource );
  82. //
  83. // Initialize the pseudo Lsn for the restart Lbcb's
  84. //
  85. Lfcb->NextRestartLsn = LfsLi1;
  86. //
  87. // Initialize the event to the signalled state.
  88. //
  89. KeInitializeEvent( &Lfcb->Sync->Event, NotificationEvent, TRUE );
  90. Lfcb->Sync->UserCount = 0;
  91. } finally {
  92. DebugUnwind( LfsAllocateFileControlBlock );
  93. if (AbnormalTermination()
  94. && Lfcb != NULL) {
  95. LfsDeallocateLfcb( Lfcb, TRUE );
  96. Lfcb = NULL;
  97. }
  98. DebugTrace( -1, Dbg, "LfsAllocateLfcb: Exit -> %08lx\n", Lfcb );
  99. }
  100. return Lfcb;
  101. }
  102. VOID
  103. LfsDeallocateLfcb (
  104. IN PLFCB Lfcb,
  105. IN BOOLEAN CompleteTeardown
  106. )
  107. /*++
  108. Routine Description:
  109. This routine releases the resources associated with a log file control
  110. block.
  111. Arguments:
  112. Lfcb - Supplies a pointer to the log file control block.
  113. CompleteTeardown - Indicates if we are to completely remove this Lfcb.
  114. Return Value:
  115. None
  116. --*/
  117. {
  118. PLBCB NextLbcb;
  119. PAGED_CODE();
  120. DebugTrace( +1, Dbg, "LfsDeallocateLfcb: Entered\n", 0 );
  121. DebugTrace( 0, Dbg, "Lfcb -> %08lx\n", Lfcb );
  122. //
  123. // Check that there are no buffer blocks.
  124. //
  125. ASSERT( IsListEmpty( &Lfcb->LbcbActive ));
  126. ASSERT( IsListEmpty( &Lfcb->LbcbWorkque ));
  127. //
  128. // Check that we have no clients.
  129. //
  130. ASSERT( IsListEmpty( &Lfcb->LchLinks ));
  131. //
  132. // If there is a restart area we deallocate it.
  133. //
  134. if (Lfcb->RestartArea != NULL) {
  135. LfsDeallocateRestartArea( Lfcb->RestartArea );
  136. }
  137. //
  138. // If there are any of the tail Lbcb's, deallocate them now.
  139. //
  140. if (Lfcb->ActiveTail != NULL) {
  141. LfsDeallocateLbcb( Lfcb, Lfcb->ActiveTail );
  142. Lfcb->ActiveTail = NULL;
  143. }
  144. if (Lfcb->PrevTail != NULL) {
  145. LfsDeallocateLbcb( Lfcb, Lfcb->PrevTail );
  146. Lfcb->PrevTail = NULL;
  147. }
  148. //
  149. // Only do the following if we are to remove the Lfcb completely.
  150. //
  151. if (CompleteTeardown) {
  152. //
  153. // If there is a resource structure we deallocate it.
  154. //
  155. if (Lfcb->Sync != NULL) {
  156. ExDeleteResource( &Lfcb->Sync->Resource );
  157. ExFreePool( Lfcb->Sync );
  158. }
  159. }
  160. //
  161. // Deallocate all of the spare Lbcb's.
  162. //
  163. while (!IsListEmpty( &Lfcb->SpareLbcbList )) {
  164. NextLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink;
  165. RemoveHeadList( &Lfcb->SpareLbcbList );
  166. ExFreePool( NextLbcb );
  167. }
  168. //
  169. // Discard the Lfcb structure.
  170. //
  171. ExFreePool( Lfcb );
  172. DebugTrace( -1, Dbg, "LfsDeallocateLfcb: Exit\n", 0 );
  173. return;
  174. }
  175. VOID
  176. LfsAllocateLbcb (
  177. IN PLFCB Lfcb,
  178. OUT PLBCB *Lbcb
  179. )
  180. /*++
  181. Routine Description:
  182. This routine will allocate the next Lbcb. If the pool allocation fails
  183. we will look at the private queue of Lbcb's.
  184. Arguments:
  185. Lfcb - Supplies a pointer to the log file control block.
  186. Lbcb - Address to store the allocated Lbcb.
  187. Return Value:
  188. None
  189. --*/
  190. {
  191. PLBCB NewLbcb = NULL;
  192. PAGED_CODE();
  193. //
  194. // If there are enough entries on the look-aside list then get one from
  195. // there.
  196. //
  197. if (Lfcb->SpareLbcbCount > LFCB_RESERVE_LBCB_COUNT) {
  198. NewLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink;
  199. Lfcb->SpareLbcbCount -= 1;
  200. RemoveHeadList( &Lfcb->SpareLbcbList );
  201. //
  202. // Otherwise try to allocate from pool.
  203. //
  204. } else {
  205. NewLbcb = ExAllocatePoolWithTag( PagedPool, sizeof( LBCB ), ' sfL' );
  206. }
  207. //
  208. // If we didn't get one then look at the look-aside list.
  209. //
  210. if (NewLbcb == NULL) {
  211. if (Lfcb->SpareLbcbCount != 0) {
  212. NewLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink;
  213. Lfcb->SpareLbcbCount -= 1;
  214. RemoveHeadList( &Lfcb->SpareLbcbList );
  215. } else {
  216. ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
  217. }
  218. }
  219. //
  220. // Initialize the structure.
  221. //
  222. RtlZeroMemory( NewLbcb, sizeof( LBCB ));
  223. NewLbcb->NodeTypeCode = LFS_NTC_LBCB;
  224. NewLbcb->NodeByteSize = sizeof( LBCB );
  225. //
  226. // Return it to the user.
  227. //
  228. *Lbcb = NewLbcb;
  229. return;
  230. }
  231. VOID
  232. LfsDeallocateLbcb (
  233. IN PLFCB Lfcb,
  234. IN PLBCB Lbcb
  235. )
  236. /*++
  237. Routine Description:
  238. This routine will deallocate the Lbcb. If we need one for the look-aside
  239. list we will put it there.
  240. Arguments:
  241. Lfcb - Supplies a pointer to the log file control block.
  242. Lbcb - This is the Lbcb to deallocate.
  243. Return Value:
  244. None
  245. --*/
  246. {
  247. PAGED_CODE();
  248. //
  249. // Deallocate any restart area attached to this Lbcb.
  250. //
  251. if (FlagOn( Lbcb->LbcbFlags, LBCB_RESTART_LBCB ) &&
  252. (Lbcb->PageHeader != NULL)) {
  253. LfsDeallocateRestartArea( Lbcb->PageHeader );
  254. }
  255. //
  256. // Put this in the Lbcb queue if it is short.
  257. //
  258. if (Lfcb->SpareLbcbCount < LFCB_MAX_LBCB_COUNT) {
  259. InsertHeadList( &Lfcb->SpareLbcbList, (PLIST_ENTRY) Lbcb );
  260. Lfcb->SpareLbcbCount += 1;
  261. //
  262. // Otherwise just free the pool block.
  263. //
  264. } else {
  265. ExFreePool( Lbcb );
  266. }
  267. return;
  268. }