diff options
Diffstat (limited to 'private/ntos/lfs/lfsdisk.h')
-rw-r--r-- | private/ntos/lfs/lfsdisk.h | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/private/ntos/lfs/lfsdisk.h b/private/ntos/lfs/lfsdisk.h new file mode 100644 index 000000000..198486340 --- /dev/null +++ b/private/ntos/lfs/lfsdisk.h @@ -0,0 +1,506 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + LfsDisk.h + +Abstract: + + This module defines the on-disk structures present in the log file. + +Author: + + Brian Andrew [BrianAn] 13-June-1991 + +Revision History: + +IMPORTANT NOTE: + + The Log File Service will by used on systems that require that on-disk + structures guarantee the natural alignment of all arithmetic quantities + up to and including quad-word (64-bit) numbers. Therefore, all Lfs + on-disk structures are quad-word aligned, etc. + +--*/ + +#ifndef _LFSDISK_ +#define _LFSDISK_ + +#define MINIMUM_LFS_PAGES 0x00000030 +#define MINIMUM_LFS_CLIENTS 1 + +// +// The following macros are used to set and query with respect to the +// update sequence arrays. +// + +#define UpdateSequenceStructureSize( MSH ) \ + ((((PMULTI_SECTOR_HEADER) (MSH))->UpdateSequenceArraySize - 1) * SEQUENCE_NUMBER_STRIDE) + +#define UpdateSequenceArraySize( STRUCT_SIZE ) \ + ((STRUCT_SIZE) / SEQUENCE_NUMBER_STRIDE + 1) + +#define FIRST_STRIDE \ + (SEQUENCE_NUMBER_STRIDE - sizeof( UPDATE_SEQUENCE_NUMBER )) + + +// +// Log client ID. This is used to uniquely identify a client for a +// particular log file. +// + +typedef struct _LFS_CLIENT_ID { + + USHORT SeqNumber; + USHORT ClientIndex; + +} LFS_CLIENT_ID, *PLFS_CLIENT_ID; + + +// +// Log Record Header. This is the header that begins every Log Record in +// the log file. +// + +typedef struct _LFS_RECORD_HEADER { + + // + // Log File Sequence Number of this log record. + // + + LSN ThisLsn; + + // + // The following fields are used to back link Lsn's. The ClientPrevious + // and ClientUndoNextLsn fields are used by a client to link his log + // records. + // + + LSN ClientPreviousLsn; + LSN ClientUndoNextLsn; + + // + // The following field is the size of data area for this record. The + // log record header will be padded if necessary to fill to a 64-bit + // boundary, so the client data will begin on a 64-bit boundary to + // insure that all of his data is 64-bit aligned. The below value + // has not been padded to 64 bits however. + // + + ULONG ClientDataLength; + + // + // Client ID. This identifies the owner of this log record. The owner + // is uniquely identified by his offset in the client array and the + // sequence number associated with that client record. + // + + LFS_CLIENT_ID ClientId; + + // + // This the Log Record type. This could be a commit protocol record, + // a client restart area or a client update record. + // + + LFS_RECORD_TYPE RecordType; + + // + // Transaction ID. This is used externally by a client (Transaction + // Manager) to group log file entries. + // + + TRANSACTION_ID TransactionId; + + // + // Log record flags. + // + + USHORT Flags; + + // + // Alignment field. + // + + USHORT AlignWord; + +} LFS_RECORD_HEADER, *PLFS_RECORD_HEADER; + +#define LOG_RECORD_MULTI_PAGE (0x0001) + +#define LFS_RECORD_HEADER_SIZE QuadAlign( sizeof( LFS_RECORD_HEADER )) + + +// +// Following are the version specific fields in the record page header. +// + +typedef struct _LFS_UNPACKED_RECORD_PAGE { + + // + // This gives us the offset of the free space in the page. + // + + USHORT NextRecordOffset; + + USHORT WordAlign; + + // + // Reserved. The following array is reserved for possible future use. + // + + USHORT Reserved; + + // + // Update Sequence Array. Used to protect the page block. + // + + UPDATE_SEQUENCE_ARRAY UpdateSequenceArray; + +} LFS_UNPACKED_RECORD_PAGE, *PLFS_UNPACKED_RECORD_PAGE; + +typedef struct _LFS_PACKED_RECORD_PAGE { + + // + // This gives us the offset of the free space in the page. + // + + USHORT NextRecordOffset; + + USHORT WordAlign; + + ULONG DWordAlign; + + // + // The following is the Lsn for the last log record which ends on the page. + // + + LSN LastEndLsn; + + // + // Update Sequence Array. Used to protect the page block. + // + + UPDATE_SEQUENCE_ARRAY UpdateSequenceArray; + +} LFS_PACKED_RECORD_PAGE, *PLFS_PACKED_RECORD_PAGE; + + +// +// Log Record Page Header. This structure is present at the beginning of each +// log file page in the client record section. +// + +typedef struct _LFS_RECORD_PAGE_HEADER { + + // + // Cache multisector protection header. + // + + MULTI_SECTOR_HEADER MultiSectorHeader; + + union { + + // + // Highest Lsn in this log file page. This field is only for + // regular log pages. + // + + LSN LastLsn; + + // + // Log file offset. This is for the tail copies and indicates the + // location in the file where the original lays. In this case the + // LastLsn field above can be obtained from the last ending Lsn + // field in the PACKED_RECORD_PAGE structure. + // + + LONGLONG FileOffset; + + } Copy; + + // + // Page Header Flags. These are the same flags that are stored in the + // Lbcb->Flags field. + // + // LOG_PAGE_LOG_RECORD_END - Page contains the end of a log record + // + + ULONG Flags; + + // + // I/O Page Position. The following fields are used to determine + // where this log page resides within a Lfs I/O transfer. + // + + USHORT PageCount; + USHORT PagePosition; + + // + // The following is the difference between version 1.1 and earlier. + // + + union { + + LFS_UNPACKED_RECORD_PAGE Unpacked; + LFS_PACKED_RECORD_PAGE Packed; + + } Header; + +} LFS_RECORD_PAGE_HEADER, *PLFS_RECORD_PAGE_HEADER; + +#define LOG_PAGE_LOG_RECORD_END (0x00000001) + +#define LFS_UNPACKED_RECORD_PAGE_HEADER_SIZE ( \ + FIELD_OFFSET( LFS_RECORD_PAGE_HEADER, Header.Unpacked.UpdateSequenceArray ) \ +) + +#define LFS_PACKED_RECORD_PAGE_HEADER_SIZE ( \ + FIELD_OFFSET( LFS_RECORD_PAGE_HEADER, Header.Packed.UpdateSequenceArray ) \ +) + + +// +// Log Restart Page Header. This structure is at the head of the restart +// areas in a log file. +// + +typedef struct _LFS_RESTART_PAGE_HEADER { + + // + // Cache multisector protection header. + // + + MULTI_SECTOR_HEADER MultiSectorHeader; + + // + // This is the last Lsn found by checkdisk for this volume. + // + + LSN ChkDskLsn; + + // + // System page size. This is the page size of the system which + // initialized the log file. Unless the log file has been gracefully + // shutdown (there are no clients with restart areas), it is a fatal + // error to attempt to write to a log file on a system with a differen + // page size. + // + + ULONG SystemPageSize; + + // + // Log Page Size. This is the log page size used for this log file. + // The entire Lfs restart area must fit on a single log page. + // + + ULONG LogPageSize; + + // + // Lfs restart area offset. This is the offset from the start of this + // structure to the Lfs restart area. + // + + USHORT RestartOffset; + + // + // The indicates major and minor versions. Note that the pre-release versions + // have -1 in both positions. Major version 0 indicates the transition + // from Beta to USA support. + // + // Major Version + // + // -1 Beta Version + // 0 Transition + // 1 Update sequence support. + // + + SHORT MinorVersion; + SHORT MajorVersion; + + // + // Update Sequence Array. Used to protect the page block. + // + + UPDATE_SEQUENCE_ARRAY UpdateSequenceArray; + +} LFS_RESTART_PAGE_HEADER, *PLFS_RESTART_PAGE_HEADER; + +#define LFS_RESTART_PAGE_HEADER_SIZE ( \ + FIELD_OFFSET( LFS_RESTART_PAGE_HEADER, UpdateSequenceArray ) \ +) + +// +// Id strings for the page headers. +// + +#define LFS_SIGNATURE_RESTART_PAGE "RSTR" +#define LFS_SIGNATURE_RESTART_PAGE_ULONG 0x52545352 +#define LFS_SIGNATURE_RECORD_PAGE "RCRD" +#define LFS_SIGNATURE_RECORD_PAGE_ULONG 0x44524352 +#define LFS_SIGNATURE_BAD_USA "BAAD" +#define LFS_SIGNATURE_BAD_USA_ULONG 0x44414142 +#define LFS_SIGNATURE_MODIFIED "CHKD" +#define LFS_SIGNATURE_MODIFIED_ULONG 0x444b4843 +#define LFS_SIGNATURE_UNINITIALIZED "\377\377\377\377" +#define LFS_SIGNATURE_UNINITIALIZED_ULONG 0xffffffff + + +// +// Log Client Record. A log client record exists for each client user of +// the log file. One of these is in each Lfs restart area. +// + +#define LFS_NO_CLIENT 0xffff +#define LFS_CLIENT_NAME_MAX 64 + +typedef struct _LFS_CLIENT_RECORD { + + // + // Oldest Lsn. This is the oldest Lsn that this client requires to + // be in the log file. + // + + LSN OldestLsn; + + // + // Client Restart Lsn. This is the Lsn of the latest client restart + // area written to the disk. A reserved Lsn will indicate that no + // restart area exists for this client. + // + + LSN ClientRestartLsn; + + // + // + // Previous/Next client area. These are the indexes into an array of + // Log Client Records for the previous and next client records. + // + + USHORT PrevClient; + USHORT NextClient; + + // + // Sequence Number. Incremented whenever this record is reused. This + // will happen whenever a client opens (reopens) the log file and has + // no current restart area. + + USHORT SeqNumber; + + // + // Alignment field. + // + + USHORT AlignWord; + + // + // Align the entire record. + // + + ULONG AlignDWord; + + // + // The following fields are used to describe the client name. A client + // name consists of at most 32 Unicode character (64 bytes). The Log + // file service will treat client names as case sensitive. + // + + ULONG ClientNameLength; + + WCHAR ClientName[LFS_CLIENT_NAME_MAX]; + +} LFS_CLIENT_RECORD, *PLFS_CLIENT_RECORD; + + +// +// Lfs Restart Area. Two copies of these will exist at the beginning of the +// log file. +// + +typedef struct _LFS_RESTART_AREA { + + // + // Current Lsn. This is periodic snapshot of the current logical end of + // log file to facilitate restart. + // + + LSN CurrentLsn; + + // + // Number of Clients. This is the maximum number of clients supported + // for this log file. + // + + USHORT LogClients; + + // + // The following are indexes into the client record arrays. The client + // records are linked into two lists. A free list of client records and + // an in-use list of records. + // + + USHORT ClientFreeList; + USHORT ClientInUseList; + + // + // Flag field. + // + // RESTART_SINGLE_PAGE_IO All log pages written 1 by 1 + // + + USHORT Flags; + + // + // The following is the number of bits to use for the sequence number. + // + + ULONG SeqNumberBits; + + // + // Length of this restart area. + // + + USHORT RestartAreaLength; + + // + // Offset from the start of this structure to the client array. + // Ignored in versions prior to 1.1 + // + + USHORT ClientArrayOffset; + + // + // Usable log file size. We will stop sharing the value in the page header. + // + + LONGLONG FileSize; + + // + // DataLength of last Lsn. This doesn't include the length of + // the Lfs header. + // + + ULONG LastLsnDataLength; + + // + // The following apply to log pages. This is the log page data offset and + // the length of the log record header. Ignored in versions prior to 1.1 + // + + USHORT RecordHeaderLength; + USHORT LogPageDataOffset; + + // + // Client data. + // + + LFS_CLIENT_RECORD LogClientArray[1]; + +} LFS_RESTART_AREA, *PLFS_RESTART_AREA; + +#define RESTART_SINGLE_PAGE_IO (0x0001) + +#define LFS_RESTART_AREA_SIZE (FIELD_OFFSET( LFS_RESTART_AREA, LogClientArray )) + +#endif // _LFSDISK_ |