Beispiel #1
0
PLBCB
LfsGetLbcb (
    IN PLFCB Lfcb
    )

/*++

Routine Description:

    This routine is called to add a Lbcb to the active queue.

Arguments:

    Lfcb - This is the file control block for the log file.

Return Value:

    PLBCB - Pointer to the Lbcb allocated.

--*/

{
    PLBCB Lbcb = NULL;
    PVOID PageHeader;
    PBCB PageHeaderBcb = NULL;

    BOOLEAN WrappedOrUsaError;

    PAGED_CODE();

    LfsDebugTrace( +1, Dbg, "LfsGetLbcb:  Entered\n", 0 );
    LfsDebugTrace(  0, Dbg, "Lfcb      -> %08lx\n", Lfcb );

    //
    //  Use a try-finally to facilitate cleanup.
    //

    try {

        //
        //  Pin the desired record page.
        //

        LfsPreparePinWriteData( Lfcb,
                                Lfcb->NextLogPage,
                                (ULONG)Lfcb->LogPageSize,
                                &PageHeader,
                                &PageHeaderBcb );

        //
        //  Put our signature into the page so we won't fail if we
        //  see a previous 'BAAD' signature.
        //

        *((PULONG) PageHeader) = LFS_SIGNATURE_RECORD_PAGE_ULONG;

        //
        //  Now allocate an Lbcb.
        //

        LfsAllocateLbcb( Lfcb, &Lbcb );

        //
        //  If we are at the beginning of the file we test that the
        //  sequence number won't wrap to 0.
        //

        if (!FlagOn( Lfcb->Flags, LFCB_NO_LAST_LSN | LFCB_REUSE_TAIL )
            && ( Lfcb->NextLogPage == Lfcb->FirstLogPage )) {

            Lfcb->SeqNumber = Lfcb->SeqNumber + 1;

            //
            //  If the sequence number is going from 0 to 1, then
            //  this is the first time the log file has wrapped.  We want
            //  to remember this because it means that we can now do
            //  large spiral writes.
            //

            if (Int64ShllMod32( Lfcb->SeqNumber, Lfcb->FileDataBits ) == 0) {

                LfsDebugTrace( 0, Dbg, "Log sequence number about to wrap:  Lfcb -> %08lx\n", Lfcb );
                KeBugCheck( FILE_SYSTEM );
            }

            //
            //  If this number is greater or equal to  the wrap sequence number in
            //  the Lfcb, set the wrap flag in the Lbcb.
            //

            if (!FlagOn( Lfcb->Flags, LFCB_LOG_WRAPPED )
                && ( Lfcb->SeqNumber >= Lfcb->SeqNumberForWrap )) {

                SetFlag( Lbcb->LbcbFlags, LBCB_LOG_WRAPPED );
                SetFlag( Lfcb->Flags, LFCB_LOG_WRAPPED );
            }
        }

        //
        //  Now initialize the rest of the Lbcb fields.
        //

        Lbcb->FileOffset = Lfcb->NextLogPage;
        Lbcb->SeqNumber = Lfcb->SeqNumber;
        Lbcb->BufferOffset = Lfcb->LogPageDataOffset;

        //
        //  Store the next page in the Lfcb.
        //

        LfsNextLogPageOffset( Lfcb,
                              Lfcb->NextLogPage,
                              &Lfcb->NextLogPage,
                              &WrappedOrUsaError );

        Lbcb->Length = Lfcb->LogPageSize;
        Lbcb->PageHeader = PageHeader;
        Lbcb->LogPageBcb = PageHeaderBcb;

        Lbcb->ResourceThread = ExGetCurrentResourceThread();

        //
        //  If we are reusing a previous page then set a flag in
        //  the Lbcb to indicate that we should flush a copy
        //  first.
        //

        if (FlagOn( Lfcb->Flags, LFCB_REUSE_TAIL )) {

            SetFlag( Lbcb->LbcbFlags, LBCB_FLUSH_COPY );
            ClearFlag( Lfcb->Flags, LFCB_REUSE_TAIL );

            (ULONG)Lbcb->BufferOffset = Lfcb->ReusePageOffset;

            Lbcb->Flags = ((PLFS_RECORD_PAGE_HEADER) PageHeader)->Flags;
            Lbcb->LastLsn = ((PLFS_RECORD_PAGE_HEADER) PageHeader)->Copy.LastLsn;
            Lbcb->LastEndLsn = ((PLFS_RECORD_PAGE_HEADER) PageHeader)->Header.Packed.LastEndLsn;
        }

        //
        //  Put the Lbcb on the active queue
        //

        InsertTailList( &Lfcb->LbcbActive, &Lbcb->ActiveLinks );

        SetFlag( Lbcb->LbcbFlags, LBCB_ON_ACTIVE_QUEUE );

    } finally {

        DebugUnwind( LfsGetLbcb );

        //
        //  If an error occurred, we need to clean up any blocks which
        //  have not been added to the active queue.
        //

        if (AbnormalTermination()) {

            if (Lbcb != NULL) {

                LfsDeallocateLbcb( Lfcb, Lbcb );
                Lbcb = NULL;
            }

            //
            //  Unpin the system page if pinned.
            //

            if (PageHeaderBcb != NULL) {

                CcUnpinData( PageHeaderBcb );
            }
        }

        LfsDebugTrace( -1, Dbg, "LfsGetLbcb:  Exit\n", 0 );
    }

    return Lbcb;
}
Beispiel #2
0
VOID
LfsDeallocateLfcb (
    IN PLFCB Lfcb,
    IN BOOLEAN CompleteTeardown
    )

