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

lfs.h File Reference

Go to the source code of this file.

Classes

struct  _MULTI_SECTOR_HEADER
struct  _LFS_WRITE_DATA
struct  _LFS_WRITE_ENTRY
struct  _LOG_FILE_INFORMATION

Defines

#define SEQUENCE_NUMBER_STRIDE   (512)
#define LFS_DEFAULT_LOG_PAGE_SIZE   (0x1000)

Typedefs

typedef USHORT UPDATE_SEQUENCE_NUMBER
typedef USHORTPUPDATE_SEQUENCE_NUMBER
typedef _MULTI_SECTOR_HEADER MULTI_SECTOR_HEADER
typedef _MULTI_SECTOR_HEADERPMULTI_SECTOR_HEADER
typedef UPDATE_SEQUENCE_NUMBER UPDATE_SEQUENCE_ARRAY [1]
typedef UPDATE_SEQUENCE_ARRAYPUPDATE_SEQUENCE_ARRAY
typedef _LFS_WRITE_DATA LFS_WRITE_DATA
typedef _LFS_WRITE_DATAPLFS_WRITE_DATA
typedef LARGE_INTEGER LSN
typedef LARGE_INTEGER * PLSN
typedef enum _LFS_RECORD_TYPE LFS_RECORD_TYPE
typedef enum _LFS_RECORD_TYPEPLFS_RECORD_TYPE
typedef enum _LFS_CONTEXT_MODE LFS_CONTEXT_MODE
typedef enum _LFS_CONTEXT_MODEPLFS_CONTEXT_MODE
typedef ULONG TRANSACTION_ID
typedef ULONG * PTRANSACTION_ID
typedef enum _TRANSACTION_STATE TRANSACTION_STATE
typedef enum _TRANSACTION_STATEPTRANSACTION_STATE
typedef enum _LFS_INFO LFS_INFO
typedef enum _LFS_INFOPLFS_INFO
typedef PVOID LFS_LOG_HANDLE
typedef PVOID * PLFS_LOG_HANDLE
typedef PVOID LFS_LOG_CONTEXT
typedef PVOID * PLFS_LOG_CONTEXT
typedef _LFS_WRITE_ENTRY LFS_WRITE_ENTRY
typedef _LFS_WRITE_ENTRYPLFS_WRITE_ENTRY
typedef _LOG_FILE_INFORMATION LOG_FILE_INFORMATION
typedef _LOG_FILE_INFORMATIONPLOG_FILE_INFORMATION

Enumerations

enum  _LFS_RECORD_TYPE { LfsClientRecord = 1, LfsClientRestart }
enum  _LFS_CONTEXT_MODE { LfsContextUndoNext = 1, LfsContextPrevious, LfsContextForward }
enum  _TRANSACTION_STATE { TransactionUninitialized = 0, TransactionActive, TransactionPrepared, TransactionCommitted }
enum  _LFS_INFO { LfsUseUsa = 1, LfsPackLog, LfsFixedPageSize }

Functions

BOOLEAN LfsInitializeLogFileService ()
VOID LfsInitializeLogFile (IN PFILE_OBJECT LogFile, IN USHORT MaximumClients, IN ULONG LogPageSize OPTIONAL, IN LONGLONG FileSize, OUT PLFS_WRITE_DATA WriteData)
ULONG LfsOpenLogFile (IN PFILE_OBJECT LogFile, IN UNICODE_STRING ClientName, IN USHORT MaximumClients, IN ULONG LogPageSize OPTIONAL, IN LONGLONG FileSize, IN OUT PLFS_INFO LfsInfo, OUT PLFS_LOG_HANDLE LogHandle, OUT PLFS_WRITE_DATA WriteData)
VOID LfsCloseLogFile (IN LFS_LOG_HANDLE LogHandle)
VOID LfsDeleteLogHandle (IN LFS_LOG_HANDLE LogHandle)
VOID LfsReadLogFileInformation (IN LFS_LOG_HANDLE LogHandle, IN PLOG_FILE_INFORMATION Buffer, IN OUT PULONG Length)
BOOLEAN LfsVerifyLogFile (IN LFS_LOG_HANDLE LogHandle, IN PVOID LogFileHeader, IN ULONG Length)
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)
VOID LfsResetUndoTotal (IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberRecords, IN LONG ResetTotal)
BOOLEAN LfsWrite (IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberOfWriteEntries, IN PLFS_WRITE_ENTRY WriteEntries, IN LFS_RECORD_TYPE RecordType, IN TRANSACTION_ID *TransactionId OPTIONAL, IN LSN UndoNextLsn, IN LSN PreviousLsn, IN LONG UndoRequirement, OUT PLSN Lsn)
BOOLEAN LfsForceWrite (IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberOfWriteEntries, IN PLFS_WRITE_ENTRY WriteEntries, IN LFS_RECORD_TYPE RecordType, IN TRANSACTION_ID *TransactionId OPTIONAL, IN LSN UndoNextLsn, IN LSN PreviousLsn, IN LONG UndoRequirement, OUT PLSN Lsn)
VOID LfsFlushToLsn (IN LFS_LOG_HANDLE LogHandle, IN LSN Lsn)
VOID LfsCheckWriteRange (IN PLFS_WRITE_DATA WriteData, IN OUT PLONGLONG FlushOffset, IN OUT PULONG FlushLength)
VOID LfsReadLogRecord (IN LFS_LOG_HANDLE LogHandle, IN LSN FirstLsn, IN LFS_CONTEXT_MODE ContextMode, OUT PLFS_LOG_CONTEXT Context, OUT PLFS_RECORD_TYPE RecordType, OUT TRANSACTION_ID *TransactionId, OUT PLSN UndoNextLsn, OUT PLSN PreviousLsn, OUT PULONG BufferLength, OUT PVOID *Buffer)
BOOLEAN LfsReadNextLogRecord (IN LFS_LOG_HANDLE LogHandle, IN OUT LFS_LOG_CONTEXT Context, OUT PLFS_RECORD_TYPE RecordType, OUT TRANSACTION_ID *TransactionId, OUT PLSN UndoNextLsn, OUT PLSN PreviousLsn, OUT PLSN Lsn, OUT PULONG BufferLength, OUT PVOID *Buffer)
VOID LfsTerminateLogQuery (IN LFS_LOG_HANDLE LogHandle, IN LFS_LOG_CONTEXT Context)
LSN LfsQueryLastLsn (IN LFS_LOG_HANDLE LogHandle)

Variables

LSN LfsZeroLsn


Define Documentation

#define LFS_DEFAULT_LOG_PAGE_SIZE   (0x1000)
 

Definition at line 153 of file lfs.h.

Referenced by LfsInitializeLogFile(), LfsNormalizeBasicLogFile(), and LfsRestartLogFile().

#define SEQUENCE_NUMBER_STRIDE   (512)
 

Definition at line 73 of file lfs.h.

Referenced by LfsIsRestartPageHeaderValid(), and LfsReadRestart().


Typedef Documentation

typedef enum _LFS_CONTEXT_MODE LFS_CONTEXT_MODE
 

typedef enum _LFS_INFO LFS_INFO
 

typedef PVOID LFS_LOG_CONTEXT
 

Definition at line 199 of file lfs.h.

typedef PVOID LFS_LOG_HANDLE
 

Definition at line 197 of file lfs.h.

Referenced by LfsOpenLogFile().

typedef enum _LFS_RECORD_TYPE LFS_RECORD_TYPE
 

typedef struct _LFS_WRITE_DATA LFS_WRITE_DATA
 

typedef struct _LFS_WRITE_ENTRY LFS_WRITE_ENTRY
 

typedef struct _LOG_FILE_INFORMATION LOG_FILE_INFORMATION
 

typedef LARGE_INTEGER LSN
 

Definition at line 140 of file lfs.h.

Referenced by LfsCheckSubsequentLogPage(), LfsFindClientNextLsn(), LfsFindLastLsn(), LfsFlushLbcb(), LfsFlushLfcb(), LfsIsRestartAreaValid(), LfsQueryLastLsn(), LfsRestartLogFile(), LfsSearchForwardByClient(), LfsUpdateLfcbFromNoRestart(), LfsUpdateLfcbFromRestart(), and LfsWriteLogRecordIntoLogPage().

typedef struct _MULTI_SECTOR_HEADER MULTI_SECTOR_HEADER
 

typedef enum _LFS_CONTEXT_MODE * PLFS_CONTEXT_MODE
 

typedef enum _LFS_INFO * PLFS_INFO
 

typedef PVOID * PLFS_LOG_CONTEXT
 

Definition at line 199 of file lfs.h.

typedef PVOID * PLFS_LOG_HANDLE
 

Definition at line 197 of file lfs.h.

typedef enum _LFS_RECORD_TYPE * PLFS_RECORD_TYPE
 

typedef struct _LFS_WRITE_DATA * PLFS_WRITE_DATA
 

typedef struct _LFS_WRITE_ENTRY * PLFS_WRITE_ENTRY
 

Referenced by LfsWrite().

typedef struct _LOG_FILE_INFORMATION * PLOG_FILE_INFORMATION
 

typedef LARGE_INTEGER * PLSN
 

Definition at line 140 of file lfs.h.

Referenced by LfsFlushLbcb(), and LfsReadRestart().

typedef struct _MULTI_SECTOR_HEADER * PMULTI_SECTOR_HEADER
 

typedef ULONG * PTRANSACTION_ID
 

Definition at line 178 of file lfs.h.

typedef enum _TRANSACTION_STATE * PTRANSACTION_STATE
 

typedef UPDATE_SEQUENCE_ARRAY* PUPDATE_SEQUENCE_ARRAY
 

Definition at line 117 of file lfs.h.

typedef USHORT * PUPDATE_SEQUENCE_NUMBER
 

Definition at line 75 of file lfs.h.

typedef ULONG TRANSACTION_ID
 

Definition at line 178 of file lfs.h.

typedef enum _TRANSACTION_STATE TRANSACTION_STATE
 

typedef UPDATE_SEQUENCE_NUMBER UPDATE_SEQUENCE_ARRAY[1]
 

Definition at line 115 of file lfs.h.

typedef USHORT UPDATE_SEQUENCE_NUMBER
 

Definition at line 75 of file lfs.h.

Referenced by LfsIsRestartPageHeaderValid(), LfsUpdateLfcbFromNoRestart(), and LfsUpdateLfcbFromRestart().


Enumeration Type Documentation

enum _LFS_CONTEXT_MODE
 

Enumeration values:
LfsContextUndoNext 
LfsContextPrevious 
LfsContextForward 

Definition at line 170 of file lfs.h.

00170 { 00171 00172 LfsContextUndoNext = 1, 00173 LfsContextPrevious, 00174 LfsContextForward 00175 00176 } LFS_CONTEXT_MODE, *PLFS_CONTEXT_MODE;

enum _LFS_INFO
 

Enumeration values:
LfsUseUsa 
LfsPackLog 
LfsFixedPageSize 

Definition at line 189 of file lfs.h.

00189 { 00190 00191 LfsUseUsa = 1, 00192 LfsPackLog, 00193 LfsFixedPageSize 00194 00195 } LFS_INFO, *PLFS_INFO;

enum _LFS_RECORD_TYPE
 

Enumeration values:
LfsClientRecord 
LfsClientRestart 

Definition at line 159 of file lfs.h.

00159 { 00160 00161 LfsClientRecord = 1, 00162 LfsClientRestart 00163 00164 } LFS_RECORD_TYPE, *PLFS_RECORD_TYPE;

enum _TRANSACTION_STATE
 

Enumeration values:
TransactionUninitialized 
TransactionActive 
TransactionPrepared 
TransactionCommitted 

Definition at line 180 of file lfs.h.


Function Documentation

VOID LfsCheckWriteRange IN PLFS_WRITE_DATA  WriteData,
IN OUT PLONGLONG  FlushOffset,
IN OUT PULONG  FlushLength
 

Definition at line 477 of file lfs/write.c.

References _LBCB::FileOffset, LFS_SIGNATURE_RECORD_PAGE_ULONG, NULL, PAGE_SIZE, PAGED_CODE, _LBCB::PageHeader, _LFCB::PageToDirty, and _LFCB::SystemPageSize.

