test: rstrtsup.c File Reference

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

# rstrtsup.c File Reference

`#include "lfsprocs.h"`

Go to the source code of this file.

## Defines

#define | Dbg (DEBUG_TRACE_RESTART_SUP)

## Functions

VOID | LfsWriteLfsRestart (IN PLFCB Lfcb, IN ULONG ThisRestartSize, IN BOOLEAN WaitForIo)
VOID | LfsFindOldestClientLsn (IN PLFS_RESTART_AREA RestartArea, IN PLFS_CLIENT_RECORD ClientArray, OUT PLSN OldestLsn)

## Define Documentation

#define Dbg (DEBUG_TRACE_RESTART_SUP)

| Definition at line 27 of file rstrtsup.c.

## Function Documentation

VOID LfsFindOldestClientLsn | ( | IN PLFS_RESTART_AREA | RestartArea,
|  | IN PLFS_CLIENT_RECORD | ClientArray,
|  | OUT PLSN | OldestLsn
| ) |

Definition at line 189 of file rstrtsup.c.

References Dbg, DebugTrace, LFS_NO_CLIENT, _LFS_CLIENT_RECORD::NextClient, _LFS_CLIENT_RECORD::OldestLsn, PAGED_CODE, and USHORT.

Referenced by LfsSetBaseLsnPriv(), and LfsUpdateLfcbFromRestart().

    00197                    :
    00198
    00199     This routine walks through the active clients to determine the oldest
    00200     Lsn the system must maintain.
    00201
    00202 Arguments:
    00203
    00204     RestartArea - This is the Restart Area to examine.
    00205
    00206     ClientArray - This is the start of the client data array.
    00207
    00208     OldestLsn - We store the oldest Lsn we find in this value.  It is
    00209         initialized with a starting value, we won't return a more recent
    00210         Lsn.
    00211
    00212 Return Value:
    00213
    00214     None.
    00215
    00216 --*/
    00217
    00218 {
    00219     USHORT NextClient;
    00220
    00221     PLFS_CLIENT_RECORD ClientBlock;
    00222
    00223     PAGED_CODE();
    00224
    00225     DebugTrace( +1, Dbg, "LfsFindOldestClientLsn:  Entered\n", 0 );
    00226     DebugTrace(  0, Dbg, "RestartArea       -> %08lx\n", RestartArea );
    00227     DebugTrace(  0, Dbg, "Base Lsn (Low)    -> %08lx\n", BaseLsn.LowPart );
    00228     DebugTrace(  0, Dbg, "Base Lsn (High)   -> %08lx\n", BaseLsn.HighPart );
    00229
    00230     //
    00231     //  Take the first client off the in use list.
    00232     //
    00233
    00234     NextClient = RestartArea->ClientInUseList;
    00235
    00236     //
    00237     //  While there are more clients, compare their oldest Lsn with the
    00238     //  current oldest.
    00239     //
    00240
    00241     while (NextClient != LFS_NO_CLIENT) {
    00242
    00243         ClientBlock = ClientArray + NextClient;
    00244
    00245         //
    00246         //  We ignore this block if it's oldest Lsn is 0.
    00247         //
    00248
    00249         if (( ClientBlock->OldestLsn.QuadPart != 0 )
    00250             && ( ClientBlock->OldestLsn.QuadPart < OldestLsn->QuadPart )) {
    00251
    00252             *OldestLsn = ClientBlock->OldestLsn;
    00253         }
    00254
    00255         //
    00256         //  Try the next client block.
    00257         //
    00258
    00259         NextClient = ClientBlock->NextClient;
    00260     }
    00261
    00262     DebugTrace(  0, Dbg, "OldestLsn (Low)   -> %08lx\n", BaseLsn.LowPart );
    00263     DebugTrace(  0, Dbg, "OldestLsn (High)  -> %08lx\n", BaseLsn.HighPart );
    00264     DebugTrace( -1, Dbg, "LfsFindOldestClientLsn:  Exit\n", 0 );
    00265
    00266     return;
    00267 }

VOID LfsWriteLfsRestart | ( | IN PLFCB | Lfcb,
|  | IN ULONG | ThisRestartSize,
|  | IN BOOLEAN | WaitForIo
| ) |

Definition at line 36 of file rstrtsup.c.

References _LBCB::ActiveLinks, Add2Ptr, ClearFlag, _LFS_RESTART_AREA::ClientArrayOffset, Dbg, DebugTrace, DebugUnwind, ExFreePool(), _LBCB::FileOffset, FlagOn, _LBCB::LastEndLsn, _LBCB::LastLsn, LBCB_NOT_EMPTY, LBCB_ON_ACTIVE_QUEUE, LBCB_RESTART_LBCB, _LBCB::LbcbFlags, _LBCB::Length, LFCB_PACK_LOG, LfsAllocateLbcb(), LfsAllocateRestartArea, LfsFlushLbcb(), LfsWriteLfsRestart(), NULL, PAGED_CODE, _LBCB::PageHeader, SetFlag, and _LBCB::WorkqueLinks.

