test: restart.c File Reference

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 }