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

restart.c File Reference

#include "lfsprocs.h"

Go to the source code of this file.

Defines

#define Dbg   (DEBUG_TRACE_RESTART)

Functions

VOID LfsSetBaseLsnPriv (IN PLFCB Lfcb, IN PLFS_CLIENT_RECORD ClientRecord, IN LSN BaseLsn)
NTSTATUS LfsReadRestartArea (IN LFS_LOG_HANDLE LogHandle, IN OUT PULONG BufferLength, IN PVOID Buffer, OUT PLSN Lsn)
VOID LfsWriteRestartArea (IN LFS_LOG_HANDLE LogHandle, IN ULONG BufferLength, IN PVOID Buffer, OUT PLSN Lsn)
VOID LfsSetBaseLsn (IN LFS_LOG_HANDLE LogHandle, IN LSN BaseLsn)


Define Documentation

#define Dbg   (DEBUG_TRACE_RESTART)
 

Definition at line 28 of file restart.c.


Function Documentation

NTSTATUS LfsReadRestartArea IN LFS_LOG_HANDLE  LogHandle,
IN OUT PULONG  BufferLength,
IN PVOID  Buffer,
OUT PLSN  Lsn
 

Definition at line 46 of file restart.c.

References Add2Ptr, Buffer, CcUnpinData(), _LFCB::ClientArray, _LCH::ClientArrayByteOffset, _LFS_RECORD_HEADER::ClientDataLength, _LFS_CLIENT_RECORD::ClientRestartLsn, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsCopyReadLogRecord(), LfsExceptionFilter(), LfsPinOrMapLogRecordHeader(), LfsReadRestartArea(), LfsReleaseLch, LfsReleaseLfcb, LfsValidateClientId, LfsValidateLch, LfsZeroLsn, NTSTATUS(), NULL, PAGED_CODE, Status, _LFS_RECORD_HEADER::ThisLsn, and try_return.

Referenced by LfsReadRestartArea().