00485 : 00486 00487 This routine is called Ntfs to Lfs when a flush occurs. This will give Lfs a chance 00488 to trim the amount of the flush. Lfs can then use a 4K log record page size 00489 for all systems (Intel and Alpha). 00490 00491 This routine will trim the size of the IO request to the value stored in the 00492 Lfcb for this volume. We will also redirty the second half of the page if 00493 we have begun writing log records into it. 00494 00495 Arguments: 00496 00497 WriteData - This is the data in the user's data structure which is maintained 00498 by Lfs to describe the current writes. 00499 00500 FlushOffset - On input this is the start of the flush passed to Ntfs from MM. 00501 On output this is the start of the actual range to flush. 00502 00503 FlushLength - On input this is the length of the flush from the given FlushOffset. 00504 On output this is the length of the flush from the possibly modified FlushOffset. 00505 00506 Return Value: 00507 00508 None 00509 00510 --*/ 00511 00512 { 00513 PLIST_ENTRY Links; 00514 PLFCB Lfcb; 00515 PLFCB NextLfcb; 00516 PAGED_CODE(); 00517 00518 // 00519 // Find the correct Lfcb for this request. 00520 // 00521 00522 Lfcb = WriteData->Lfcb; 00523 00524 // 00525 // Trim the write if not a system page size. 00526 // 00527 00528 if (PAGE_SIZE != Lfcb->SystemPageSize) { 00529 00530 // 00531 // Check if we are trimming before the write. 00532 // 00533 00534 if (*FlushOffset < WriteData->FileOffset) { 00535 00536 *FlushLength -= (ULONG) (WriteData->FileOffset - *FlushOffset); 00537 *FlushOffset = WriteData->FileOffset; 00538 } 00539 00540 // 00541 // Check that we aren't flushing too much. 00542 // 00543 00544 if (*FlushOffset + *FlushLength > WriteData->FileOffset + WriteData->Length) { 00545 00546 *FlushLength = (ULONG) (WriteData->FileOffset + WriteData->Length - *FlushOffset); 00547 } 00548 00549 // 00550 // Finally check if we have to redirty a page. 00551 // 00552 00553 if ((Lfcb->PageToDirty != NULL) && 00554 (*FlushLength + *FlushOffset == Lfcb->PageToDirty->FileOffset)) { 00555 00556 *((PULONG) (Lfcb->PageToDirty->PageHeader)) = LFS_SIGNATURE_RECORD_PAGE_ULONG; 00557 } 00558 } 00559 00560 return; 00561 }

VOID LfsCloseLogFile IN LFS_LOG_HANDLE  LogHandle  ) 
 

Definition at line 706 of file lfs/registry.c.

References _LBCB::ActiveLinks, Add2Ptr, CcUnpinDataForThread(), ClearFlag, _LFCB::ClientArray, _LCH::ClientArrayByteOffset, _LFS_RESTART_AREA::ClientFreeList, _LCH::ClientId, _LFS_CLIENT_ID::ClientIndex, _LFS_RESTART_AREA::ClientInUseList, _LFS_CLIENT_RECORD::ClientRestartLsn, Dbg, DebugTrace, DebugUnwind, _LFCB_SYNC::Event, Executive, FALSE, FlagOn, _LFCB::Flags, KernelMode, KeWaitForSingleObject(), LBCB_NOT_EMPTY, LBCB_ON_ACTIVE_QUEUE, _LFCB::LbcbActive, _LBCB::LbcbFlags, _LFCB::LbcbWorkque, _LCH::LchLinks, _LCH::Lfcb, LFCB_FINAL_SHUTDOWN, _LFCB::LfcbLinks, LFS_NO_CLIENT, LfsAcquireLch, LfsAcquireLfcb, LfsAcquireLfsData, LfsAddClientToList(), LfsCloseLogFile(), LfsDeallocateLbcb(), LfsDeallocateLfcb(), LfsExceptionFilter(), _LFCB::LfsIoState, LfsLbcbIsRestart, LfsNoIoInProgress, LfsReleaseLch, LfsReleaseLfcb, LfsReleaseLfsData, LfsRemoveClientFromList(), LfsValidateClientId, LfsValidateLch, LfsWriteLfsRestart(), LfsZeroLsn, _LBCB::LogPageBcb, NTSTATUS(), NULL, PAGED_CODE, _LBCB::ResourceThread, _LFCB::RestartArea, _LFCB::RestartAreaSize, _LFS_CLIENT_RECORD::SeqNumber, SetFlag, Status, _LFCB::Sync, TRUE, try_return, USHORT, _LFCB::Waiters, and _LBCB::WorkqueLinks.

Referenced by LfsCloseLogFile().

00712 : 00713 00714 This routine is called when a client detaches itself from the log 00715 file. On return, all prior references to this client in the log 00716 file are inaccessible. 00717 00718 Arguments: 00719 00720 LogHandle - Pointer to private Lfs structure used to identify this 00721 client. 00722 00723 Return Value: 00724 00725 None 00726 00727 --*/ 00728 00729 { 00730 volatile NTSTATUS Status = STATUS_SUCCESS; 00731 00732 PLCH Lch; 00733 00734 PLFCB Lfcb; 00735 00736 USHORT ClientIndex; 00737 PLFS_CLIENT_RECORD ClientRecord; 00738 00739 BOOLEAN FlushRestart; 00740 BOOLEAN ExitLoop; 00741 00742 PAGED_CODE(); 00743 00744 DebugTrace( +1, Dbg, "LfsCloseLogFile: Entered\n", 0 ); 00745 DebugTrace( 0, Dbg, "LogHandle -> %08lx\n", LogHandle ); 00746 00747 Lch = (PLCH) LogHandle; 00748 00749 // 00750 // Enclose this in a loop. We will loop as long as there are waiters or there is an IO 00751 // in progress. 00752 // 00753 00754 while (TRUE) { 00755 00756 // 00757 // Always assume we exit the loop. 00758 // 00759 00760 ExitLoop = TRUE; 00761 00762 // 00763 // Check that the structure is a valid log handle structure. 00764 // 00765 00766 LfsValidateLch( Lch ); 00767 00768 // 00769 // Protect this entry point with a try-except. 00770 // 00771 00772 try { 00773 00774 // 00775 // Use a try-finally to facilitate cleanup. 00776 // 00777 00778 // 00779 // Acquire the global data block and the log file control block. 00780 // 00781 00782 LfsAcquireLfsData(); 00783 00784 try { 00785 00786 PLBCB ThisLbcb; 00787 00788 LfsAcquireLch( Lch ); 00789 00790 Lfcb = Lch->Lfcb; 00791 00792 // 00793 // If the Log file has been closed then return immediately. 00794 // 00795 00796 if (Lfcb == NULL) { 00797 00798 try_return( NOTHING ); 00799 } 00800 00801 // 00802 // Check that there are no waiters or IO in progress before proceeding. 00803 // 00804 00805 if ((Lfcb->Waiters != 0) || 00806 (Lfcb->LfsIoState != LfsNoIoInProgress)) { 00807 00808 ExitLoop = FALSE; 00809 Lfcb->Waiters += 1; 00810 try_return( NOTHING ); 00811 } 00812 00813 // 00814 // Check that the client Id is valid. 00815 // 00816 00817 LfsValidateClientId( Lfcb, Lch ); 00818 00819 ClientRecord = Add2Ptr( Lfcb->ClientArray, 00820 Lch->ClientArrayByteOffset, 00821 PLFS_CLIENT_RECORD ); 00822 00823 #if 1 00824 // 00825 // Increment the client sequence number in the restart area. 00826 // This will prevent anyone else from accessing this client block. 00827 // 00828 00829 ClientIndex = Lch->ClientId.ClientIndex; 00830 00831 ClientRecord->SeqNumber++; 00832 #endif 00833 00834 // 00835 // Remember if this client wrote a restart area. 00836 // 00837 00838 FlushRestart = (BOOLEAN) ( LfsZeroLsn.QuadPart != ClientRecord->ClientRestartLsn.QuadPart ); 00839 00840 #if 1 00841 // 00842 // Remove the client from the log file in use list. 00843 // 00844 00845 LfsRemoveClientFromList( Lfcb->ClientArray, 00846 ClientRecord, 00847 &Lfcb->RestartArea->ClientInUseList ); 00848 00849 // 00850 // Add the client block to the log file free list 00851 // 00852 00853 LfsAddClientToList( Lfcb->ClientArray, 00854 ClientIndex, 00855 &Lfcb->RestartArea->ClientFreeList ); 00856 00857 // 00858 // If this is the last client then move the last active Lbcb off 00859 // the active queue. 00860 // 00861 00862 if (Lfcb->RestartArea->ClientInUseList == LFS_NO_CLIENT) { 00863 #endif 00864 // 00865 // Set the flag to indicate we are at the final close. 00866 // 00867 00868 SetFlag( Lfcb->Flags, LFCB_FINAL_SHUTDOWN ); 00869 00870 // 00871 // Walk through the active queue and remove any Lbcb's with 00872 // data from that queue. That will allow them to get out to disk. 00873 // 00874 00875 while (!IsListEmpty( &Lfcb->LbcbActive )) { 00876 00877 ThisLbcb = CONTAINING_RECORD( Lfcb->LbcbActive.Flink, 00878 LBCB, 00879 ActiveLinks ); 00880 00881 RemoveEntryList( &ThisLbcb->ActiveLinks ); 00882 ClearFlag( ThisLbcb->LbcbFlags, LBCB_ON_ACTIVE_QUEUE ); 00883 00884 // 00885 // If this page has some new entries, allow it to 00886 // be flushed to disk. Otherwise deallocate it. 00887 // 00888 00889 if (!FlagOn( ThisLbcb->LbcbFlags, LBCB_NOT_EMPTY )) { 00890 00891 RemoveEntryList( &ThisLbcb->WorkqueLinks ); 00892 00893 if (ThisLbcb->LogPageBcb != NULL) { 00894 00895 CcUnpinDataForThread( ThisLbcb->LogPageBcb, 00896 ThisLbcb->ResourceThread ); 00897 } 00898 00899 LfsDeallocateLbcb( Lfcb, ThisLbcb ); 00900 } 00901 } 00902 00903 // 00904 // It's possible that we have the two restart areas in the workque. 00905 // They can be removed and the memory deallocated if we have no 00906 // more clients. 00907 // 00908 // We skip this action if the there is Io in progress or the user 00909 // had a restart area. 00910 // 00911 00912 if ((Lfcb->LfsIoState == LfsNoIoInProgress) && !FlushRestart) { 00913 00914 PLIST_ENTRY Links; 00915 00916 // 00917 // Now walk through the workque list looking for a non-restart 00918 // entry. 00919 // 00920 00921 Links = Lfcb->LbcbWorkque.Flink; 00922 00923 while (Links != &Lfcb->LbcbWorkque) { 00924 00925 ThisLbcb = CONTAINING_RECORD( Links, 00926 LBCB, 00927 WorkqueLinks ); 00928 00929 // 00930 // If this is not a restart area, we exit and remember that 00931 // we need to flush the restart areas. 00932 // 00933 00934 if (!LfsLbcbIsRestart( ThisLbcb )) { 00935 00936 FlushRestart = TRUE; 00937 break; 00938 } 00939 00940 Links = Links->Flink; 00941 } 00942 00943 // 00944 // If we are still not to flush the restart areas remove 00945 // all of the restart areas from the queue. 00946 // 00947 00948 if (!FlushRestart) { 00949 00950 while (!IsListEmpty( &Lfcb->LbcbWorkque)) { 00951 00952 ThisLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Blink, 00953 LBCB, 00954 WorkqueLinks ); 00955 00956 RemoveEntryList( &ThisLbcb->WorkqueLinks ); 00957 LfsDeallocateLbcb( Lfcb, ThisLbcb ); 00958 } 00959 } 00960 00961 } else { 00962 00963 FlushRestart = TRUE; 00964 } 00965 00966 #if 1 00967 // 00968 // We will have to flush the restart area in this case. 00969 // 00970 00971 } else { 00972 00973 FlushRestart = TRUE; 00974 } 00975 #endif 00976 00977 // 00978 // Flush the new restart area if we need to. 00979 // 00980 00981 if (FlushRestart) { 00982 00983 LfsWriteLfsRestart( Lfcb, Lfcb->RestartAreaSize, FALSE ); 00984 LfsWriteLfsRestart( Lfcb, Lfcb->RestartAreaSize, TRUE ); 00985 } 00986 00987 // 00988 // Clear the Lfcb pointer in the client handle. 00989 // 00990 00991 Lch->Lfcb = NULL; 00992 RemoveEntryList( &Lch->LchLinks ); 00993 00994 // 00995 // If there are no active clients, we can remove this log file 00996 // control block from the active queue. 00997 // 00998 00999 #if 1 01000 if (Lfcb->RestartArea->ClientInUseList == LFS_NO_CLIENT) { 01001 #endif 01002 01003 RemoveEntryList( &Lfcb->LfcbLinks ); 01004 LfsDeallocateLfcb( Lfcb, FALSE ); 01005 #if 1 01006 } 01007 #endif 01008 01009 try_exit: NOTHING; 01010 } finally { 01011 01012 DebugUnwind( LfsCloseLogFile ); 01013 01014 // 01015 // Release the log file control block if held. 01016 // 01017 01018 LfsReleaseLch( Lch ); 01019 01020 // 01021 // Release the global data block if held. 01022 // 01023 01024 LfsReleaseLfsData(); 01025 01026 DebugTrace( -1, Dbg, "LfsCloseLogFile: Exit\n", 0 ); 01027 } 01028 01029 } except (LfsExceptionFilter( GetExceptionInformation() )) { 01030 01031 Status = GetExceptionCode(); 01032 } 01033 01034 // 01035 // Test if we want to exit the loop now. 01036 // 01037 01038 if (ExitLoop) { break; } 01039 01040 // 01041 // Wait for the io to complete. 01042 // 01043 01044 KeWaitForSingleObject( &Lfcb->Sync->Event, 01045 Executive, 01046 KernelMode, 01047 FALSE, 01048 NULL ); 01049 01050 LfsAcquireLfcb( Lfcb ); 01051 Lfcb->Waiters -= 1; 01052 LfsReleaseLfcb( Lfcb ); 01053 } 01054 01055 // 01056 // We always let this operation succeed. 01057 // 01058 01059 return; 01060 }

VOID LfsDeleteLogHandle IN LFS_LOG_HANDLE  LogHandle  ) 
 

