Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

strucsup.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 StrucSup.c 00008 00009 Abstract: 00010 00011 This module provides support routines for creation and deletion 00012 of Lfs structures. 00013 00014 Author: 00015 00016 Brian Andrew [BrianAn] 20-June-1991 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "lfsprocs.h" 00023 00024 // 00025 // The debug trace level 00026 // 00027 00028 #define Dbg (DEBUG_TRACE_STRUC_SUP) 00029 00030 #ifdef ALLOC_PRAGMA 00031 #pragma alloc_text(PAGE, LfsAllocateLbcb) 00032 #pragma alloc_text(PAGE, LfsAllocateLfcb) 00033 #pragma alloc_text(PAGE, LfsDeallocateLbcb) 00034 #pragma alloc_text(PAGE, LfsDeallocateLfcb) 00035 #pragma alloc_text(PAGE, LfsAllocateLcb) 00036 #pragma alloc_text(PAGE, LfsDeallocateLcb) 00037 #endif 00038 00039 00040 PLFCB 00041 LfsAllocateLfcb ( 00042 ) 00043 00044 /*++ 00045 00046 Routine Description: 00047 00048 This routine allocates and initializes a log file control block. 00049 00050 Arguments: 00051 00052 Return Value: 00053 00054 PLFCB - A pointer to the log file control block just 00055 allocated and initialized. 00056 00057 --*/ 00058 00059 { 00060 PLFCB Lfcb = NULL; 00061 ULONG Count; 00062 PLBCB NextLbcb; 00063 PLCB NextLcb; 00064 00065 PAGED_CODE(); 00066 00067 DebugTrace( +1, Dbg, "LfsAllocateLfcb: Entered\n", 0 ); 00068 00069 // 00070 // Use a try-finally to facilitate cleanup. 00071 // 00072 00073 try { 00074 00075 // 00076 // Allocate and zero the structure for the Lfcb. 00077 // 00078 00079 Lfcb = FsRtlAllocatePool( PagedPool, sizeof( LFCB )); 00080 00081 // 00082 // Zero out the structure initially. 00083 // 00084 00085 RtlZeroMemory( Lfcb, sizeof( LFCB )); 00086 00087 // 00088 // Initialize the log file control block. 00089 // 00090 00091 Lfcb->NodeTypeCode = LFS_NTC_LFCB; 00092 Lfcb->NodeByteSize = sizeof( LFCB ); 00093 00094 // 00095 // Initialize the client links. 00096 // 00097 00098 InitializeListHead( &Lfcb->LchLinks ); 00099 00100 // 00101 // Initialize the Lbcb links. 00102 // 00103 00104 InitializeListHead( &Lfcb->LbcbWorkque ); 00105 InitializeListHead( &Lfcb->LbcbActive ); 00106 00107 // 00108 // Initialize and allocate the spare Lbcb queue. 00109 // 00110 00111 InitializeListHead( &Lfcb->SpareLbcbList ); 00112 00113 for (Count = 0; Count < LFCB_RESERVE_LBCB_COUNT; Count++) { 00114 00115 NextLbcb = ExAllocatePoolWithTag( PagedPool, sizeof( LBCB ), ' sfL' ); 00116 00117 if (NextLbcb != NULL) { 00118 00119 InsertHeadList( &Lfcb->SpareLbcbList, (PLIST_ENTRY) NextLbcb ); 00120 Lfcb->SpareLbcbCount += 1; 00121 } 00122 } 00123 00124 // 00125 // Initialize and allocate the spare Lcb queue. 00126 // 00127 00128 InitializeListHead( &Lfcb->SpareLcbList ); 00129 00130 for (Count = 0; Count < LFCB_RESERVE_LCB_COUNT; Count++) { 00131 00132 NextLcb = ExAllocatePoolWithTag( PagedPool, sizeof( LCB ), ' sfL' ); 00133 00134 if (NextLcb != NULL) { 00135 00136 InsertHeadList( &Lfcb->SpareLcbList, (PLIST_ENTRY) NextLcb ); 00137 Lfcb->SpareLcbCount += 1; 00138 } 00139 } 00140 00141 // 00142 // Allocate the Lfcb synchronization event. 00143 // 00144 00145 Lfcb->Sync = FsRtlAllocatePool( NonPagedPool, sizeof( LFCB_SYNC )); 00146 00147 ExInitializeResource( &Lfcb->Sync->Resource ); 00148 00149 // 00150 // Initialize the pseudo Lsn for the restart Lbcb's 00151 // 00152 00153 Lfcb->NextRestartLsn = LfsLi1; 00154 00155 // 00156 // Initialize the event to the signalled state. 00157 // 00158 00159 KeInitializeEvent( &Lfcb->Sync->Event, NotificationEvent, TRUE ); 00160 00161 Lfcb->Sync->UserCount = 0; 00162 00163 // 00164 // Initialize the spare list mutex 00165 // 00166 00167 ExInitializeFastMutex( &(Lfcb->Sync->SpareListMutex) ); 00168 00169 } finally { 00170 00171 DebugUnwind( LfsAllocateFileControlBlock ); 00172 00173 if (AbnormalTermination() 00174 && Lfcb != NULL) { 00175 00176 LfsDeallocateLfcb( Lfcb, TRUE ); 00177 Lfcb = NULL; 00178 } 00179 00180 DebugTrace( -1, Dbg, "LfsAllocateLfcb: Exit -> %08lx\n", Lfcb ); 00181 } 00182 00183 return Lfcb; 00184 } 00185 00186 00187 VOID 00188 LfsDeallocateLfcb ( 00189 IN PLFCB Lfcb, 00190 IN BOOLEAN CompleteTeardown 00191 ) 00192 00193 /*++ 00194 00195 Routine Description: 00196 00197 This routine releases the resources associated with a log file control 00198 block. 00199 00200 Arguments: 00201 00202 Lfcb - Supplies a pointer to the log file control block. 00203 00204 CompleteTeardown - Indicates if we are to completely remove this Lfcb. 00205 00206 Return Value: 00207 00208 None 00209 00210 --*/ 00211 00212 { 00213 PLBCB NextLbcb; 00214 PLCB NextLcb; 00215 00216 PAGED_CODE(); 00217 00218 DebugTrace( +1, Dbg, "LfsDeallocateLfcb: Entered\n", 0 ); 00219 DebugTrace( 0, Dbg, "Lfcb -> %08lx\n", Lfcb ); 00220 00221 // 00222 // Check that there are no buffer blocks. 00223 // 00224 00225 ASSERT( IsListEmpty( &Lfcb->LbcbActive )); 00226 ASSERT( IsListEmpty( &Lfcb->LbcbWorkque )); 00227 00228 // 00229 // Check that we have no clients. 00230 // 00231 00232 ASSERT( IsListEmpty( &Lfcb->LchLinks )); 00233 00234 // 00235 // If there is a restart area we deallocate it. 00236 // 00237 00238 if (Lfcb->RestartArea != NULL) { 00239 00240 LfsDeallocateRestartArea( Lfcb->RestartArea ); 00241 } 00242 00243 // 00244 // If there are any of the tail Lbcb's, deallocate them now. 00245 // 00246 00247 if (Lfcb->ActiveTail != NULL) { 00248 00249 LfsDeallocateLbcb( Lfcb, Lfcb->ActiveTail ); 00250 Lfcb->ActiveTail = NULL; 00251 } 00252 00253 if (Lfcb->PrevTail != NULL) { 00254 00255 LfsDeallocateLbcb( Lfcb, Lfcb->PrevTail ); 00256 Lfcb->PrevTail = NULL; 00257 } 00258 00259 // 00260 // Only do the following if we are to remove the Lfcb completely. 00261 // 00262 00263 if (CompleteTeardown) { 00264 00265 // 00266 // If there is a resource structure we deallocate it. 00267 // 00268 00269 if (Lfcb->Sync != NULL) { 00270 00271 ExDeleteResource( &Lfcb->Sync->Resource ); 00272 00273 ExFreePool( Lfcb->Sync ); 00274 } 00275 } 00276 00277 // 00278 // Deallocate all of the spare Lbcb's. 00279 // 00280 00281 while (!IsListEmpty( &Lfcb->SpareLbcbList )) { 00282 00283 NextLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink; 00284 00285 RemoveHeadList( &Lfcb->SpareLbcbList ); 00286 00287 ExFreePool( NextLbcb ); 00288 } 00289 00290 // 00291 // Deallocate all of the spare Lcb's. 00292 // 00293 00294 while (!IsListEmpty( &Lfcb->SpareLcbList )) { 00295 00296 NextLcb = (PLCB) Lfcb->SpareLcbList.Flink; 00297 00298 RemoveHeadList( &Lfcb->SpareLcbList ); 00299 00300 ExFreePool( NextLcb ); 00301 } 00302 00303 // 00304 // Discard the Lfcb structure. 00305 // 00306 00307 ExFreePool( Lfcb ); 00308 00309 DebugTrace( -1, Dbg, "LfsDeallocateLfcb: Exit\n", 0 ); 00310 return; 00311 } 00312 00313 00314 VOID 00315 LfsAllocateLbcb ( 00316 IN PLFCB Lfcb, 00317 OUT PLBCB *Lbcb 00318 ) 00319 00320 /*++ 00321 00322 Routine Description: 00323 00324 This routine will allocate the next Lbcb. If the pool allocation fails 00325 we will look at the private queue of Lbcb's. 00326 00327 Arguments: 00328 00329 Lfcb - Supplies a pointer to the log file control block. 00330 00331 Lbcb - Address to store the allocated Lbcb. 00332 00333 Return Value: 00334 00335 None 00336 00337 --*/ 00338 00339 { 00340 PLBCB NewLbcb = NULL; 00341 00342 PAGED_CODE(); 00343 00344 // 00345 // If there are enough entries on the look-aside list then get one from 00346 // there. 00347 // 00348 00349 if (Lfcb->SpareLbcbCount > LFCB_RESERVE_LBCB_COUNT) { 00350 00351 NewLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink; 00352 00353 Lfcb->SpareLbcbCount -= 1; 00354 RemoveHeadList( &Lfcb->SpareLbcbList ); 00355 00356 // 00357 // Otherwise try to allocate from pool. 00358 // 00359 00360 } else { 00361 00362 NewLbcb = ExAllocatePoolWithTag( PagedPool, sizeof( LBCB ), ' sfL' ); 00363 } 00364 00365 // 00366 // If we didn't get one then look at the look-aside list. 00367 // 00368 00369 if (NewLbcb == NULL) { 00370 00371 if (Lfcb->SpareLbcbCount != 0) { 00372 00373 NewLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink; 00374 00375 Lfcb->SpareLbcbCount -= 1; 00376 RemoveHeadList( &Lfcb->SpareLbcbList ); 00377 00378 } else { 00379 00380 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 00381 } 00382 } 00383 00384 // 00385 // Initialize the structure. 00386 // 00387 00388 RtlZeroMemory( NewLbcb, sizeof( LBCB )); 00389 NewLbcb->NodeTypeCode = LFS_NTC_LBCB; 00390 NewLbcb->NodeByteSize = sizeof( LBCB ); 00391 00392 // 00393 // Return it to the user. 00394 // 00395 00396 *Lbcb = NewLbcb; 00397 return; 00398 } 00399 00400 00401 VOID 00402 LfsDeallocateLbcb ( 00403 IN PLFCB Lfcb, 00404 IN PLBCB Lbcb 00405 ) 00406 00407 /*++ 00408 00409 Routine Description: 00410 00411 This routine will deallocate the Lbcb. If we need one for the look-aside 00412 list we will put it there. 00413 00414 Arguments: 00415 00416 Lfcb - Supplies a pointer to the log file control block. 00417 00418 Lbcb - This is the Lbcb to deallocate. 00419 00420 Return Value: 00421 00422 None 00423 00424 --*/ 00425 00426 { 00427 PAGED_CODE(); 00428 00429 // 00430 // Deallocate any restart area attached to this Lbcb. 00431 // 00432 00433 if (FlagOn( Lbcb->LbcbFlags, LBCB_RESTART_LBCB ) && 00434 (Lbcb->PageHeader != NULL)) { 00435 00436 LfsDeallocateRestartArea( Lbcb->PageHeader ); 00437 } 00438 00439 // 00440 // Put this in the Lbcb queue if it is short. 00441 // 00442 00443 if (Lfcb->SpareLbcbCount < LFCB_MAX_LBCB_COUNT) { 00444 00445 InsertHeadList( &Lfcb->SpareLbcbList, (PLIST_ENTRY) Lbcb ); 00446 Lfcb->SpareLbcbCount += 1; 00447 00448 // 00449 // Otherwise just free the pool block. 00450 // 00451 00452 } else { 00453 00454 ExFreePool( Lbcb ); 00455 } 00456 00457 return; 00458 } 00459 00460 00461 00462 VOID 00463 LfsAllocateLcb ( 00464 IN PLFCB Lfcb, 00465 OUT PLCB *NewLcb 00466 ) 00467 /*++ 00468 00469 Routine Description: 00470 00471 This routine will allocate an Lcb. If the pool fails we will fall back 00472 on our spare list. A failure then will result in an exception 00473 00474 Arguments: 00475 00476 Lfcb - Supplies a pointer to the log file control block. 00477 00478 Lcb - This will contain the new lcb 00479 00480 Return Value: 00481 00482 None 00483 00484 --*/ 00485 { 00486 00487 ExAcquireFastMutex( &(Lfcb->Sync->SpareListMutex) ); 00488 00489 try { 00490 00491 *NewLcb = NULL; 00492 if (Lfcb->SpareLcbCount < LFCB_RESERVE_LCB_COUNT) { 00493 (*NewLcb) = ExAllocatePoolWithTag( PagedPool, sizeof( LCB ), ' sfL' ); 00494 } 00495 00496 if ((*NewLcb) == NULL) { 00497 if (Lfcb->SpareLcbCount > 0) { 00498 *NewLcb = (PLCB) Lfcb->SpareLcbList.Flink; 00499 Lfcb->SpareLcbCount -= 1; 00500 RemoveHeadList( &Lfcb->SpareLcbList ); 00501 } else { 00502 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 00503 } 00504 } 00505 00506 RtlZeroMemory( (*NewLcb), sizeof( LCB ) ); 00507 (*NewLcb)->NodeTypeCode = LFS_NTC_LCB; 00508 (*NewLcb)->NodeByteSize = sizeof( LCB ); 00509 00510 } finally { 00511 ExReleaseFastMutex( &(Lfcb->Sync->SpareListMutex) ); 00512 } 00513 } 00514 00515 00516 00517 VOID 00518 LfsDeallocateLcb ( 00519 IN PLFCB Lfcb, 00520 IN PLCB Lcb 00521 ) 00522 /*++ 00523 00524 Routine Description: 00525 00526 This routine will deallocate an Lcb. We'll cache the old lcb if there 00527 aren't too many already on the spare list 00528 00529 Arguments: 00530 00531 Lfcb - Supplies a pointer to the log file control block. 00532 00533 Lcb - This will contain the lcb to release 00534 00535 Return Value: 00536 00537 None 00538 00539 --*/ 00540 00541 { 00542 if (Lcb->RecordHeaderBcb != NULL) { 00543 CcUnpinData( Lcb->RecordHeaderBcb ); 00544 } 00545 if ((Lcb->CurrentLogRecord != NULL) && Lcb->AuxilaryBuffer) { 00546 LfsFreeSpanningBuffer( Lcb->CurrentLogRecord ); 00547 } 00548 00549 ExAcquireFastMutex( &(Lfcb->Sync->SpareListMutex) ); 00550 00551 try { 00552 if (Lfcb->SpareLcbCount < LFCB_MAX_LCB_COUNT) { 00553 InsertHeadList( &Lfcb->SpareLcbList, (PLIST_ENTRY) Lcb ); 00554 Lfcb->SpareLcbCount += 1; 00555 } else { 00556 ExFreePool( Lcb ); 00557 } 00558 } finally { 00559 ExReleaseFastMutex( &(Lfcb->Sync->SpareListMutex) ); 00560 } 00561 } 00562 00563 00564

Generated on Sat May 15 19:41:53 2004 for test by doxygen 1.3.7