summaryrefslogblamecommitdiffstats
path: root/private/ntos/lfs/lfsdisk.h
blob: 198486340a3ad0fac52bea92163104a9075cfd64 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
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_