00055 : 00056 00057 This routine is called by the client when he wishes to read his restart 00058 area in the log file. 00059 00060 Arguments: 00061 00062 LogHandle - Pointer to private Lfs structure used to identify this 00063 client. 00064 00065 BufferLength - On entry it is the length of the user buffer. On exit 00066 it is the size of the data stored in the buffer. 00067 00068 Buffer - Pointer to the buffer where the client restart data is to be 00069 copied. 00070 00071 Lsn - This is the Lsn for client restart area. 00072 00073 Return Value: 00074 00075 None 00076 00077 --*/ 00078 00079 { 00080 volatile NTSTATUS Status = STATUS_SUCCESS; 00081 00082 BOOLEAN UsaError; 00083 00084 PLCH Lch; 00085 00086 PLFS_CLIENT_RECORD ClientRecord; 00087 00088 PLFS_RECORD_HEADER RecordHeader; 00089 PBCB RecordHeaderBcb; 00090 00091 PLFCB Lfcb; 00092 NTSTATUS RetStatus = STATUS_SUCCESS; 00093 00094 00095 PAGED_CODE(); 00096 00097 DebugTrace( +1, Dbg, "LfsReadRestartArea: Entered\n", 0 ); 00098 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00099 DebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); 00100 DebugTrace( 0, Dbg, "Buffer -> %08lx\n", Buffer ); 00101 00102 RecordHeaderBcb = NULL; 00103 00104 Lch = (PLCH) LogHandle; 00105 00106 // 00107 // Check that the structure is a valid log handle structure. 00108 // 00109 00110 LfsValidateLch( Lch ); 00111 00112 // 00113 // Use a try-except to catch errors. 00114 // 00115 00116 try { 00117 00118 // 00119 // Use a try-finally to facilitate cleanup. 00120 // 00121 00122 try { 00123 00124 // 00125 // Acquire the log file control block for this log file. 00126 // 00127 00128 LfsAcquireLch( Lch ); 00129 Lfcb = Lch->Lfcb; 00130 00131 // 00132 // If the Log file has been closed then refuse access. 00133 // 00134 00135 if (Lfcb == NULL) { 00136 00137 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00138 } 00139 00140 // 00141 // Check that the client Id is valid. 00142 // 00143 00144 LfsValidateClientId( Lfcb, Lch ); 00145 00146 ClientRecord = Add2Ptr( Lfcb->ClientArray, 00147 Lch->ClientArrayByteOffset, 00148 PLFS_CLIENT_RECORD ); 00149 00150 // 00151 // If the client doesn't have a restart area, go ahead and exit 00152 // now. 00153 // 00154 00155 if ( ClientRecord->ClientRestartLsn.QuadPart == 0 ) { //**** xxEqlZero( ClientRecord->ClientRestartLsn ) 00156 00157 // 00158 // We show there is no restart area by returning a length 00159 // of zero. We also set the Lsn value to zero so that 00160 // we can catch it if the user tries to use the Lsn. 00161 // 00162 00163 DebugTrace( 0, Dbg, "No client restart area exists\n", 0 ); 00164 00165 *BufferLength = 0; 00166 *Lsn = LfsZeroLsn; 00167 00168 try_return( NOTHING ); 00169 } 00170 00171 // 00172 // Release the Lfcb as we won't be modifying any fields in it. 00173 // 00174 00175 LfsReleaseLfcb( Lfcb ); 00176 00177 // 00178 // Pin the log record for this Lsn. 00179 // 00180 00181 LfsPinOrMapLogRecordHeader( Lfcb, 00182 ClientRecord->ClientRestartLsn, 00183 FALSE, 00184 FALSE, 00185 &UsaError, 00186 &RecordHeader, 00187 &RecordHeaderBcb ); 00188 00189 // 00190 // If the Lsn values don't match, then the disk is corrupt. 00191 // 00192 00193 if ( ClientRecord->ClientRestartLsn.QuadPart != RecordHeader->ThisLsn.QuadPart ) { //**** xxNeq( ClientRecord->ClientRestartLsn, RecordHeader->ThisLsn ) 00194 00195 ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); 00196 } 00197 00198 00199 // 00200 // Check that the user's buffer is big enough to hold the restart 00201 // data. We raise an error status for this error. 00202 // 00203 00204 if (RecordHeader->ClientDataLength > *BufferLength) { 00205 00206 DebugTrace( 0, Dbg, "Client buffer is too small\n", 0 ); 00207 *BufferLength = RecordHeader->ClientDataLength; 00208 *Lsn = LfsZeroLsn; 00209 try_return( RetStatus = STATUS_BUFFER_TOO_SMALL ); 00210 } 00211 00212 00213 // 00214 // Use the cache manager to copy the data into the user's buffer. 00215 // 00216 00217 LfsCopyReadLogRecord( Lfcb, 00218 RecordHeader, 00219 Buffer ); 00220 00221 // 00222 // Pass the length and the Lsn of the restart area back to the 00223 // caller. 00224 // 00225 00226 *BufferLength = RecordHeader->ClientDataLength; 00227 *Lsn = RecordHeader->ThisLsn; 00228 00229 try_exit: NOTHING; 00230 } finally { 00231 00232 DebugUnwind( LfsReadRestartArea ); 00233 00234 // 00235 // Release the log file control block if held. 00236 // 00237 00238 LfsReleaseLch( Lch ); 00239 00240 // 00241 // Unpin the log record header for the client restart if pinned. 00242 // 00243 00244 if (RecordHeaderBcb != NULL) { 00245 00246 CcUnpinData( RecordHeaderBcb ); 00247 } 00248 00249 DebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn->LowPart ); 00250 DebugTrace( 0, Dbg, "Lsn (High) -> %08lx\n", Lsn->HighPart ); 00251 DebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); 00252 DebugTrace( -1, Dbg, "LfsReadRestartArea: Exit\n", 0 ); 00253 } 00254 00255 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00256 00257 Status = GetExceptionCode(); 00258 } 00259 00260 if (Status != STATUS_SUCCESS) { 00261 00262 ExRaiseStatus( Status ); 00263 } 00264 00265 return RetStatus; 00266 }

VOID LfsSetBaseLsn IN LFS_LOG_HANDLE  LogHandle,
IN LSN  BaseLsn
 

Definition at line 447 of file restart.c.

