|
|
/*++ BUILD Version: 0000 // Increment this if a change has global effects
Copyright (c) 1989 Microsoft Corporation
Module Name:
Lfs.h
Abstract:
This module contains the public data structures and procedure prototypes for the Log File Service.
Author: Brian Andrew [BrianAn] 20-June-1991
Revision History:
--*/
#ifndef _LFS_
#define _LFS_
//
// The Multi-Sector Header and Update Sequence Array provide detection of
// incomplete multi-sector transfers for devices which either have a
// physical sector size equal to the Sequence Number Stride or greater, or
// which do not transfer sectors out of order. If a device exists which has
// a sector size smaller than the Sequence Number Stride *and* it sometimes
// transfers sectors out of order, then the Update Sequence Array will not
// provide absolute detection of incomplete transfers. The Sequence Number
// Stride is set to a small enough number to provide absolute protection for
// all known hard disks. It is not set any smaller, in order to avoid
// excessive run time and space overhead.
//
// The Multi-Sector Header contains space for a four-byte signature for the
// convenience of its user. It then provides the offset to and length of the
// the Update Sequence Array. The Update Sequence Array consists of an array
// of n saved USHORTs, where n is the size of the structure being protected
// divided by the sequence number stride. (The size of structure being
// protected must be a nonzero power of 2 times the Sequence Number Stride,
// and less than or equal to the physical page size of the machine.) The
// first word of the Update Sequence Array contains the Update Sequence Number,
// which is a cyclical counter (however 0 is not used) of the number of times
// the containing structure has been written to disk. Following the Update
// Sequence Number are the n saved USHORTs which were overwritten by the
// Update Sequence Number the last time the containing structure was
// written to disk.
//
// In detail, just prior to each time the protected structure is written to
// disk, the last word in each Sequence Number Stride is saved to its
// respective position in the Sequence Number Array, and then it is overwritten
// with the next Update Sequence Number. Just after this write, or whenever
// reading the structure, the saved word from the Sequence Number Array is
// restored to its actual position in the structure. Before restoring the
// saved words on reads, all of the sequence numbers at the end of each
// stride are compared with the actual sequence number at the start of the
// array. If any of these compares come up not equal, then a failed
// multi-sector transfer has been detected.
//
// The size of the array is determined by the size of the containing structure.
// As a C detail, the array is declared here with a size of 1, since its
// actual size can only be determined at runtime.
//
// The Update Sequence Array should be included at the end of the header of
// the structure it is protecting, since it is variable size. Its user must
// insure that the correct size is reserved for it, namely:
//
// (sizeof-structure / SEQUENCE_NUMBER_STRIDE + 1) * sizeof(USHORT)
//
#define SEQUENCE_NUMBER_STRIDE (512)
typedef USHORT UPDATE_SEQUENCE_NUMBER, *PUPDATE_SEQUENCE_NUMBER;
//
// This structure must be allocated at the start of the structure being
// protected.
//
#if !defined( _AUTOCHECK_ )
typedef struct _MULTI_SECTOR_HEADER {
//
// Space for a four-character signature
//
UCHAR Signature[4];
//
// Offset to Update Sequence Array, from start of structure. The Update
// Sequence Array must end before the last USHORT in the first "sector"
// of size SEQUENCE_NUMBER_STRIDE. (I.e., with the current constants,
// the sum of the next two fields must be <= 510.)
//
USHORT UpdateSequenceArrayOffset;
//
// Size of Update Sequence Array (from above formula)
//
USHORT UpdateSequenceArraySize;
} MULTI_SECTOR_HEADER, *PMULTI_SECTOR_HEADER;
#endif
//
// This array must be present at the offset described above.
//
typedef UPDATE_SEQUENCE_NUMBER UPDATE_SEQUENCE_ARRAY[1];
typedef UPDATE_SEQUENCE_ARRAY *PUPDATE_SEQUENCE_ARRAY;
//
// The following structure is allocated in the file system's Vcb and
// its address is passed to Lfs during log file initialization. It
// contains the offset of the current write as well as the system
// page size being used by Lfs.
//
typedef struct _LFS_WRITE_DATA {
LONGLONG FileOffset; ULONG Length; ULONG LfsStructureSize; PVOID Lfcb;
} LFS_WRITE_DATA, *PLFS_WRITE_DATA;
//
// The following structure is used to identify a log record by a log
// sequence number.
//
typedef LARGE_INTEGER LSN, *PLSN;
//
// The following Lsn will never occur in a file, it is used to indicate
// a non-lsn.
//
extern LSN LfsZeroLsn;
//
// We set the default page size to 4K
//
#define LFS_DEFAULT_LOG_PAGE_SIZE (0x1000)
//
// The following type defines the different log record types.
//
typedef enum _LFS_RECORD_TYPE {
LfsClientRecord = 1, LfsClientRestart
} LFS_RECORD_TYPE, *PLFS_RECORD_TYPE;
//
// The following search modes are supported.
//
typedef enum _LFS_CONTEXT_MODE {
LfsContextUndoNext = 1, LfsContextPrevious, LfsContextForward
} LFS_CONTEXT_MODE, *PLFS_CONTEXT_MODE;
typedef ULONG TRANSACTION_ID, *PTRANSACTION_ID;
typedef enum _TRANSACTION_STATE {
TransactionUninitialized = 0, TransactionActive, TransactionPrepared, TransactionCommitted
} TRANSACTION_STATE, *PTRANSACTION_STATE;
//
// Information conduit back and forth between
// LFS and its client.
//
typedef enum _LFS_CLIENT_INFO {
LfsUseUsa = 1, LfsPackLog, LfsFixedPageSize
} LFS_CLIENT_INFO;
typedef struct _LFS_INFO {
LOGICAL ReadOnly; LOGICAL InRestart; LOGICAL BadRestart; LFS_CLIENT_INFO LfsClientInfo;
} LFS_INFO, *PLFS_INFO;
typedef PVOID LFS_LOG_HANDLE, *PLFS_LOG_HANDLE;
typedef PVOID LFS_LOG_CONTEXT, *PLFS_LOG_CONTEXT;
//
// Write Entry for LfsWrite and LfsForceWrite. The interface to these
// routines takes a pointer to a Write Entry along with a count of how
// many Write Entries to expect to describe pieces of the caller's buffer
// which are supposed to be copied in sequence to the log file.
//
typedef struct _LFS_WRITE_ENTRY {
PVOID Buffer; ULONG ByteLength;
} LFS_WRITE_ENTRY, *PLFS_WRITE_ENTRY;
//
// Global Maintenance routines
//
BOOLEAN LfsInitializeLogFileService ( VOID );
//
// Log File Registration routines
//
typedef struct _LOG_FILE_INFORMATION {
//
// This is the total useable space in the log file after space for
// headers and Lfs Restart Areas.
//
LONGLONG TotalAvailable;
//
// This is the useable space in the log file from the current position
// in the log file to the lowest BaseLsn. This total as returned is not
// yet reduced for undo commitments, returned separately below.
//
LONGLONG CurrentAvailable;
//
// This is the total undo commitment for all clients of the log file.
// LfsWrite requests are refused when the sum of the write size of the
// request plus the UndoRequirement for the request plus the TotalUndoCommitment
// are greater than the CurrentAvailable.
//
LONGLONG TotalUndoCommitment;
//
// This is the total undo commitment for this client.
//
LONGLONG ClientUndoCommitment;
//
// Current system Lsn's. Includes the Oldest, LastFlushed and current
// Lsn.
//
LSN OldestLsn; LSN LastFlushedLsn; LSN LastLsn;
} LOG_FILE_INFORMATION, *PLOG_FILE_INFORMATION;
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 );
//
// Log File Client Restart routines
//
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, IN LOGICAL CleanShutdown, OUT PLSN Lsn );
VOID LfsSetBaseLsn ( IN LFS_LOG_HANDLE LogHandle, IN LSN BaseLsn );
//
// If ResetTotal is positive, then NumberRecords and ResetTotal set the absolute
// values for the client. If ResetTotal is negative, then they are adjustments
// to the totals for this client.
//
VOID LfsResetUndoTotal ( IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberRecords, IN LONG ResetTotal );
//
// Log File Write routines
//
VOID LfsGetActiveLsnRange ( IN LFS_LOG_HANDLE LogHandle, OUT PLSN OldestLsn, OUT PLSN NextLsn );
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, IN ULONG Flags, OUT PLSN Lsn );
#define LFS_WRITE_FLAG_WRITE_AT_FRONT 1
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 );
//
// Log File Query Record routines
//
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 );
#endif // LFS
|