/*++

Routine Description:

    This routine releases the resources associated with a log file control
    block.

Arguments:

    Lfcb - Supplies a pointer to the log file control block.

    CompleteTeardown - Indicates if we are to completely remove this Lfcb.

Return Value:

    None

--*/

{
    PLBCB NextLbcb;

    PAGED_CODE();

    DebugTrace( +1, Dbg, "LfsDeallocateLfcb:  Entered\n", 0 );
    DebugTrace(  0, Dbg, "Lfcb  -> %08lx\n", Lfcb );

    //
    //  Check that there are no buffer blocks.
    //

    ASSERT( IsListEmpty( &Lfcb->LbcbActive ));
    ASSERT( IsListEmpty( &Lfcb->LbcbWorkque ));

    //
    //  Check that we have no clients.
    //

    ASSERT( IsListEmpty( &Lfcb->LchLinks ));

    //
    //  If there is a restart area we deallocate it.
    //

    if (Lfcb->RestartArea != NULL) {

        LfsDeallocateRestartArea( Lfcb->RestartArea );
    }

    //
    //  If there are any of the tail Lbcb's, deallocate them now.
    //

    if (Lfcb->ActiveTail != NULL) {

        LfsDeallocateLbcb( Lfcb, Lfcb->ActiveTail );
        Lfcb->ActiveTail = NULL;
    }

    if (Lfcb->PrevTail != NULL) {

        LfsDeallocateLbcb( Lfcb, Lfcb->PrevTail );
        Lfcb->PrevTail = NULL;
    }

    //
    //  Only do the following if we are to remove the Lfcb completely.
    //

    if (CompleteTeardown) {

        //
        //  If there is a resource structure we deallocate it.
        //

        if (Lfcb->Sync != NULL) {

            ExDeleteResource( &Lfcb->Sync->Resource );

            ExFreePool( Lfcb->Sync );
        }
    }

    //
    //  Deallocate all of the spare Lbcb's.
    //

    while (!IsListEmpty( &Lfcb->SpareLbcbList )) {

        NextLbcb = (PLBCB) Lfcb->SpareLbcbList.Flink;

        RemoveHeadList( &Lfcb->SpareLbcbList );

        ExFreePool( NextLbcb );
    }

    //
    //  Discard the Lfcb structure.
    //

    ExFreePool( Lfcb );

    DebugTrace( -1, Dbg, "LfsDeallocateLfcb:  Exit\n", 0 );
    return;
}