Referenced by LfsCloseLogFile(), LfsInitializeLogFilePriv(), LfsSetBaseLsn(), LfsWriteLfsRestart(), and LfsWriteRestartArea().

    00044                    :
    00045
    00046     This routine puts the Lfs restart area on the queue of operations to
    00047     write to the file.  We do this by allocating a second restart area
    00048     and attaching it to the Lfcb.  We also allocate a buffer control
    00049     block to use for this write.  We look at the WaitForIo boolean to
    00050     determine whether this thread can perform the I/O.  This also indicates
    00051     whether this thread gives up the Lfcb.
    00052
    00053 Arguments:
    00054
    00055     Lfcb - A pointer to the log file control block for this operation.
    00056
    00057     ThisRestartSize - This is the size to use for the restart area.
    00058
    00059     WaitForIo - Indicates if this thread is to perform the work.
    00060
    00061 Return Value:
    00062
    00063     None.
    00064
    00065 --*/
    00066
    00067 {
    00068     PLBCB NewLbcb = NULL;
    00069     PLFS_RESTART_AREA NewRestart = NULL;
    00070
    00071     PAGED_CODE();
    00072
    00073     DebugTrace( +1, Dbg, "LfsWriteLfsRestart:  Entered\n", 0 );
    00074     DebugTrace(  0, Dbg, "Lfcb          -> %08lx\n", Lfcb );
    00075     DebugTrace(  0, Dbg, "Write Chkdsk  -> %04x\n", WriteChkdsk );
    00076     DebugTrace(  0, Dbg, "Restart Size  -> %08lx\n", ThisRestartSize );
    00077     DebugTrace(  0, Dbg, "WaitForIo     -> %08lx\n", WaitForIo );
    00078
    00079     //
    00080     //  Use a try-finally to facilitate cleanup.
    00081     //
    00082
    00083     try {
    00084
    00085         PLBCB ActiveLbcb;
    00086
    00087         //
    00088         //  We allocate another restart area and
    00089         //  copy the current area into it.  Attach the new area to the Lfcb.
    00090         //
    00091
    00092         LfsAllocateRestartArea( &NewRestart, ThisRestartSize );
    00093
    00094         //
    00095         //  We allocate a Lbcb structure and update the values to
    00096         //  reflect this restart area.
    00097         //
    00098
    00099         LfsAllocateLbcb( Lfcb, &NewLbcb );
    00100         SetFlag( NewLbcb->LbcbFlags, LBCB_RESTART_LBCB );
    00101
    00102         //
    00103         //  If this is the second page, then add a system page to the offset.
    00104         //
    00105
    00106         if (!Lfcb->InitialRestartArea) {
    00107
    00108             NewLbcb->FileOffset = Lfcb->SystemPageSize + NewLbcb->FileOffset;
    00109         }
    00110
    00111         (ULONG)NewLbcb->Length = ThisRestartSize;
    00112
    00113         NewLbcb->PageHeader = (PVOID) Lfcb->RestartArea;
    00114
    00115         //
    00116         //  Lets put the current lsn in the Lbcb.
    00117         //
    00118
    00119         NewLbcb->LastEndLsn = NewLbcb->LastLsn = Lfcb->NextRestartLsn;
    00120         Lfcb->NextRestartLsn.QuadPart = 1 + Lfcb->NextRestartLsn.QuadPart;
    00121
    00122         //
    00123         //  Copy the existing restart area into the new area.
    00124         //
    00125
    00126         RtlCopyMemory( NewRestart, Lfcb->RestartArea, ThisRestartSize );
    00127         Lfcb->RestartArea = NewRestart;
    00128
    00129         Lfcb->ClientArray = Add2Ptr( NewRestart, Lfcb->ClientArrayOffset, PLFS_CLIENT_RECORD );
    00130
    00131         NewRestart = NULL;
    00132
    00133         //
    00134         //  Update the Lfcb to indicate that the other restart area
    00135         //  on the disk is to be used.
    00136         //
    00137
    00138         Lfcb->InitialRestartArea = !Lfcb->InitialRestartArea;
    00139
    00140         //
    00141         //  Add this Lbcb to the end of the workque and flush to that point.
    00142         //
    00143
    00144         InsertTailList( &Lfcb->LbcbWorkque, &NewLbcb->WorkqueLinks );
    00145
    00146         //
    00147         //  If we don't support a packed log file then we need to make
    00148         //  sure that all file records written out ahead of this
    00149         //  restart area make it out to disk and we don't add anything
    00150         //  to this page.
    00151         //
    00152
    00153         if (!FlagOn( Lfcb->Flags, LFCB_PACK_LOG )
    00154             && !IsListEmpty( &Lfcb->LbcbActive )) {
    00155
    00156             ActiveLbcb = CONTAINING_RECORD( Lfcb->LbcbActive.Flink,
    00157                                             LBCB,
    00158                                             ActiveLinks );
    00159
    00160             if (FlagOn( ActiveLbcb->LbcbFlags, LBCB_NOT_EMPTY )) {
    00161
    00162                 RemoveEntryList( &ActiveLbcb->ActiveLinks );
    00163                 ClearFlag( ActiveLbcb->LbcbFlags, LBCB_ON_ACTIVE_QUEUE );
    00164             }
    00165         }
    00166
    00167         if (WaitForIo) {
    00168
    00169             LfsFlushLbcb( Lfcb, NewLbcb );
    00170         }
    00171
    00172     } finally {
    00173
    00174         DebugUnwind( LfsWriteLfsRestart );
    00175
    00176         if (NewRestart != NULL) {
    00177
    00178             ExFreePool( NewRestart );
    00179         }
    00180
    00181         DebugTrace( -1, Dbg, "LfsWriteLfsRestart:  Exit\n", 0 );
    00182     }
    00183
    00184     return;
    00185 }