References Add2Ptr, _LFCB::ClientArray, _LCH::ClientArrayByteOffset, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsReleaseLch, LfsSetBaseLsn(), LfsSetBaseLsnPriv(), LfsValidateClientId, LfsValidateLch, LfsWriteLfsRestart(), NTSTATUS(), NULL, PAGED_CODE, _LFCB::RestartAreaSize, and Status.

Referenced by LfsSetBaseLsn().

00454 : 00455 00456 This routine is called by the client to notify the log service of the 00457 oldest Lsn he expects to need during restart. The Lfs is allowed to 00458 reuse any part of the circular log file which logically precedes 00459 this Lsn. A client may only specify a Lsn which follows the previous 00460 Lsn specified by this client. 00461 00462 Arguments: 00463 00464 LogHandle - Pointer to private Lfs structure used to identify this 00465 client. 00466 00467 BaseLsn - This is the oldest Lsn the client may require during a 00468 restart. 00469 00470 Return Value: 00471 00472 None 00473 00474 --*/ 00475 00476 { 00477 volatile NTSTATUS Status = STATUS_SUCCESS; 00478 00479 PLCH Lch; 00480 00481 PLFCB Lfcb; 00482 00483 PLFS_CLIENT_RECORD ClientRecord; 00484 00485 PAGED_CODE(); 00486 00487 DebugTrace( +1, Dbg, "LfsSetBaseLsn: Entered\n", 0 ); 00488 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00489 DebugTrace( 0, Dbg, "Base Lsn (Low) -> %08lx\n", BaseLsn.LowPart ); 00490 DebugTrace( 0, Dbg, "Base Lsn (High) -> %08lx\n", BaseLsn.HighPart ); 00491 00492 Lch = (PLCH) LogHandle; 00493 00494 // 00495 // Check that the structure is a valid log handle structure. 00496 // 00497 00498 LfsValidateLch( Lch ); 00499 00500 // 00501 // Use a try-except to catch errors. 00502 // 00503 00504 try { 00505 00506 // 00507 // Use a try-finally to facilitate cleanup. 00508 // 00509 00510 try { 00511 00512 // 00513 // Acquire the log file control block for this log file. 00514 // 00515 00516 LfsAcquireLch( Lch ); 00517 Lfcb = Lch->Lfcb; 00518 00519 // 00520 // If the Log file has been closed then refuse access. 00521 // 00522 00523 if (Lfcb == NULL) { 00524 00525 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00526 } 00527 00528 // 00529 // Check that the client Id is valid. 00530 // 00531 00532 LfsValidateClientId( Lfcb, Lch ); 00533 00534 ClientRecord = Add2Ptr( Lfcb->ClientArray, 00535 Lch->ClientArrayByteOffset, 00536 PLFS_CLIENT_RECORD ); 00537 00538 // 00539 // We simply call the worker routine to advance the base lsn. 00540 // If we moved forward in the file, we will put our restart area in the 00541 // queue. 00542 // 00543 00544 LfsSetBaseLsnPriv( Lfcb, 00545 ClientRecord, 00546 BaseLsn ); 00547 00548 LfsWriteLfsRestart( Lfcb, Lfcb->RestartAreaSize, FALSE ); 00549 00550 } finally { 00551 00552 DebugUnwind( LfsSetBaseLsn ); 00553 00554 // 00555 // Release the log file control block if held. 00556 // 00557 00558 LfsReleaseLch( Lch ); 00559 00560 DebugTrace( -1, Dbg, "LfsSetBaseLsn: Exit\n", 0 ); 00561 } 00562 00563 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00564 00565 Status = GetExceptionCode(); 00566 } 00567 00568 if (Status != STATUS_SUCCESS) { 00569 00570 ExRaiseStatus( Status ); 00571 } 00572 00573 return; 00574 }

VOID LfsSetBaseLsnPriv IN PLFCB  Lfcb,
IN PLFS_CLIENT_RECORD  ClientRecord,
IN LSN  BaseLsn
 

Definition at line 582 of file restart.c.

References ClearFlag, Dbg, DebugTrace, LFCB_NO_OLDEST_LSN, LfsFindCurrentAvail(), LfsFindOldestClientLsn(), LfsLsnToFileOffset, and PAGED_CODE.

Referenced by LfsSetBaseLsn(), and LfsWriteRestartArea().

00590 : 00591 00592 This worker routine is called internally by Lfs to modify the 00593 oldest Lsn a client expects to need during restart. The Lfs is allowed to 00594 reuse any part of the circular log file which logically precedes 00595 this Lsn. A client may only specify a Lsn which follows the previous 00596 Lsn specified by this client. 00597 00598 Arguments: 00599 00600 Lfcb - Log context block for this file. 00601 00602 ClientRecord - For the client whose base Lsn is being modified. 00603 00604 BaseLsn - This is the oldest Lsn the client may require during a 00605 restart. 00606 00607 Return Value: 00608 00609 None. 00610 00611 --*/ 00612 00613 { 00614 PAGED_CODE(); 00615 00616 DebugTrace( +1, Dbg, "LfsSetBaseLsn: Entered\n", 0 ); 00617 DebugTrace( 0, Dbg, "Lfcb -> %08lx\n", Lfcb ); 00618 DebugTrace( 0, Dbg, "Base Lsn (Low) -> %08lx\n", BaseLsn.LowPart ); 00619 DebugTrace( 0, Dbg, "Base Lsn (High) -> %08lx\n", BaseLsn.HighPart ); 00620 00621 // 00622 // We only proceed if the client is moving forward in the file. 00623 // 00624 00625 if ( BaseLsn.QuadPart > Lfcb->OldestLsn.QuadPart ) { //**** xxGtr( BaseLsn, Lfcb->OldestLsn ) 00626 00627 if ( BaseLsn.QuadPart > ClientRecord->OldestLsn.QuadPart ) { //**** xxGtr( BaseLsn, ClientRecord->OldestLsn ) 00628 00629 ClientRecord->OldestLsn = BaseLsn; 00630 } 00631 00632 Lfcb->OldestLsn = BaseLsn; 00633 00634 // 00635 // We walk through all the active clients and find the new 00636 // oldest Lsn for the log file. 00637 // 00638 00639 LfsFindOldestClientLsn( Lfcb->RestartArea, 00640 Lfcb->ClientArray, 00641 &Lfcb->OldestLsn ); 00642 00643 Lfcb->OldestLsnOffset = LfsLsnToFileOffset( Lfcb, Lfcb->OldestLsn ); 00644 ClearFlag( Lfcb->Flags, LFCB_NO_OLDEST_LSN ); 00645 00646 LfsFindCurrentAvail( Lfcb ); 00647 } 00648 00649 DebugTrace( -1, Dbg, "LfsSetBaseLsnPriv: Exit\n", 0 ); 00650 00651 return; 00652 }

VOID LfsWriteRestartArea IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  BufferLength,
IN PVOID  Buffer,
OUT PLSN  Lsn
 

Definition at line 270 of file restart.c.

References Add2Ptr, _LFS_WRITE_ENTRY::Buffer, Buffer, _LFS_WRITE_ENTRY::ByteLength, _LFCB::ClientArray, _LCH::ClientArrayByteOffset, _LFS_CLIENT_RECORD::ClientRestartLsn, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), _LCH::Lfcb, LfsAcquireLch, LfsClientRestart, LfsExceptionFilter(), LfsReleaseLch, LfsSetBaseLsnPriv(), LfsValidateClientId, LfsValidateLch, LfsWriteLfsRestart(), LfsWriteLogRecordIntoLogPage(), LfsWriteRestartArea(), LfsZeroLsn, NTSTATUS(), NULL, PAGED_CODE, _LFCB::RestartAreaSize, Status, and TRUE.

Referenced by LfsWriteRestartArea().

00279 : 00280 00281 This routine is called by the client to write a restart area to the 00282 disk. This routine will not return to the caller until the client 00283 restart area and all prior Lsn's have been flushed and the Lfs 00284 restart area on the disk has been updated. 00285 00286 On return, all log records up to and including 'Lsn' have been flushed 00287 to the disk. 00288 00289 Arguments: 00290 00291 LogHandle - Pointer to private Lfs structure used to identify this 00292 client. 00293 00294 BufferLength - On entry it is the length of the user buffer. 00295 00296 Buffer - Pointer to the buffer where the client restart data resides. 00297 00298 Lsn - This is the Lsn for this write operation. On input, this will be the 00299 new Base Lsn for this client. 00300 00301 **** This was used to prevent adding an interface change to 00302 the Beta release. 00303 00304 Return Value: 00305 00306 None 00307 00308 --*/ 00309 00310 { 00311 volatile NTSTATUS Status = STATUS_SUCCESS; 00312 00313 PLCH Lch; 00314 00315 PLFCB Lfcb; 00316 00317 PLFS_CLIENT_RECORD ClientRecord; 00318 00319 LFS_WRITE_ENTRY WriteEntry; 00320 00321 PAGED_CODE(); 00322 00323 DebugTrace( +1, Dbg, "LfsWriteRestartArea: Entered\n", 0 ); 00324 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00325 DebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", BufferLength ); 00326 DebugTrace( 0, Dbg, "Buffer -> %08lx\n", Buffer ); 00327 00328 Lch = (PLCH) LogHandle; 00329 00330 // 00331 // Check that the structure is a valid log handle structure. 00332 // 00333 00334 LfsValidateLch( Lch ); 00335 00336 // 00337 // Use a try-except to catch errors. 00338 // 00339 00340 try { 00341 00342 // 00343 // Use a try-finally to facilitate cleanup. 00344 // 00345 00346 try { 00347 00348 // 00349 // Acquire the log file control block for this log file. 00350 // 00351 00352 LfsAcquireLch( Lch ); 00353 Lfcb = Lch->Lfcb; 00354 00355 // 00356 // If the Log file has been closed then refuse access. 00357 // 00358 00359 if (Lfcb == NULL) { 00360 00361 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00362 } 00363 00364 // 00365 // Check that the client Id is valid. 00366 // 00367 00368 LfsValidateClientId( Lfcb, Lch ); 00369 00370 ClientRecord = Add2Ptr( Lfcb->ClientArray, 00371 Lch->ClientArrayByteOffset, 00372 PLFS_CLIENT_RECORD ); 00373 00374 // 00375 // Go ahead and update the Base Lsn in the client area if the value 00376 // given is not zero. 00377 // 00378 00379 if ( Lsn->QuadPart != 0 ) { //**** xxNeqZero( *Lsn ) 00380 00381 LfsSetBaseLsnPriv( Lfcb, 00382 ClientRecord, 00383 *Lsn ); 00384 } 00385 00386 // 00387 // Write this restart area as a log record into a log page. 00388 // 00389 00390 WriteEntry.Buffer = Buffer; 00391 WriteEntry.ByteLength = BufferLength; 00392 00393 LfsWriteLogRecordIntoLogPage( Lfcb, 00394 Lch, 00395 1, 00396 &WriteEntry, 00397 LfsClientRestart, 00398 NULL, 00399 LfsZeroLsn, 00400 LfsZeroLsn, 00401 0, 00402 TRUE, 00403 Lsn ); 00404 00405 // 00406 // Update the restart area for the client. 00407 // 00408 00409 ClientRecord->ClientRestartLsn = *Lsn; 00410 00411 // 00412 // Write the restart area to the disk. 00413 // 00414 00415 LfsWriteLfsRestart( Lfcb, Lfcb->RestartAreaSize, TRUE ); 00416 00417 } finally { 00418 00419 DebugUnwind( LfsWriteRestartArea ); 00420 00421 // 00422 // Release the log file control block if still held. 00423 // 00424 00425 LfsReleaseLch( Lch ); 00426 00427 DebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn->LowPart ); 00428 DebugTrace( 0, Dbg, "Log (High) -> %08lx\n", Lsn->HighPart ); 00429 DebugTrace( -1, Dbg, "LfsWriteRestartArea: Exit\n", 0 ); 00430 } 00431 00432 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00433 00434 Status = GetExceptionCode(); 00435 } 00436 00437 if (Status != STATUS_SUCCESS) { 00438 00439 ExRaiseStatus( Status ); 00440 } 00441 00442 return; 00443 }


Generated on Sat May 15 19:45:29 2004 for test by doxygen 1.3.7