Definition at line 1063 of file lfs/registry.c.

References ExDeleteResource, ExFreePool(), LFS_NTC_LCH, LfsAcquireLch, LfsDeallocateLch, LfsExceptionFilter(), LfsReleaseLch, _LCH::NodeTypeCode, NULL, PAGED_CODE, _LFCB_SYNC::Resource, _LCH::Sync, and _LFCB_SYNC::UserCount.

01069 : 01070 01071 This routine is called when a client is tearing down the last of 01072 his volume structures. There will be no more references to this 01073 handle. If it is the last handle for the log file then we will 01074 deallocate the Sync structure as well. 01075 01076 Arguments: 01077 01078 LogHandle - Pointer to private Lfs structure used to identify this 01079 client. 01080 01081 Return Value: 01082 01083 None 01084 01085 --*/ 01086 01087 { 01088 PLCH Lch; 01089 01090 PAGED_CODE(); 01091 01092 // 01093 // If the log handle is null then return immediately. 01094 // 01095 01096 Lch = (PLCH) LogHandle; 01097 01098 if ((Lch == NULL) || 01099 (Lch->NodeTypeCode != LFS_NTC_LCH)) { 01100 01101 return; 01102 } 01103 01104 // 01105 // Ignore all errors from now on. 01106 // 01107 01108 try { 01109 01110 LfsAcquireLch( Lch ); 01111 01112 Lch->Sync->UserCount -= 1; 01113 01114 // 01115 // If we are the last user then deallocate the sync structure. 01116 // 01117 01118 if (Lch->Sync->UserCount == 0) { 01119 01120 ExDeleteResource( &Lch->Sync->Resource ); 01121 01122 ExFreePool( Lch->Sync ); 01123 01124 } else { 01125 01126 LfsReleaseLch( Lch ); 01127 } 01128 01129 LfsDeallocateLch( Lch ); 01130 01131 } except (LfsExceptionFilter( GetExceptionInformation() )) { 01132 01133 NOTHING; 01134 } 01135 01136 return; 01137 }

VOID LfsFlushToLsn IN LFS_LOG_HANDLE  LogHandle,
IN LSN  Lsn
 

Definition at line 360 of file lfs/write.c.

References Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsFlushToLsn(), LfsFlushToLsnPriv(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, NTSTATUS(), NULL, PAGED_CODE, and Status.

Referenced by LfsFlushToLsn().

00367 : 00368 00369 This routine is called by a client to insure that all log records 00370 to a certain point have been flushed to the file. This is done by 00371 checking if the desired Lsn has even been written at all. If so we 00372 check if it has been flushed to the file. If not, we simply write 00373 the current restart area to the disk. 00374 00375 Arguments: 00376 00377 LogHandle - Pointer to private Lfs structure used to identify this 00378 client. 00379 00380 Lsn - This is the Lsn that must be on the disk on return from this 00381 routine. 00382 00383 Return Value: 00384 00385 None 00386 00387 --*/ 00388 00389 { 00390 volatile NTSTATUS Status = STATUS_SUCCESS; 00391 00392 PLCH Lch; 00393 00394 PLFCB Lfcb; 00395 00396 PAGED_CODE(); 00397 00398 DebugTrace( +1, Dbg, "LfsFlushToLsn: Entered\n", 0 ); 00399 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00400 DebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn.LowPart ); 00401 DebugTrace( 0, Dbg, "Lsn (High) -> %08lx\n", Lsn.HighPart ); 00402 00403 Lch = (PLCH) LogHandle; 00404 00405 // 00406 // Check that the structure is a valid log handle structure. 00407 // 00408 00409 LfsValidateLch( Lch ); 00410 00411 // 00412 // Use a try-except to catch errors. 00413 // 00414 00415 try { 00416 00417 // 00418 // Use a try-finally to facilitate cleanup. 00419 // 00420 00421 try { 00422 00423 // 00424 // Acquire the log file control block for this log file. 00425 // 00426 00427 LfsAcquireLch( Lch ); 00428 Lfcb = Lch->Lfcb; 00429 00430 // 00431 // If the log file has been closed we will assume the Lsn has been flushed. 00432 // 00433 00434 if (Lfcb != NULL) { 00435 00436 // 00437 // Check that the client Id is valid. 00438 // 00439 00440 LfsValidateClientId( Lfcb, Lch ); 00441 00442 // 00443 // Call our common routine to perform the work. 00444 // 00445 00446 LfsFlushToLsnPriv( Lfcb, Lsn ); 00447 } 00448 00449 } finally { 00450 00451 DebugUnwind( LfsFlushToLsn ); 00452 00453 // 00454 // Release the log file control block if held. 00455 // 00456 00457 LfsReleaseLch( Lch ); 00458 00459 DebugTrace( -1, Dbg, "LfsFlushToLsn: Exit\n", 0 ); 00460 } 00461 00462 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00463 00464 Status = GetExceptionCode(); 00465 } 00466 00467 if (Status != STATUS_SUCCESS) { 00468 00469 ExRaiseStatus( Status ); 00470 } 00471 00472 return; 00473 }

BOOLEAN LfsForceWrite IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  NumberOfWriteEntries,
IN PLFS_WRITE_ENTRY  WriteEntries,
IN LFS_RECORD_TYPE  RecordType,
IN TRANSACTION_ID *TransactionId  OPTIONAL,
IN LSN  UndoNextLsn,
IN LSN  PreviousLsn,
IN LONG  UndoRequirement,
OUT PLSN  Lsn
 

Referenced by LfsForceWrite().

VOID LfsInitializeLogFile IN PFILE_OBJECT  LogFile,
IN USHORT  MaximumClients,
IN ULONG LogPageSize  OPTIONAL,
IN LONGLONG  FileSize,
OUT PLFS_WRITE_DATA  WriteData
 

Definition at line 150 of file lfs/registry.c.

References Add2Ptr, CcSetAdditionalCacheAttributes(), _LFCB::ClientArray, _LFCB::ClientArrayOffset, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LFCB::FileObject, _LFCB::FirstLogPage, _LFCB::InitialRestartArea, KeQuerySystemTime(), _LFS_DATA::LfcbLinks, _LFCB::LfcbLinks, LFS_DEFAULT_LOG_PAGE_SIZE, LfsAcquireLfcb, LfsAcquireLfsData, LfsAllocateLfcb(), LfsAllocateRestartArea, LfsData, LfsDeallocateLfcb(), LfsDeallocateRestartArea, LfsExceptionFilter(), LfsInitializeLogFile(), LfsInitializeLogFilePriv(), LfsLi0, LfsNormalizeBasicLogFile(), LfsReleaseLfcb, LfsReleaseLfsData, _LFS_WRITE_DATA::LfsStructureSize, LfsUpdateLfcbFromNoRestart(), LfsUpdateLfcbFromPgHeader(), LfsUpdateRestartAreaFromLfcb(), NTSTATUS(), NULL, PAGE_SIZE, PAGED_CODE, _LFCB::RestartArea, _LFCB::RestartDataSize, Status, TRUE, and _LFCB::UserWriteData.

Referenced by LfsInitializeLogFile().

00160 : 00161 00162 This routine is called to initialize a log file to prepare it for use 00163 by log clients. Any previous data in the file will be overwritten. 00164 00165 Lfs will partition the file into 2 Lfs restart areas and as many log 00166 pages as will fit in the file. The restart area size is determined 00167 by computing the amount of space needed for the maximum number 00168 00169 Arguments: 00170 00171 LogFile - This is the file object for the file to be used as a log file. 00172 00173 MaximumClients - This is the maximum number of clients that will be 00174 active in the log file at any one time. 00175 00176 LogPageSize - If specified (not 0), this is the recommended size of 00177 the log page. Lfs will use this as a guide in 00178 determining the log page size. 00179 00180 FileSize - This is the available size of the log file. 00181 00182 WriteData - Pointer to WRITE_DATA in caller's data structure. 00183 00184 Return Value: 00185 00186 None 00187 00188 --*/ 00189 00190 { 00191 PLFCB Lfcb; 00192 LARGE_INTEGER CurrentTime; 00193 00194 PLFS_RESTART_AREA RestartArea = NULL; 00195 00196 volatile NTSTATUS Status = STATUS_SUCCESS; 00197 00198 PAGED_CODE(); 00199 00200 DebugTrace( +1, Dbg, "LfsInitializeLogFile: Entered\n", 0 ); 00201 DebugTrace( 0, Dbg, "Log File -> %08lx\n", LogFile ); 00202 DebugTrace( 0, Dbg, "Maximum Clients -> %04x\n", MaximumClients ); 00203 DebugTrace( 0, Dbg, "Log Page Size -> %08lx\n", LogPageSize ); 00204 DebugTrace( 0, Dbg, "File Size (Low) -> %08lx\n", FileSize.LowPart ); 00205 DebugTrace( 0, Dbg, "File Size (High) -> %08lx\n", FileSize.HighPart ); 00206 00207 Lfcb = NULL; 00208 00209 // 00210 // Protect this entry point with a try-except. 00211 // 00212 00213 try { 00214 00215 // 00216 // We grab the global data exclusively. 00217 // 00218 00219 LfsAcquireLfsData(); 00220 00221 // 00222 // Use a try-finally to facilitate cleanup. 00223 // 00224 00225 try { 00226 00227 // 00228 // We allocate an Lfcb and point it to the log file. 00229 // 00230 00231 Lfcb = LfsAllocateLfcb(); 00232 00233 LfsAcquireLfcb( Lfcb ); 00234 00235 Lfcb->FileObject = LogFile; 00236 00237 // 00238 // Call the Cache Manager to disable read ahead and write behind; 00239 // we flush the log file explicitly. 00240 // 00241 00242 CcSetAdditionalCacheAttributes( LogFile, TRUE, TRUE ); 00243 00244 // 00245 // Normalize the values passed in with this call. 00246 // 00247 00248 LfsNormalizeBasicLogFile( &FileSize, 00249 &LogPageSize, 00250 &MaximumClients, 00251 (BOOLEAN) ((PAGE_SIZE >= LFS_DEFAULT_LOG_PAGE_SIZE) && 00252 (PAGE_SIZE <= LFS_DEFAULT_LOG_PAGE_SIZE * 2))); 00253 00254 // 00255 // We can go directly to version 1.1 since we can immediately pack 00256 // the log file and use the default system log page size. 00257 // 00258 00259 LfsUpdateLfcbFromPgHeader( Lfcb, 00260 LogPageSize, 00261 LogPageSize, 00262 1, 00263 1, 00264 TRUE ); 00265 00266 KeQuerySystemTime( &CurrentTime ); 00267 00268 LfsUpdateLfcbFromNoRestart( Lfcb, 00269 FileSize, 00270 LfsLi0, 00271 MaximumClients, 00272 CurrentTime.LowPart, 00273 FALSE, 00274 FALSE ); 00275 00276 LfsAllocateRestartArea( &RestartArea, Lfcb->RestartDataSize ); 00277 00278 LfsUpdateRestartAreaFromLfcb( Lfcb, RestartArea ); 00279 00280 Lfcb->RestartArea = RestartArea; 00281 Lfcb->ClientArray = Add2Ptr( RestartArea, Lfcb->ClientArrayOffset, PLFS_CLIENT_RECORD ); 00282 RestartArea = NULL; 00283 00284 Lfcb->InitialRestartArea = TRUE; 00285 00286 // 00287 // Now update the caller's WRITE_DATA structure. 00288 // 00289 00290 Lfcb->UserWriteData = WriteData; 00291 WriteData->LfsStructureSize = LogPageSize; 00292 WriteData->Lfcb = Lfcb; 00293 00294 // 00295 // Force two restart areas to disk and reinitialize the file. 00296 // 00297 00298 LfsInitializeLogFilePriv( Lfcb, 00299 TRUE, 00300 Lfcb->RestartDataSize, 00301 Lfcb->FirstLogPage, 00302 TRUE ); 00303 00304 // 00305 // Put the Lfcb into the global queue. 00306 // 00307 00308 InsertHeadList( &LfsData.LfcbLinks, &Lfcb->LfcbLinks ); 00309 00310 } finally { 00311 00312 DebugUnwind( LfsInitializeLogFile ); 00313 00314 // 00315 // If the Lfcb has been acquired, we release it now. 00316 // 00317 00318 if (Lfcb != NULL) { 00319 00320 LfsReleaseLfcb( Lfcb ); 00321 00322 // 00323 // If an error occurred and we allocated an Lfcb. We deallocate 00324 // it now. 00325 // 00326 00327 if (AbnormalTermination()) { 00328 00329 LfsDeallocateLfcb( Lfcb, TRUE ); 00330 } 00331 } 00332 00333 // 00334 // Deallocate the restart area. 00335 // 00336 00337 if (RestartArea != NULL) { 00338 00339 LfsDeallocateRestartArea( RestartArea ); 00340 } 00341 00342 // 00343 // We release the global data. 00344 // 00345 00346 LfsReleaseLfsData(); 00347 00348 DebugTrace( -1, Dbg, "LfsInitializeLogFile: Exit\n", 0 ); 00349 } 00350 00351 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00352 00353 Status = GetExceptionCode(); 00354 } 00355 00356 if (Status != STATUS_SUCCESS) { 00357 00358 ExRaiseStatus( Status ); 00359 } 00360 00361 return; 00362 }

BOOLEAN LfsInitializeLogFileService  ) 
 

Definition at line 40 of file sysinit.c.

References _LFS_DATA::Buffer1, _LFS_DATA::Buffer2, _LFS_DATA::BufferLock, _LFS_DATA::BufferNotification, ClearFlag, Dbg, DebugTrace, ExInitializeFastMutex, FALSE, FlagOn, _LFS_DATA::Flags, KeInitializeEvent, KeQuerySystemTime(), _LFS_DATA::LfcbLinks, LFS_BUFFER_SIZE, LFS_DATA, LFS_DATA_INIT_FAILED, LFS_DATA_INITIALIZED, LFS_NTC_DATA, LfsAllocatePoolNoRaise, LfsData, _LFS_DATA::LfsDataLock, LfsFreePool, LfsUsaSeqNumber, _LFS_DATA::NodeByteSize, _LFS_DATA::NodeTypeCode, NULL, PAGED_CODE, PagedPool, SetFlag, TRUE, and USHORT.

00045 : 00046 00047 This routine must be called during system initialization before the 00048 first call to logging service, to allow the Log File Service to initialize 00049 its global data structures. This routine has no dependencies on other 00050 system components being initialized. 00051 00052 This routine will initialize the global structures used by the logging 00053 service and start the Lfs worker thread. 00054 00055 Arguments: 00056 00057 None 00058 00059 Return Value: 00060 00061 TRUE if initialization was successful 00062 00063 --*/ 00064 00065 { 00066 LARGE_INTEGER CurrentTime; 00067 00068 PAGED_CODE(); 00069 00070 DebugTrace( +1, Dbg, "LfsInitializeLogFileService: Enter\n", 0 ); 00071 00072 // 00073 // If the structure has already been initialized then we can return 00074 // immediately. 00075 // 00076 00077 if (LfsData.NodeTypeCode == LFS_NTC_DATA 00078 && LfsData.NodeByteSize == sizeof( LFS_DATA ) 00079 && FlagOn( LfsData.Flags, LFS_DATA_INITIALIZED )) { 00080 00081 DebugTrace( -1, Dbg, "LfsInitializeLogFileService: Exit -> %01x\n", TRUE ); 00082 00083 return TRUE; 00084 } 00085 00086 // 00087 // Zero out the structure initially. 00088 // 00089 00090 RtlZeroMemory( &LfsData, sizeof( LFS_DATA )); 00091 00092 // 00093 // Assume the operation will fail. 00094 // 00095 00096 LfsData.Flags = LFS_DATA_INIT_FAILED; 00097 00098 // 00099 // Initialize the global structure for Lfs. 00100 // 00101 00102 LfsData.NodeTypeCode = LFS_NTC_DATA; 00103 LfsData.NodeByteSize = sizeof( LFS_DATA ); 00104 00105 InitializeListHead( &LfsData.LfcbLinks ); 00106 00107 // 00108 // Initialize the synchronization objects. 00109 // 00110 00111 ExInitializeFastMutex( &LfsData.LfsDataLock ); 00112 00113 // 00114 // Initialize the buffer allocation. System will be robust enough to tolerate 00115 // allocation failures. 00116 // 00117 00118 ExInitializeFastMutex( &LfsData.BufferLock ); 00119 KeInitializeEvent( &LfsData.BufferNotification, NotificationEvent, TRUE ); 00120 LfsData.Buffer1 = LfsAllocatePoolNoRaise( PagedPool, LFS_BUFFER_SIZE ); 00121 00122 if (LfsData.Buffer1 == NULL) { 00123 00124 return FALSE; 00125 } 00126 00127 LfsData.Buffer2 = LfsAllocatePoolNoRaise( PagedPool, LFS_BUFFER_SIZE ); 00128 00129 // 00130 // Make sure we got both. 00131 // 00132 00133 if (LfsData.Buffer2 == NULL) { 00134 00135 LfsFreePool( LfsData.Buffer1 ); 00136 LfsData.Buffer1 = NULL; 00137 return FALSE; 00138 } 00139 00140 // 00141 // Initialization has been successful. 00142 // 00143 00144 ClearFlag( LfsData.Flags, LFS_DATA_INIT_FAILED ); 00145 SetFlag( LfsData.Flags, LFS_DATA_INITIALIZED ); 00146 00147 // 00148 // Get a random number as a seed for the Usa sequence numbers. Use the lower 00149 // bits of the current time. 00150 // 00151 00152 KeQuerySystemTime( &CurrentTime ); 00153 LfsUsaSeqNumber = (USHORT) CurrentTime.LowPart; 00154 00155 DebugTrace( -1, Dbg, "LfsInitializeLogFileService: Exit -> %01x\n", TRUE ); 00156 00157 return TRUE; 00158 } }

ULONG LfsOpenLogFile IN PFILE_OBJECT  LogFile,
IN UNICODE_STRING  ClientName,
IN USHORT  MaximumClients,
IN ULONG LogPageSize  OPTIONAL,
IN LONGLONG  FileSize,
IN OUT PLFS_INFO  LfsInfo,
OUT PLFS_LOG_HANDLE  LogHandle,
OUT PLFS_WRITE_DATA  WriteData
 

Definition at line 366 of file lfs/registry.c.

References CcSetAdditionalCacheAttributes(), _LFCB::ClientArray, _LCH::ClientArrayByteOffset, _LFS_RESTART_AREA::ClientFreeList, _LCH::ClientId, _LFS_CLIENT_ID::ClientIndex, _LFS_RESTART_AREA::ClientInUseList, _LFS_CLIENT_RECORD::ClientName, _LFS_CLIENT_RECORD::ClientNameLength, _LFS_CLIENT_RECORD::ClientRestartLsn, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), _LFCB::FileObject, FlagOn, _LFCB::Flags, _LFCB::LchLinks, _LCH::LchLinks, _LCH::Lfcb, LFCB_LOG_FILE_CORRUPT, LFCB_PACK_LOG, _LFS_DATA::LfcbLinks, _LFCB::LfcbLinks, LFS_CLIENT_NAME_MAX, LFS_LOG_HANDLE, LFS_NO_CLIENT, LfsAcquireLfsData, LfsAddClientToList(), LfsAllocateLch, LfsData, LfsDeallocateLch, LfsDeallocateLfcb(), LfsExceptionFilter(), LfsOpenLogFile(), LfsReleaseLfcb, LfsReleaseLfsData, LfsRemoveClientFromList(), LfsRestartLogFile(), LfsZeroLsn, _LFS_CLIENT_RECORD::NextClient, NTSTATUS(), NULL, _LFS_CLIENT_RECORD::OldestLsn, _LFCB::OldestLsn, PAGED_CODE, PtrOffset, _LFCB::RecordHeaderLength, _LFCB::RestartArea, _LFS_CLIENT_ID::SeqNumber, _LFS_CLIENT_RECORD::SeqNumber, Status, _LCH::Sync, _LFCB::Sync, TRUE, _LFCB_SYNC::UserCount, and USHORT.

Referenced by LfsOpenLogFile().

00379 : 00380 00381 This routine is called when a client wishes to register with logging 00382 service. This can be a reregistration (i.e. restart after a crash) 00383 or an initial registration. There can be no other active clients 00384 with the same name. The Log Handle returned is then used for any 00385 subsequent access by this client. 00386 00387 If an Lfs restart has not been done on the log file, it will be done 00388 at this time. 00389 00390 Arguments: 00391 00392 LogFile - A file object for a file previously initialized for use 00393 as a log file. 00394 00395 ClientName - This unicode string is used to uniquely identify clients 00396 of the logging service. A case-sensitive comparison is 00397 used to check this name against active clients of the 00398 log file. 00399 00400 MaximumClients - The maximum number of clients if the log file has 00401 never been initialized. 00402 00403 LogPageSize - This is the recommeded size for the log page. 00404 00405 FileSize - This is the size of the log file. 00406 00407 LfsInfo - On entry, indicates the log file state the user may 00408 know about. On exit, indicates the log file state that Lfs 00409 knows about. This is a conduit for Lfs to communicate with its 00410 clients. 00411 00412 LogHandle - The address to store the identifier the logging service 00413 will use to identify this client in all other Lfs calls. 00414 00415 WriteData - Pointer to WRITE_DATA in caller's data structure. 00416 00417 Return Value: 00418 00419 ULONG - Amount to add to reservation value for header for log record. 00420 00421 --*/ 00422 00423 { 00424 volatile NTSTATUS Status = STATUS_SUCCESS; 00425 00426 PLIST_ENTRY Link; 00427 PLFCB ThisLfcb = NULL; 00428 PLFCB NewLfcb = NULL; 00429 00430 USHORT ThisClient; 00431 PLFS_CLIENT_RECORD ClientRecord; 00432 00433 PLCH Lch = NULL; 00434 00435 ULONG ReservedHeader; 00436 00437 PAGED_CODE(); 00438 00439 DebugTrace( +1, Dbg, "LfsOpenLogFile: Entered\n", 0 ); 00440 DebugTrace( 0, Dbg, "Log File -> %08lx\n", LogFile ); 00441 DebugTrace( 0, Dbg, "Client Name -> %08lx\n", &ClientName ); 00442 DebugTrace( 0, Dbg, "Maximum Clients -> %04x\n", MaximumClients ); 00443 DebugTrace( 0, Dbg, "Log Page Size -> %08lx\n", LogPageSize ); 00444 DebugTrace( 0, Dbg, "File Size (Low) -> %08lx\n", FileSize.LowPart ); 00445 DebugTrace( 0, Dbg, "File Size (High) -> %08lx\n", FileSize.HighPart ); 00446 00447 // 00448 // Check that the client name length is a legal length. 00449 // 00450 00451 if (ClientName.Length > LFS_CLIENT_NAME_MAX) { 00452 00453 DebugTrace( 0, Dbg, "Illegal name length for client\n", 0 ); 00454 DebugTrace( -1, Dbg, "LfsOpenLogFile: Exit\n", 0 ); 00455 ExRaiseStatus( STATUS_INVALID_PARAMETER ); 00456 } 00457 00458 // 00459 // Protect this call with a try-except. 00460 // 00461 00462 try { 00463 00464 // 00465 // Aqcuire the global data. 00466 // 00467 00468 LfsAcquireLfsData(); 00469 00470 // 00471 // Use a try-finally to facilitate cleanup. 00472 // 00473 00474 try { 00475 00476 // 00477 // Walk through the list searching for this file object. 00478 // 00479 00480 Link = LfsData.LfcbLinks.Flink; 00481 00482 while (Link != &LfsData.LfcbLinks) { 00483 00484 ThisLfcb = CONTAINING_RECORD( Link, LFCB, LfcbLinks ); 00485 00486 if (ThisLfcb->FileObject == LogFile) { 00487 00488 DebugTrace( 0, Dbg, "Found matching log file\n", 0 ); 00489 break; 00490 } 00491 00492 Link = Link->Flink; 00493 } 00494 00495 // 00496 // If the log file doesn't exist, create an Lfcb and perform an 00497 // Lfs restart. 00498 // 00499 00500 if (Link == &LfsData.LfcbLinks) { 00501 00502 // 00503 // Call the Cache Manager to disable read ahead and write behind; 00504 // we flush the log file explicitly. 00505 // 00506 00507 CcSetAdditionalCacheAttributes( LogFile, TRUE, TRUE ); 00508 00509 // 00510 // Perform Lfs restart on this file object. 00511 // 00512 00513 ThisLfcb = NewLfcb = LfsRestartLogFile( LogFile, 00514 MaximumClients, 00515 0, 00516 FileSize, 00517 LfsInfo, 00518 WriteData ); 00519 00520 // 00521 // Insert this Lfcb into the global list. 00522 // 00523 00524 InsertHeadList( &LfsData.LfcbLinks, &ThisLfcb->LfcbLinks ); 00525 } 00526 00527 // 00528 // At this point we have the log file control block for the file 00529 // object given us. We first check whether the log file is fatally 00530 // corrupt. 00531 // 00532 00533 if (FlagOn( ThisLfcb->Flags, LFCB_LOG_FILE_CORRUPT )) { 00534 00535 // 00536 // We leave the in-memory data alone and raise an error if 00537 // anyone attempts to access this file. 00538 // 00539 00540 DebugTrace( 0, Dbg, "The Lfcb is corrupt\n", 0 ); 00541 ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); 00542 } 00543 00544 // 00545 // Search through and look for a client match. 00546 // 00547 00548 ThisClient = ThisLfcb->RestartArea->ClientInUseList; 00549 00550 while (ThisClient != LFS_NO_CLIENT) { 00551 00552 ClientRecord = ThisLfcb->ClientArray + ThisClient; 00553 00554 if (ClientRecord->ClientNameLength == (ULONG) ClientName.Length 00555 && RtlCompareMemory( ClientRecord->ClientName, 00556 ClientName.Buffer, 00557 ClientName.Length ) == (ULONG) ClientName.Length) { 00558 00559 DebugTrace( 0, Dbg, "Matching client name found\n", 0 ); 00560 break; 00561 } 00562 00563 ThisClient = ClientRecord->NextClient; 00564 } 00565 00566 // 00567 // Allocate an Lch structure and link it into the Lfcb. 00568 // 00569 00570 LfsAllocateLch( &Lch ); 00571 InsertTailList( &ThisLfcb->LchLinks, &Lch->LchLinks ); 00572 00573 // 00574 // Initialize the client handle with the data from the Lfcb. 00575 // 00576 00577 Lch->Lfcb = ThisLfcb; 00578 Lch->Sync = ThisLfcb->Sync; 00579 Lch->Sync->UserCount += 1; 00580 00581 // 00582 // If a match isn't found, take a client block off the free list 00583 // if available. 00584 // 00585 00586 if (ThisClient == LFS_NO_CLIENT) { 00587 00588 // 00589 // Raise an error status if out of client blocks. 00590 // 00591 00592 ThisClient = ThisLfcb->RestartArea->ClientFreeList; 00593 00594 if (ThisClient == LFS_NO_CLIENT) { 00595 00596 DebugTrace( 0, Dbg, "No free client records available\n", 0 ); 00597 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 00598 } 00599 00600 // 00601 // Initialize the client block. 00602 // 00603 00604 ClientRecord = ThisLfcb->ClientArray + ThisClient; 00605 00606 LfsRemoveClientFromList( ThisLfcb->ClientArray, 00607 ClientRecord, 00608 &ThisLfcb->RestartArea->ClientFreeList ); 00609 00610 ClientRecord->ClientRestartLsn = LfsZeroLsn; 00611 ClientRecord->OldestLsn = ThisLfcb->OldestLsn; 00612 ClientRecord->ClientNameLength = ClientName.Length; 00613 RtlCopyMemory( ClientRecord->ClientName, 00614 ClientName.Buffer, 00615 ClientName.Length ); 00616 00617 // 00618 // Add it to the in use list. 00619 // 00620 00621 LfsAddClientToList( ThisLfcb->ClientArray, 00622 ThisClient, 00623 &ThisLfcb->RestartArea->ClientInUseList ); 00624 } 00625 00626 // 00627 // Update the client handle with the client block information. 00628 // 00629 00630 Lch->ClientId.SeqNumber = ClientRecord->SeqNumber; 00631 Lch->ClientId.ClientIndex = ThisClient; 00632 00633 Lch->ClientArrayByteOffset = PtrOffset( ThisLfcb->ClientArray, 00634 ClientRecord ); 00635 00636 *LogHandle = (LFS_LOG_HANDLE) Lch; 00637 00638 } finally { 00639 00640 DebugUnwind( LfsOpenLogFile ); 00641 00642 // 00643 // If the Lfcb has been acquired, we release it now. 00644 // 00645 00646 if (ThisLfcb != NULL) { 00647 00648 // 00649 // Pass information back to our caller for the number 00650 // of bytes to add to the reserved amount for a 00651 // log header. 00652 // 00653 00654 ReservedHeader = ThisLfcb->RecordHeaderLength; 00655 if (FlagOn( ThisLfcb->Flags, LFCB_PACK_LOG )) { 00656 00657 ReservedHeader *= 2; 00658 } 00659 00660 LfsReleaseLfcb( ThisLfcb ); 00661 } 00662 00663 // 00664 // If there is an error then deallocate the Lch and any new Lfcb. 00665 // 00666 00667 if (AbnormalTermination()) { 00668 00669 if (Lch != NULL) { 00670 00671 LfsDeallocateLch( Lch ); 00672 ThisLfcb->Sync->UserCount -= 1; 00673 } 00674 00675 if (NewLfcb != NULL) { 00676 00677 LfsDeallocateLfcb( NewLfcb, TRUE ); 00678 } 00679 } 00680 00681 // 00682 // Always free the global. 00683 // 00684 00685 LfsReleaseLfsData(); 00686 00687 DebugTrace( 0, Dbg, "Log Handle -> %08ln\n", *LogHandle ); 00688 DebugTrace( -1, Dbg, "LfsOpenLogFile: Exit\n", 0 ); 00689 } 00690 00691 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00692 00693 Status = GetExceptionCode(); 00694 } 00695 00696 if (Status != STATUS_SUCCESS) { 00697 00698 ExRaiseStatus( Status ); 00699 } 00700 00701 return ReservedHeader; 00702 }

LSN LfsQueryLastLsn IN LFS_LOG_HANDLE  LogHandle  ) 
 

Definition at line 701 of file querylog.c.

References _LFS_RESTART_AREA::CurrentLsn, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FlagOn, _LFCB::Flags, _LCH::Lfcb, LFCB_NO_LAST_LSN, LfsAcquireLch, LfsQueryLastLsn(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, LfsZeroLsn, LSN, NULL, PAGED_CODE, and _LFCB::RestartArea.

Referenced by LfsQueryLastLsn().

00707 : 00708 00709 This routine will return the most recent Lsn for this log record. 00710 00711 Arguments: 00712 00713 LogHandle - Pointer to private Lfs structure used to identify this 00714 client. 00715 00716 Return Value: 00717 00718 LSN - This is the last Lsn assigned in this log file. 00719 00720 --*/ 00721 00722 { 00723 PLCH Lch; 00724 00725 PLFCB Lfcb; 00726 00727 LSN LastLsn; 00728 00729 PAGED_CODE(); 00730 00731 DebugTrace( +1, Dbg, "LfsQueryLastLsn: Entered\n", 0 ); 00732 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00733 00734 Lch = (PLCH) LogHandle; 00735 00736 // 00737 // Check that the structure is a valid log handle structure. 00738 // 00739 00740 LfsValidateLch( Lch ); 00741 00742 // 00743 // Use a try-finally to facilitate cleanup. 00744 // 00745 00746 try { 00747 00748 // 00749 // Acquire the log file control block for this log file. 00750 // 00751 00752 LfsAcquireLch( Lch ); 00753 Lfcb = Lch->Lfcb; 00754 00755 // 00756 // If the Log file has been closed then refuse access. 00757 // 00758 00759 if (Lfcb == NULL) { 00760 00761 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00762 } 00763 00764 // 00765 // Check that the client Id is valid. 00766 // 00767 00768 LfsValidateClientId( Lfcb, Lch ); 00769 00770 // 00771 // Copy the last Lsn out of the Lfcb. If the last Lsn is 00772 // does not correspond to a log record, we will return the 00773 // zero Lsn. 00774 // 00775 00776 if (FlagOn( Lfcb->Flags, LFCB_NO_LAST_LSN )) { 00777 00778 LastLsn = LfsZeroLsn; 00779 00780 } else { 00781 00782 LastLsn = Lfcb->RestartArea->CurrentLsn; 00783 } 00784 00785 } finally { 00786 00787 DebugUnwind( LfsQueryLastLsn ); 00788 00789 // 00790 // Release the Lfcb if acquired. 00791 // 00792 00793 LfsReleaseLch( Lch ); 00794 00795 DebugTrace( 0, Dbg, "Last Lsn (Low) -> %08lx\n", LastLsn.LowPart ); 00796 DebugTrace( 0, Dbg, "Last Lsn (High) -> %08lx\n", LastLsn.HighPart ); 00797 DebugTrace( -1, Dbg, "LfsQueryLastLsn: Exit\n", 0 ); 00798 } 00799 00800 return LastLsn; 00801 }

VOID LfsReadLogFileInformation IN LFS_LOG_HANDLE  LogHandle,
IN PLOG_FILE_INFORMATION  Buffer,
IN OUT PULONG  Length
 

Definition at line 1141 of file lfs/registry.c.

References Buffer, _LOG_FILE_INFORMATION::ClientUndoCommitment, _LCH::ClientUndoCommitment, _LOG_FILE_INFORMATION::CurrentAvailable, _LFS_RESTART_AREA::CurrentLsn, Dbg, DebugTrace, DebugUnwind, _LOG_FILE_INFORMATION::LastFlushedLsn, _LFCB::LastFlushedLsn, _LOG_FILE_INFORMATION::LastLsn, _LCH::Lfcb, LfsAcquireLch, LfsCurrentAvailSpace(), LfsReadLogFileInformation(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, NULL, _LOG_FILE_INFORMATION::OldestLsn, _LFCB::OldestLsn, PAGED_CODE, _LFCB::RestartArea, _LOG_FILE_INFORMATION::TotalAvailable, _LFCB::TotalAvailable, _LOG_FILE_INFORMATION::TotalUndoCommitment, _LFCB::TotalUndoCommitment, and try_return.

Referenced by LfsReadLogFileInformation().

01149 : 01150 01151 This routine returns information about the current state of the log 01152 file, primarily to aid the client perform its checkpoint processing. 01153 01154 Arguments: 01155 01156 LogHandle - Pointer to private Lfs structure used to identify this 01157 client. 01158 01159 Buffer - Pointer to buffer to return the log file information. 01160 01161 Length - On input this is the length of the user's buffer. On output, 01162 it is the amount of data stored by the Lfs in the buffer. 01163 01164 Return Value: 01165 01166 None 01167 01168 --*/ 01169 01170 { 01171 PLCH Lch; 01172 PLFCB Lfcb; 01173 01174 PAGED_CODE(); 01175 01176 DebugTrace( +1, Dbg, "LfsReadLogFileInformation: Entered\n", 0 ); 01177 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 01178 DebugTrace( 0, Dbg, "Buffer -> %08lx\n", Buffer ); 01179 DebugTrace( 0, Dbg, "Length -> %08lx\n", *Length ); 01180 01181 Lch = (PLCH) LogHandle; 01182 01183 // 01184 // Check that the structure is a valid log handle structure. 01185 // 01186 01187 LfsValidateLch( Lch ); 01188 01189 // 01190 // Use a try-finally to facilitate cleanup. 01191 // 01192 01193 try { 01194 01195 // 01196 // Acquire the log file control block for this log file. 01197 // 01198 01199 LfsAcquireLch( Lch ); 01200 Lfcb = Lch->Lfcb; 01201 01202 // 01203 // If the Log file has been closed then return immediately. 01204 // 01205 01206 if (Lfcb == NULL) { 01207 01208 try_return( *Length = 0 ); 01209 } 01210 01211 // 01212 // Check that the client Id is valid. 01213 // 01214 01215 LfsValidateClientId( Lfcb, Lch ); 01216 01217 // 01218 // The buffer better be large enough. 01219 // 01220 01221 if (*Length >= sizeof( LOG_FILE_INFORMATION )) { 01222 01223 PLOG_FILE_INFORMATION Information; 01224 LONGLONG CurrentAvail; 01225 ULONG UnusedBytes; 01226 01227 LfsCurrentAvailSpace( Lfcb, 01228 &CurrentAvail, 01229 &UnusedBytes ); 01230 01231 // 01232 // Cast a pointer to the buffer and fill in the 01233 // data. 01234 // 01235 01236 Information = (PLOG_FILE_INFORMATION) Buffer; 01237 01238 Information->TotalAvailable = Lfcb->TotalAvailable; 01239 Information->CurrentAvailable = CurrentAvail; 01240 Information->TotalUndoCommitment = Lfcb->TotalUndoCommitment; 01241 Information->ClientUndoCommitment = Lch->ClientUndoCommitment; 01242 01243 Information->OldestLsn = Lfcb->OldestLsn; 01244 Information->LastFlushedLsn = Lfcb->LastFlushedLsn; 01245 Information->LastLsn = Lfcb->RestartArea->CurrentLsn; 01246 01247 *Length = sizeof( LOG_FILE_INFORMATION ); 01248 01249 } else { 01250 01251 *Length = 0; 01252 } 01253 01254 try_exit: NOTHING; 01255 } finally { 01256 01257 DebugUnwind( LfsReadLogFileInformation ); 01258 01259 // 01260 // Release the log file control block if held. 01261 // 01262 01263 LfsReleaseLch( Lch ); 01264 01265 DebugTrace( -1, Dbg, "LfsReadLogFileInformation: Exit\n", 0 ); 01266 } 01267 01268 return; 01269 }

VOID LfsReadLogRecord IN LFS_LOG_HANDLE  LogHandle,
IN LSN  FirstLsn,
IN LFS_CONTEXT_MODE  ContextMode,
OUT PLFS_LOG_CONTEXT  Context,
OUT PLFS_RECORD_TYPE  RecordType,
OUT TRANSACTION_ID TransactionId,
OUT PLSN  UndoNextLsn,
OUT PLSN  PreviousLsn,
OUT PULONG  BufferLength,
OUT PVOID *  Buffer
 

Definition at line 72 of file querylog.c.

References Add2Ptr, Buffer, _LFCB::ClientArray, _LCH::ClientArrayByteOffset, _LCH::ClientId, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), _LCH::Lfcb, LfsAcquireLch, LfsAllocateLcb(), LfsContextForward, LfsContextPrevious, LfsContextUndoNext, LfsDeallocateLcb(), LfsExceptionFilter(), LfsFindLogRecord(), LfsInitializeLcb, LfsReadLogRecord(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, LfsVerifyClientLsnInRange, NTSTATUS(), NULL, PAGED_CODE, and Status.

Referenced by LfsReadLogRecord().

00087 : 00088 00089 This routine initiates the query operation. It returns the log record 00090 in question and a context structure used by the Lfs to return related 00091 log records. The caller specifies what mode of query to use. He may 00092 walk backwards through the file by Undo records or all records for 00093 this client linked through the previous Lsn fields. He may also look 00094 forwards through the file for all records for the issuing client. 00095 00096 Arguments: 00097 00098 LogHandle - Pointer to private Lfs structure used to identify this 00099 client. 00100 00101 FirstLsn - Starting record for this query operation. 00102 00103 ContextMode - Method of query. 00104 00105 Context - Supplies the address to store a pointer to the Lfs created 00106 context structure. 00107 00108 RecordType - Supplies the address to store the record type of this 00109 log record. 00110 00111 TransactionId - Supplies the address to store the transaction Id of 00112 this log record. 00113 00114 UndoNextLsn - Supplies the address to store the Undo Next Lsn for this 00115 log record. 00116 00117 PreviousLsn - Supplies the address to store the Previous Lsn for this 00118 log record. 00119 00120 BufferLength - This is the length of the log data. 00121 00122 Buffer - This is a pointer to the start of the log data. 00123 00124 Return Value: 00125 00126 None 00127 00128 --*/ 00129 00130 { 00131 volatile NTSTATUS Status = STATUS_SUCCESS; 00132 00133 PLFS_CLIENT_RECORD ClientRecord; 00134 00135 PLCH Lch; 00136 00137 PLFCB Lfcb; 00138 00139 PLCB Lcb = NULL; 00140 00141 PAGED_CODE(); 00142 00143 DebugTrace( +1, Dbg, "LfsReadLogRecord: Entered\n", 0 ); 00144 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00145 DebugTrace( 0, Dbg, "First Lsn (Low) -> %08lx\n", FirstLsn.LowPart ); 00146 DebugTrace( 0, Dbg, "First Lsn (High) -> %08lx\n", FirstLsn.HighPart ); 00147 DebugTrace( 0, Dbg, "Context Mode -> %08lx\n", ContextMode ); 00148 00149 Lch = (PLCH) LogHandle; 00150 00151 // 00152 // Check that the context mode is valid. 00153 // 00154 00155 switch (ContextMode) { 00156 00157 case LfsContextUndoNext : 00158 case LfsContextPrevious : 00159 case LfsContextForward : 00160 00161 break; 00162 00163 default: 00164 00165 DebugTrace( 0, Dbg, "Invalid context mode -> %08x\n", ContextMode ); 00166 ExRaiseStatus( STATUS_INVALID_PARAMETER ); 00167 } 00168 00169 // 00170 // Check that the structure is a valid log handle structure. 00171 // 00172 00173 LfsValidateLch( Lch ); 00174 00175 // 00176 // Use a try-except to catch errors. 00177 // 00178 00179 try { 00180 00181 // 00182 // Use a try-finally to facilitate cleanup. 00183 // 00184 00185 try { 00186 00187 // 00188 // Acquire the log file control block for this log file. 00189 // 00190 00191 LfsAcquireLch( Lch ); 00192 Lfcb = Lch->Lfcb; 00193 00194 // 00195 // If the Log file has been closed then refuse access. 00196 // 00197 00198 if (Lfcb == NULL) { 00199 00200 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00201 } 00202 00203 // 00204 // Check that the client Id is valid. 00205 // 00206 00207 LfsValidateClientId( Lfcb, Lch ); 00208 00209 // 00210 // Check that the given Lsn is in the legal range for this client. 00211 // 00212 00213 ClientRecord = Add2Ptr( Lfcb->ClientArray, 00214 Lch->ClientArrayByteOffset, 00215 PLFS_CLIENT_RECORD ); 00216 00217 if (!LfsVerifyClientLsnInRange( Lfcb, ClientRecord, FirstLsn )) { 00218 00219 ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); 00220 } 00221 00222 // 00223 // We can give up the Lfcb as we know the Lsn is within the file. 00224 // 00225 00226 LfsReleaseLch( Lch ); 00227 00228 // 00229 // Allocate and initialize a context structure. 00230 // 00231 00232 LfsAllocateLcb( Lfcb, &Lcb ); 00233 00234 LfsInitializeLcb( Lcb, 00235 Lch->ClientId, 00236 ContextMode ); 00237 00238 // 00239 // Find the log record indicated by the given Lsn. 00240 // 00241 00242 LfsFindLogRecord( Lfcb, 00243 Lcb, 00244 FirstLsn, 00245 RecordType, 00246 TransactionId, 00247 UndoNextLsn, 00248 PreviousLsn, 00249 BufferLength, 00250 Buffer ); 00251 00252 // 00253 // Update the client's arguments. 00254 // 00255 00256 *Context = Lcb; 00257 Lcb = NULL; 00258 00259 } finally { 00260 00261 DebugUnwind( LfsReadLogRecord ); 00262 00263 // 00264 // Release the log file control block if held. 00265 // 00266 00267 LfsReleaseLch( Lch ); 00268 00269 // 00270 // Deallocate the context block if an error occurred. 00271 // 00272 00273 if (Lcb != NULL) { 00274 00275 LfsDeallocateLcb( Lfcb, Lcb ); 00276 } 00277 00278 DebugTrace( 0, Dbg, "Context -> %08lx\n", *Context ); 00279 DebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); 00280 DebugTrace( 0, Dbg, "Buffer -> %08lx\n", *Buffer ); 00281 DebugTrace( -1, Dbg, "LfsReadLogRecord: Exit\n", 0 ); 00282 } 00283 00284 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00285 00286 Status = GetExceptionCode(); 00287 } 00288 00289 if (Status != STATUS_SUCCESS) { 00290 00291 ExRaiseStatus( Status ); 00292 } 00293 00294 return; 00295 }

BOOLEAN LfsReadNextLogRecord IN LFS_LOG_HANDLE  LogHandle,
IN OUT LFS_LOG_CONTEXT  Context,
OUT PLFS_RECORD_TYPE  RecordType,
OUT TRANSACTION_ID TransactionId,
OUT PLSN  UndoNextLsn,
OUT PLSN  PreviousLsn,
OUT PLSN  Lsn,
OUT PULONG  BufferLength,
OUT PVOID *  Buffer
 

Definition at line 299 of file querylog.c.

References _LCB::AuxilaryBuffer, Buffer, CcUnpinData(), _LCB::CurrentLogRecord, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsFindClientNextLsn(), LfsFindLogRecord(), LfsFreeSpanningBuffer(), LfsReadNextLogRecord(), LfsReleaseLch, LfsReleaseLfcb, LfsValidateClientId, LfsValidateLcb, LfsValidateLch, NTSTATUS(), NULL, PAGED_CODE, _LCB::RecordHeader, _LCB::RecordHeaderBcb, Status, and TRUE.

Referenced by LfsReadNextLogRecord().

00313 : 00314 00315 This routine is called to continue a query operation. The Lfs uses 00316 private information stored in the context structure to determine the 00317 next log record to return to the caller. 00318 00319 Arguments: 00320 00321 LogHandle - Pointer to private Lfs structure used to identify this 00322 client. 00323 00324 Context - Supplies the address to store a pointer to the Lfs created 00325 context structure. 00326 00327 Lsn - Lsn for this log record. 00328 00329 RecordType - Supplies the address to store the record type of this 00330 log record. 00331 00332 TransactionId - Supplies the address to store the transaction Id of 00333 this log record. 00334 00335 UndoNextLsn - Supplies the address to store the Undo Next Lsn for this 00336 log record. 00337 00338 PreviousLsn - Supplies the address to store the Previous Lsn for this 00339 log record. 00340 00341 BufferLength - This is the length of the log data. 00342 00343 Buffer - This is a pointer to the start of the log data. 00344 00345 Return Value: 00346 00347 None 00348 00349 --*/ 00350 00351 { 00352 volatile NTSTATUS Status = STATUS_SUCCESS; 00353 00354 PLCH Lch; 00355 00356 PLFCB Lfcb; 00357 00358 PLCB Lcb; 00359 00360 BOOLEAN FoundNextLsn; 00361 00362 BOOLEAN UnwindRememberLcbFields; 00363 PBCB UnwindRecordHeaderBcb; 00364 PLFS_RECORD_HEADER UnwindRecordHeader; 00365 PVOID UnwindCurrentLogRecord; 00366 BOOLEAN UnwindAuxilaryBuffer; 00367 00368 PAGED_CODE(); 00369 00370 DebugTrace( +1, Dbg, "LfsReadNextLogRecord: Entered\n", 0 ); 00371 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00372 DebugTrace( 0, Dbg, "Context -> %08lx\n", Context ); 00373 00374 FoundNextLsn = FALSE; 00375 00376 UnwindRememberLcbFields = FALSE; 00377 00378 Lch = (PLCH) LogHandle; 00379 Lcb = (PLCB) Context; 00380 00381 // 00382 // Check that the structure is a valid log handle structure. 00383 // 00384 00385 LfsValidateLch( Lch ); 00386 00387 // 00388 // Use a try-except to catch errors. 00389 // 00390 00391 try { 00392 00393 // 00394 // Use a try-finally to facilitate cleanup. 00395 // 00396 00397 try { 00398 00399 // 00400 // Acquire the log file control block for this log file. 00401 // 00402 00403 LfsAcquireLch( Lch ); 00404 Lfcb = Lch->Lfcb; 00405 00406 // 00407 // If the Log file has been closed then refuse access. 00408 // 00409 00410 if (Lfcb == NULL) { 00411 00412 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00413 } 00414 00415 // 00416 // Check that the client Id is valid. 00417 // 00418 00419 LfsValidateClientId( Lfcb, Lch ); 00420 00421 // 00422 // Check that the context structure is valid. 00423 // 00424 00425 LfsValidateLcb( Lcb, Lch ); 00426 00427 // 00428 // Remember any context fields to be overwritten. 00429 // 00430 00431 UnwindRememberLcbFields = TRUE; 00432 00433 UnwindRecordHeaderBcb = Lcb->RecordHeaderBcb; 00434 Lcb->RecordHeaderBcb = NULL; 00435 00436 UnwindRecordHeader = Lcb->RecordHeader; 00437 UnwindCurrentLogRecord = Lcb->CurrentLogRecord; 00438 00439 UnwindAuxilaryBuffer = Lcb->AuxilaryBuffer; 00440 Lcb->AuxilaryBuffer = FALSE; 00441 00442 // 00443 // Find the next Lsn number based on the current Lsn number in 00444 // the context block. 00445 // 00446 00447 if (LfsFindClientNextLsn( Lfcb, Lcb, Lsn )) { 00448 00449 // 00450 // We can give up the Lfcb as we know the Lsn is within the file. 00451 // 00452 00453 LfsReleaseLfcb( Lfcb ); 00454 00455 // 00456 // Cleanup the context block so we can do the next search. 00457 // 00458 00459 Lcb->CurrentLogRecord = NULL; 00460 Lcb->AuxilaryBuffer = FALSE; 00461 00462 // 00463 // Perform the work of getting the log record. 00464 // 00465 00466 LfsFindLogRecord( Lfcb, 00467 Lcb, 00468 *Lsn, 00469 RecordType, 00470 TransactionId, 00471 UndoNextLsn, 00472 PreviousLsn, 00473 BufferLength, 00474 Buffer ); 00475 00476 FoundNextLsn = TRUE; 00477 } 00478 00479 } finally { 00480 00481 DebugUnwind( LfsReadNextLogRecord ); 00482 00483 // 00484 // If we exited due to an error, we have to restore the context 00485 // block. 00486 // 00487 00488 if (UnwindRememberLcbFields) { 00489 00490 if (AbnormalTermination()) { 00491 00492 // 00493 // If the record header in the context block is not 00494 // the same as we started with. Then we unpin that 00495 // data. 00496 // 00497 00498 if (Lcb->RecordHeaderBcb != NULL) { 00499 00500 CcUnpinData( Lcb->RecordHeaderBcb ); 00501 00502 } 00503 00504 if (Lcb->CurrentLogRecord != NULL 00505 && Lcb->AuxilaryBuffer == TRUE) { 00506 00507 LfsFreeSpanningBuffer( Lcb->CurrentLogRecord ); 00508 } 00509 00510 Lcb->RecordHeaderBcb = UnwindRecordHeaderBcb; 00511 Lcb->RecordHeader = UnwindRecordHeader; 00512 Lcb->CurrentLogRecord = UnwindCurrentLogRecord; 00513 Lcb->AuxilaryBuffer = UnwindAuxilaryBuffer; 00514 00515 // 00516 // Otherwise, if we have successfully found the next Lsn, 00517 // we free up any resources being held from the previous search. 00518 // 00519 00520 } else if (FoundNextLsn ) { 00521 00522 if (UnwindRecordHeaderBcb != NULL) { 00523 00524 CcUnpinData( UnwindRecordHeaderBcb ); 00525 } 00526 00527 if (UnwindCurrentLogRecord != NULL 00528 && UnwindAuxilaryBuffer == TRUE) { 00529 00530 LfsFreeSpanningBuffer( UnwindCurrentLogRecord ); 00531 } 00532 00533 // 00534 // Restore the Bcb and auxilary buffer field for the final 00535 // cleanup. 00536 // 00537 00538 } else { 00539 00540 if (UnwindRecordHeaderBcb != NULL) { 00541 00542 if (Lcb->RecordHeaderBcb != NULL) { 00543 00544 CcUnpinData( UnwindRecordHeaderBcb ); 00545 00546 } else { 00547 00548 Lcb->RecordHeaderBcb = UnwindRecordHeaderBcb; 00549 } 00550 } 00551 00552 if (UnwindAuxilaryBuffer) { 00553 00554 if (Lcb->CurrentLogRecord == UnwindCurrentLogRecord) { 00555 00556 Lcb->AuxilaryBuffer = TRUE; 00557 00558 } else { 00559 00560 LfsFreeSpanningBuffer( UnwindCurrentLogRecord ); 00561 } 00562 } 00563 } 00564 } 00565 00566 // 00567 // Release the log file control block if held. 00568 // 00569 00570 LfsReleaseLch( Lch ); 00571 00572 DebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn->LowPart ); 00573 DebugTrace( 0, Dbg, "Lsn (High) -> %08lx\n", Lsn->HighPart ); 00574 DebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); 00575 DebugTrace( 0, Dbg, "Buffer -> %08lx\n", *Buffer ); 00576 DebugTrace( -1, Dbg, "LfsReadNextLogRecord: Exit\n", 0 ); 00577 } 00578 00579 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00580 00581 Status = GetExceptionCode(); 00582 } 00583 00584 if (Status != STATUS_SUCCESS) { 00585 00586 ExRaiseStatus( Status ); 00587 } 00588 00589 return FoundNextLsn; 00590 }

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 LfsResetUndoTotal IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  NumberRecords,
IN LONG  ResetTotal
 

Definition at line 1361 of file lfs/registry.c.

References _LCH::ClientUndoCommitment, Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FlagOn, _LFCB::Flags, _LCH::Lfcb, LFCB_PACK_LOG, LfsAcquireLch, LfsReleaseLch, LfsResetUndoTotal(), LfsValidateClientId, LfsValidateLch, NULL, PAGED_CODE, _LFCB::RecordHeaderLength, and _LFCB::TotalUndoCommitment.

Referenced by LfsResetUndoTotal().

01369 : 01370 01371 This routine is called to adjust the undo commitment for this client. 01372 If the reset total is positive, then we absolutely set the 01373 reserve value for the client using this as the basis. If the value 01374 is negative, we will adjust the current value for the client. 01375 01376 To adjust the values in the Lfcb, we first return the Undo commitment 01377 in the handle and then adjust by the values passed in. 01378 01379 To adjust the value in the client handle, we simply set it if 01380 the reset value is positive, adjust it if the value is negative. 01381 01382 For a packed log file we just reserve the space requested. We 01383 have already taken into account the loss of the tail of each page. 01384 For an unpacked log file we double each value. 01385 01386 Arguments: 01387 01388 LogHandle - Pointer to private Lfs structure used to identify this 01389 client. 01390 01391 NumberRecords - This is the number of records we should assume the 01392 reset total covers. We allow an Lfs header for 01393 each one. 01394 01395 ResetTotal - This is the amount to adjust (or set) the undo 01396 commitment. 01397 01398 Return Value: 01399 01400 None 01401 01402 --*/ 01403 01404 { 01405 PLCH Lch; 01406 01407 PLFCB Lfcb; 01408 01409 LONGLONG AdjustedUndoTotal; 01410 LONG LfsHeaderBytes; 01411 01412 PAGED_CODE(); 01413 01414 DebugTrace( +1, Dbg, "LfsResetUndoTotal: Entered\n", 0 ); 01415 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 01416 DebugTrace( 0, Dbg, "Number Records -> %08lx\n", NumberRecords ); 01417 DebugTrace( 0, Dbg, "ResetTotal -> %08lx\n", ResetTotal ); 01418 01419 Lch = (PLCH) LogHandle; 01420 01421 // 01422 // Check that the structure is a valid log handle structure. 01423 // 01424 01425 LfsValidateLch( Lch ); 01426 01427 // 01428 // Use a try-finally to facilitate cleanup. 01429 // 01430 01431 try { 01432 01433 // 01434 // Acquire the log file control block for this log file. 01435 // 01436 01437 LfsAcquireLch( Lch ); 01438 Lfcb = Lch->Lfcb; 01439 01440 // 01441 // If the Log file has been closed then refuse access. 01442 // 01443 01444 if (Lfcb == NULL) { 01445 01446 ExRaiseStatus( STATUS_ACCESS_DENIED ); 01447 } 01448 01449 // 01450 // Check that the client Id is valid. 01451 // 01452 01453 LfsValidateClientId( Lfcb, Lch ); 01454 01455 // 01456 // Compute the adjusted reset total. Start by computing the 01457 // bytes needed for the Lfs log headers. Add (or subtract) this 01458 // from the reset total and multiply by 2 (only if not packing the 01459 // log). 01460 // 01461 01462 LfsHeaderBytes = NumberRecords * Lfcb->RecordHeaderLength; 01463 LfsHeaderBytes *= 2; 01464 01465 if (!FlagOn( Lfcb->Flags, LFCB_PACK_LOG )) { 01466 01467 ResetTotal *= 2; 01468 } 01469 01470 // 01471 // If the reset total is positive, add the header bytes. 01472 // 01473 01474 if (ResetTotal > 0) { 01475 01476 // 01477 // Subtract the client's current value from the TotalUndo 01478 // commit if he is setting his value exactly. 01479 // 01480 01481 Lfcb->TotalUndoCommitment = Lfcb->TotalUndoCommitment - Lch->ClientUndoCommitment; 01482 01483 // 01484 // We can clear the values in the user's handle at this 01485 // time. 01486 // 01487 01488 Lch->ClientUndoCommitment = 0; 01489 01490 01491 ResetTotal += LfsHeaderBytes; 01492 01493 // 01494 // Otherwise subtract the value for the header bytes. 01495 // 01496 01497 } else { 01498 01499 ResetTotal -= LfsHeaderBytes; 01500 } 01501 01502 // 01503 // Now we adjust the Lfcb and Lch values by the adjustment amount. 01504 // 01505 01506 AdjustedUndoTotal = ResetTotal; 01507 01508 Lfcb->TotalUndoCommitment = Lfcb->TotalUndoCommitment + AdjustedUndoTotal; 01509 01510 Lch->ClientUndoCommitment = Lch->ClientUndoCommitment + AdjustedUndoTotal; 01511 01512 } finally { 01513 01514 DebugUnwind( LfsResetUndoTotal ); 01515 01516 // 01517 // Release the log file control block if held. 01518 // 01519 01520 LfsReleaseLch( Lch ); 01521 01522 DebugTrace( -1, Dbg, "LfsResetUndoTotal: Exit\n", 0 ); 01523 } 01524 01525 return; 01526 }

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 LfsTerminateLogQuery IN LFS_LOG_HANDLE  LogHandle,
IN LFS_LOG_CONTEXT  Context
 

Definition at line 594 of file querylog.c.

References Dbg, DebugTrace, DebugUnwind, _LCH::Lfcb, LfsAcquireLch, LfsDeallocateLcb(), LfsReleaseLch, LfsTerminateLogQuery(), LfsValidateClientId, LfsValidateLcb, LfsValidateLch, NULL, PAGED_CODE, and try_return.

Referenced by LfsTerminateLogQuery().

00601 : 00602 00603 This routine is called when a client has completed his query operation 00604 and wishes to deallocate any resources acquired by the Lfs to 00605 perform the log file query. 00606 00607 Arguments: 00608 00609 LogHandle - Pointer to private Lfs structure used to identify this 00610 client. 00611 00612 Context - Supplies the address to store a pointer to the Lfs created 00613 context structure. 00614 00615 Return Value: 00616 00617 None 00618 00619 --*/ 00620 00621 { 00622 PLCH Lch; 00623 PLCB Lcb; 00624 00625 PLFCB Lfcb; 00626 00627 PAGED_CODE(); 00628 00629 DebugTrace( +1, Dbg, "LfsTerminateLogQuery: Entered\n", 0 ); 00630 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00631 DebugTrace( 0, Dbg, "Context -> %08lx\n", Context ); 00632 00633 Lch = (PLCH) LogHandle; 00634 Lcb = (PLCB) Context; 00635 00636 // 00637 // Check that the structure is a valid log handle structure. 00638 // 00639 00640 LfsValidateLch( Lch ); 00641 00642 // 00643 // Use a try-finally to facilitate cleanup. 00644 // 00645 00646 try { 00647 00648 // 00649 // Acquire the log file control block for this log file. 00650 // 00651 00652 LfsAcquireLch( Lch ); 00653 Lfcb = Lch->Lfcb; 00654 00655 // 00656 // If the Log file has been closed then refuse access. 00657 // 00658 00659 if (Lfcb == NULL) { 00660 00661 try_return( NOTHING ); 00662 } 00663 00664 // 00665 // Check that the client Id is valid. 00666 // 00667 00668 LfsValidateClientId( Lfcb, Lch ); 00669 00670 // 00671 // Check that the context structure is valid. 00672 // 00673 00674 LfsValidateLcb( Lcb, Lch ); 00675 00676 // 00677 // Deallocate the context block. 00678 // 00679 00680 LfsDeallocateLcb( Lfcb, Lcb ); 00681 00682 try_exit: NOTHING; 00683 } finally { 00684 00685 DebugUnwind( LfsTerminateLogQuery ); 00686 00687 // 00688 // Release the Lfcb if acquired. 00689 // 00690 00691 LfsReleaseLch( Lch ); 00692 00693 DebugTrace( -1, Dbg, "LfsTerminateLogQuery: Exit\n", 0 ); 00694 } 00695 00696 return; 00697 }

BOOLEAN LfsVerifyLogFile IN LFS_LOG_HANDLE  LogHandle,
IN PVOID  LogFileHeader,
IN ULONG  Length
 

Definition at line 1273 of file lfs/registry.c.

References Add2Ptr, _LFCB::CurrentOpenLogCount, FALSE, _LCH::Lfcb, LFS_NTC_LCH, LFS_NTC_LFCB, LFS_SIGNATURE_RESTART_PAGE_ULONG, LfsAcquireLch, LfsReleaseLch, LfsReleaseLfcb, _LCH::NodeTypeCode, _LFCB::NodeTypeCode, NULL, PAGED_CODE, _LFS_RESTART_PAGE_HEADER::RestartOffset, _LFCB::SystemPageSize, and TRUE.

01281 : 01282 01283 This routine is called by a client to verify that the volume has not been removed 01284 from the system and then reattached. We will verify the log file open count on 01285 disk matches the value in the user's handle. 01286 01287 Arguments: 01288 01289 LogHandle - Pointer to private Lfs structure used to identify this 01290 client. 01291 01292 LogFileHeader - Pointer to start of log file. 01293 01294 Length - Number bytes returned with the read. 01295 01296 Return Value: 01297 01298 BOOLEAN - TRUE if the log file has not been altered externally, FALSE if we 01299 fail for any reason. 01300 01301 --*/ 01302 01303 { 01304 BOOLEAN ValidLogFile = FALSE; 01305 PLCH Lch; 01306 PLFCB Lfcb; 01307 01308 PLFS_RESTART_PAGE_HEADER RestartPage = LogFileHeader; 01309 01310 PAGED_CODE(); 01311 01312 Lch = (PLCH) LogHandle; 01313 01314 // 01315 // Check that the structure is a valid log handle structure. 01316 // 01317 01318 if ((Lch == NULL) || 01319 (Lch->NodeTypeCode != LFS_NTC_LCH) || 01320 ((Lch->Lfcb != NULL) && 01321 (Lch->Lfcb->NodeTypeCode != LFS_NTC_LFCB))) { 01322 01323 return FALSE; 01324 } 01325 01326 // 01327 // Acquire the log file control block for this log file. 01328 // 01329 01330 LfsAcquireLch( Lch ); 01331 Lfcb = Lch->Lfcb; 01332 01333 // 01334 // If the Log file has been closed then return immediately. 01335 // 01336 01337 if (Lfcb == NULL) { 01338 01339 LfsReleaseLch( Lch ); 01340 return FALSE; 01341 } 01342 01343 // 01344 // Check that we have at least one page and that the page is valid. 01345 // 01346 01347 if ((Length >= (ULONG) Lfcb->SystemPageSize) && 01348 (*((PULONG) RestartPage) == LFS_SIGNATURE_RESTART_PAGE_ULONG) && 01349 ((RestartPage->RestartOffset + sizeof( LFS_RESTART_AREA )) < (ULONG) Lfcb->SystemPageSize) && 01350 ((Add2Ptr( RestartPage, RestartPage->RestartOffset, PLFS_RESTART_AREA ))->RestartOpenLogCount == Lfcb->CurrentOpenLogCount)) { 01351 01352 ValidLogFile = TRUE; 01353 } 01354 01355 LfsReleaseLfcb( Lfcb ); 01356 return ValidLogFile; 01357 }

BOOLEAN LfsWrite IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  NumberOfWriteEntries,
IN PLFS_WRITE_ENTRY  WriteEntries,
IN LFS_RECORD_TYPE  RecordType,
IN TRANSACTION_ID *TransactionId  OPTIONAL,
IN LSN  UndoNextLsn,
IN LSN  PreviousLsn,
IN LONG  UndoRequirement,
OUT PLSN  Lsn
 

Definition at line 39 of file lfs/write.c.

References Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, LfsWrite(), LfsWriteLogRecordIntoLogPage(), NTSTATUS(), NULL, PAGED_CODE, PLFS_WRITE_ENTRY, and Status.

Referenced by LfsWrite().

00053 : 00054 00055 This routine is called by a client to write a log record to the log file. 00056 The log record is lazy written and is not guaranteed to be on the disk 00057 until a subsequent LfsForceWrie or LfsWriteRestartArea or until 00058 an LfsFlushtoLsn is issued withan Lsn greater-than or equal to the Lsn 00059 returned from this service. 00060 00061 Arguments: 00062 00063 LogHandle - Pointer to private Lfs structure used to identify this 00064 client. 00065 00066 NumberOfWriteEntries - Number of components of the log record. 00067 00068 WriteEntries - Pointer to an array of write entries. 00069 00070 RecordType - Lfs defined type for this log record. 00071 00072 TransactionId - Id value used to group log records by complete transaction. 00073 00074 UndoNextLsn - Lsn of a previous log record which needs to be undone in 00075 the event of a client restart. 00076 00077 PreviousLsn - Lsn of the immediately previous log record for this client. 00078 00079 Lsn - Lsn to be associated with this log record. 00080 00081 Return Value: 00082 00083 BOOLEAN - Advisory, TRUE indicates that less than 1/4 of the log file is 00084 available. 00085 00086 --*/ 00087 00088 { 00089 volatile NTSTATUS Status = STATUS_SUCCESS; 00090 00091 BOOLEAN LogFileFull = FALSE; 00092 PLCH Lch; 00093 00094 PLFCB Lfcb; 00095 00096 PAGED_CODE(); 00097 00098 DebugTrace( +1, Dbg, "LfsWrite: Entered\n", 0 ); 00099 DebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); 00100 DebugTrace( 0, Dbg, "NumberOfWriteEntries -> %08lx\n", NumberOfWriteEntries ); 00101 DebugTrace( 0, Dbg, "WriteEntries -> %08lx\n", WriteEntries ); 00102 DebugTrace( 0, Dbg, "Record Type -> %08lx\n", RecordType ); 00103 DebugTrace( 0, Dbg, "Transaction Id -> %08lx\n", TransactionId ); 00104 DebugTrace( 0, Dbg, "UndoNextLsn (Low) -> %08lx\n", UndoNextLsn.LowPart ); 00105 DebugTrace( 0, Dbg, "UndoNextLsn (High) -> %08lx\n", UndoNextLsn.HighPart ); 00106 DebugTrace( 0, Dbg, "PreviousLsn (Low) -> %08lx\n", PreviousLsn.LowPart ); 00107 DebugTrace( 0, Dbg, "PreviousLsn (High) -> %08lx\n", PreviousLsn.HighPart ); 00108 00109 Lch = (PLCH) LogHandle; 00110 00111 // 00112 // Check that the structure is a valid log handle structure. 00113 // 00114 00115 LfsValidateLch( Lch ); 00116 00117 // 00118 // Use a try-except to catch errors. 00119 // 00120 00121 try { 00122 00123 // 00124 // Use a try-finally to facilitate cleanup. 00125 // 00126 00127 try { 00128 00129 // 00130 // Acquire the log file control block for this log file. 00131 // 00132 00133 LfsAcquireLch( Lch ); 00134 Lfcb = Lch->Lfcb; 00135 00136 // 00137 // If the Log file has been closed then refuse access. 00138 // 00139 00140 if (Lfcb == NULL) { 00141 00142 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00143 } 00144 00145 // 00146 // Check that the client Id is valid. 00147 // 00148 00149 LfsValidateClientId( Lfcb, Lch ); 00150 00151 // 00152 // Write the log record. 00153 // 00154 00155 LogFileFull = LfsWriteLogRecordIntoLogPage( Lfcb, 00156 Lch, 00157 NumberOfWriteEntries, 00158 WriteEntries, 00159 RecordType, 00160 TransactionId, 00161 UndoNextLsn, 00162 PreviousLsn, 00163 UndoRequirement, 00164 FALSE, 00165 Lsn ); 00166 00167 } finally { 00168 00169 DebugUnwind( LfsWrite ); 00170 00171 // 00172 // Release the log file control block if held. 00173 // 00174 00175 LfsReleaseLch( Lch ); 00176 00177 DebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn->LowPart ); 00178 DebugTrace( 0, Dbg, "Lsn (High) -> %08lx\n", Lsn->HighPart ); 00179 DebugTrace( -1, Dbg, "LfsWrite: Exit\n", 0 ); 00180 } 00181 00182 } except (LfsExceptionFilter( GetExceptionInformation() )) { 00183 00184 Status = GetExceptionCode(); 00185 } 00186 00187 if (Status != STATUS_SUCCESS) { 00188 00189 ExRaiseStatus( Status ); 00190 } 00191 00192 return LogFileFull; 00193 }

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, Buffer, _LFS_WRITE_ENTRY::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 }


Variable Documentation

LSN LfsZeroLsn
 

Definition at line 147 of file lfs.h.

Referenced by LfsCloseLogFile(), LfsOpenLogFile(), LfsQueryLastLsn(), LfsReadRestartArea(), and LfsWriteRestartArea().


Generated on Sat May 15 19:44:32 2004 for test by doxygen 1.3.7