Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

709 lines
18 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. LfsStruc.h
  5. Abstract:
  6. This module defines the data structures that make up the major internal
  7. part of the Log File Service.
  8. Author:
  9. Brian Andrew [BrianAn] 13-June-1991
  10. Revision History:
  11. --*/
  12. #ifndef _LFSSTRUC_
  13. #define _LFSSTRUC_
  14. typedef PVOID PBCB; //**** Bcb's are now part of the cache module
  15. //
  16. // Log Enumeration Block. A pointer to this structure is returned to the user
  17. // when a client is reading a particular set of log records from the log
  18. // file.
  19. //
  20. typedef struct _LEB {
  21. //
  22. // The type and size of this record (must be LFS_NTC_LEB)
  23. //
  24. NODE_TYPE_CODE NodeTypeCode;
  25. NODE_BYTE_SIZE NodeByteSize;
  26. //
  27. // Log record header. This is the mapped log record header and bcb
  28. // for the record header of the current Lsn.
  29. //
  30. struct _LFS_RECORD_HEADER *RecordHeader;
  31. PBCB RecordHeaderBcb;
  32. //
  33. // Context Mode. This is the mode governing the log record lookup. We
  34. // can look backwards via the ClientUndoNextLsn or ClientPreviousLsn.
  35. // We can also look forwards by walking through all the log records and
  36. // comparing ClientId fields.
  37. //
  38. LFS_CONTEXT_MODE ContextMode;
  39. //
  40. // Client Id. This is the client ID for the log records being returned.
  41. //
  42. LFS_CLIENT_ID ClientId;
  43. //
  44. // Log record pointer. This is the address returned to the user as the
  45. // log record referred to by CurrentLsn. If we allocated a buffer to
  46. // hold the record, we need to deallocate it as necessary.
  47. //
  48. // This field is either the actual mapped log record or a pointer to
  49. // an auxilary buffer allocated by the Lfs.
  50. //
  51. PVOID CurrentLogRecord;
  52. BOOLEAN AuxilaryBuffer;
  53. } LEB, *PLEB;
  54. //
  55. // Lfcb synchronization. This is the synchronization structure used by the Lfcb.
  56. //
  57. typedef enum _LFS_IO_STATE {
  58. LfsNoIoInProgress = 0,
  59. LfsClientThreadIo
  60. } LFS_IO_STATE;
  61. typedef struct _LFCB_SYNC {
  62. //
  63. // Principal Lfcb Resource.
  64. //
  65. ERESOURCE Resource;
  66. //
  67. // User Count. Number of clients using this structure. We will deallocate
  68. // when all clients are gone.
  69. //
  70. ULONG UserCount;
  71. //
  72. // Mutant to guard Lcb spare list and last flushed lsn
  73. //
  74. FAST_MUTEX Mutex;
  75. //
  76. // The enumerated type indicates if there is an active write for
  77. // this log file and whether it is being done by an Lfs or
  78. // client thread.
  79. //
  80. LFS_IO_STATE LfsIoState;
  81. } LFCB_SYNC, *PLFCB_SYNC;
  82. typedef struct _LFS_WAITER {
  83. //
  84. // Link onto the lfcb waiter list
  85. //
  86. LIST_ENTRY Waiters;
  87. //
  88. // Event to signal when the lsn has been flushed to that point or no one
  89. // is left flushing
  90. //
  91. KEVENT Event;
  92. LSN Lsn;
  93. } LFS_WAITER, *PLFS_WAITER;
  94. //
  95. // Log Client Structure. The Lfs allocates one of these for each active
  96. // client. The address of this structure will be returned to the user
  97. // as a log handle.
  98. //
  99. typedef struct _LCH {
  100. //
  101. // The type and size of this record (must be LFS_NTC_LCH)
  102. //
  103. NODE_TYPE_CODE NodeTypeCode;
  104. NODE_BYTE_SIZE NodeByteSize;
  105. //
  106. // Links for all the client handles on an Lfcb.
  107. //
  108. LIST_ENTRY LchLinks;
  109. //
  110. // Log File Control Block. This is the log file for this log handle.
  111. //
  112. struct _LFCB *Lfcb;
  113. //
  114. // Client Id. This refers to the client record for this client in the
  115. // Lfs restart area.
  116. //
  117. LFS_CLIENT_ID ClientId;
  118. //
  119. // The following is the number of bytes this client has asked to
  120. // have reserved in the log file. It includes the space
  121. // for the log record headers.
  122. //
  123. LONGLONG ClientUndoCommitment;
  124. //
  125. // Byte offset in the client array.
  126. //
  127. ULONG ClientArrayByteOffset;
  128. //
  129. // Pointer to the resource in the Lfcb. We access the resource with
  130. // this pointer for the times when the lfcb has been deleted.
  131. //
  132. PLFCB_SYNC Sync;
  133. } LCH, *PLCH;
  134. //
  135. // Log Buffer Control Block. A buffer control block is associated with
  136. // each of the log buffers. They are used to serialize access to the
  137. // log file.
  138. //
  139. typedef struct _LBCB {
  140. //
  141. // The type and size of this record (must be LFS_NTC_LBCB)
  142. //
  143. NODE_TYPE_CODE NodeTypeCode;
  144. NODE_BYTE_SIZE NodeByteSize;
  145. //
  146. // Buffer Block Links. These fields are used to link the buffer blocks
  147. // together.
  148. //
  149. LIST_ENTRY WorkqueLinks;
  150. LIST_ENTRY ActiveLinks;
  151. //
  152. // Log file position and length. This is the location in the log file to write
  153. // out this buffer.
  154. //
  155. LONGLONG FileOffset;
  156. LONGLONG Length;
  157. //
  158. // Sequence number. This is the sequence number for log records which
  159. // begin on this page.
  160. //
  161. LONGLONG SeqNumber;
  162. //
  163. // Next Offset. This is the next offset to write a log record in the
  164. // this log page. Stored as a large integer to facilitate large
  165. // integer operations.
  166. //
  167. LONGLONG BufferOffset;
  168. //
  169. // Buffer. This field points to the buffer containing the log page
  170. // for this block. For a log record page this is a pointer to
  171. // a pinned cache buffer, for a log restart page, this is a pointer
  172. // to an auxilary buffer.
  173. //
  174. PVOID PageHeader;
  175. //
  176. // Bcb for Log Page Block. This is the Bcb for the pinned data.
  177. // If this buffer block describes an Lfs restart area, this field is NULL.
  178. //
  179. PBCB LogPageBcb;
  180. //
  181. // Last Lsn. This is the Lsn for the last log record on this page. We delay
  182. // writing it until the page is flushed, storing it here instead.
  183. //
  184. LSN LastLsn;
  185. //
  186. // Last complete Lsn. This is the Lsn for the last log record which ends
  187. // on this page.
  188. //
  189. LSN LastEndLsn;
  190. //
  191. // Page Flags. These are the flags associated with this log page.
  192. // We store them in the Lbcb until the page is written. They flags
  193. // to use are the same as in the log record page header.
  194. //
  195. // LOG_PAGE_LOG_RECORD_END - Page contains the end of a log record
  196. // LOG_PAGE_PACKED - Page contains packed log records
  197. // LOG_PAGE_TAIL_COPY - Page is a copy of the log file end
  198. //
  199. ULONG Flags;
  200. //
  201. // Lbcb flags. These are flags used to describe this Lbcb.
  202. //
  203. // LBCB_LOG_WRAPPED - Lbcb has wrapped the log file
  204. // LBCB_ON_ACTIVE_QUEUE - Lbcb is on the active queue
  205. // LBCB_NOT_EMPTY - Page has existing log record
  206. // LBCB_FLUSH_COPY - Write copy of this page first
  207. // LBCB_RESTART_LBCB - This Lbcb contains a restart page
  208. //
  209. ULONG LbcbFlags;
  210. //
  211. // This is the thread which has locked the log page.
  212. //
  213. ERESOURCE_THREAD ResourceThread;
  214. } LBCB, *PLBCB;
  215. #define LBCB_LOG_WRAPPED (0x00000001)
  216. #define LBCB_ON_ACTIVE_QUEUE (0x00000002)
  217. #define LBCB_NOT_EMPTY (0x00000004)
  218. #define LBCB_FLUSH_COPY (0x00000008)
  219. #define LBCB_RESTART_LBCB (0x00000020)
  220. //
  221. // Log file data. This data structure is used on a per-log file basis.
  222. //
  223. typedef struct _LFCB {
  224. //
  225. // The type and size of this record (must be LFS_NTC_LFCB)
  226. //
  227. NODE_TYPE_CODE NodeTypeCode;
  228. NODE_BYTE_SIZE NodeByteSize;
  229. //
  230. // Lfcb Links. The following links the file control blocks to the
  231. // global data structure.
  232. //
  233. LIST_ENTRY LfcbLinks;
  234. //
  235. // Lch Links. The following links all of the handles for the Lfcb.
  236. //
  237. LIST_ENTRY LchLinks;
  238. //
  239. //
  240. // File Object. This is the file object for the log file.
  241. //
  242. PFILE_OBJECT FileObject;
  243. //
  244. // Log File Size. This is the size of the log file.
  245. // The second value is the size proposed by this open.
  246. //
  247. LONGLONG FileSize;
  248. //
  249. // Log page size, masks and shift count to do multiplication and division
  250. // of log pages.
  251. //
  252. LONGLONG LogPageSize;
  253. ULONG LogPageMask;
  254. LONG LogPageInverseMask;
  255. ULONG LogPageShift;
  256. //
  257. // First log page. This is the offset in the file of the first
  258. // log page with log records.
  259. //
  260. LONGLONG FirstLogPage;
  261. //
  262. // Next log page offset. This is the offset of the next log page to use.
  263. // If we are reusing this page we store the offset to begin with.
  264. //
  265. LONGLONG NextLogPage;
  266. ULONG ReusePageOffset;
  267. //
  268. // Data Offset. This is the offset within a log page of the data that
  269. // appears on that page. This will be the actual restart data for
  270. // an Lfs restart page, or the beginning of log record data for a log
  271. // record page.
  272. //
  273. ULONG RestartDataOffset;
  274. LONGLONG LogPageDataOffset;
  275. //
  276. // Data Size. This is the amount of data that may be stored on a
  277. // log page. It is included here because it is frequently used. It
  278. // is simply the log page size minus the data offset.
  279. //
  280. ULONG RestartDataSize;
  281. LONGLONG LogPageDataSize;
  282. //
  283. // Record header size. This is the size to use for the record headers
  284. // when reading the log file.
  285. //
  286. USHORT RecordHeaderLength;
  287. //
  288. // Sequence number. This is the number of times we have cycled through
  289. // the log file. The wrap sequence number is used to confirm that we
  290. // have gone through the entire file at least once. When we write a
  291. // log record page for an Lsn with this sequence number, then we have
  292. // cycled through the file.
  293. //
  294. LONGLONG SeqNumber;
  295. LONGLONG SeqNumberForWrap;
  296. ULONG SeqNumberBits;
  297. ULONG FileDataBits;
  298. //
  299. // Buffer Block Links. The following links the buffer blocks for this
  300. // log file.
  301. //
  302. LIST_ENTRY LbcbWorkque;
  303. LIST_ENTRY LbcbActive;
  304. PLBCB ActiveTail;
  305. PLBCB PrevTail;
  306. //
  307. // Current Restart Area. The following is the in-memory image of the
  308. // next restart area. We also store a pointer to the client data
  309. // array in the restart area. The client array offset is from the start of
  310. // the restart area.
  311. //
  312. PLFS_RESTART_AREA RestartArea;
  313. PLFS_CLIENT_RECORD ClientArray;
  314. USHORT ClientArrayOffset;
  315. USHORT ClientNameOffset;
  316. //
  317. // Restart Area size. This is the usable size of the restart area.
  318. //
  319. ULONG RestartAreaSize;
  320. USHORT LogClients;
  321. //
  322. // Initial Restart area. If true, then the in-memory restart area is to
  323. // be written to the first position on the disk.
  324. //
  325. BOOLEAN InitialRestartArea;
  326. //
  327. // The following is the earliest Lsn we will guarantee is still in the
  328. // log file.
  329. //
  330. LSN OldestLsn;
  331. //
  332. // The following is the file offset of the oldest Lsn in the system.
  333. // We redundantly store it in this form since we will be constantly
  334. // checking if a new log record will write over part of the file
  335. // we are trying to maintain.
  336. //
  337. LONGLONG OldestLsnOffset;
  338. //
  339. // Last Flushed Lsn. The following is the last Lsn guaranteed to
  340. // be flushed to the disk. The last restart lsn is the last pseudo restart lsn flushed
  341. //
  342. LSN LastFlushedLsn;
  343. LSN LastFlushedRestartLsn;
  344. //
  345. //
  346. // The following fields are used to track current usage in the log file.
  347. //
  348. // TotalAvailable - is the total number of bytes available for
  349. // log records. It is the number of log pages times the
  350. // data size of each page.
  351. //
  352. // TotalAvailInPages - is the total number of bytes in the log
  353. // pages for log records. This is TotalAvailable without
  354. // subtracting the size of the page headers.
  355. //
  356. // TotalUndoCommitment - is the number of bytes reserved for
  357. // possible abort operations. This includes space for
  358. // log record headers as well.
  359. //
  360. // MaxCurrentAvail - is the maximum available in all pages
  361. // subtracting the page header and any reserved tail.
  362. //
  363. // CurrentAvailable - is the total number of bytes available in
  364. // unused pages in the log file.
  365. //
  366. // ReservedLogPageSize - is the number of bytes on a page available
  367. // for reservation.
  368. //
  369. LONGLONG TotalAvailable;
  370. LONGLONG TotalAvailInPages;
  371. LONGLONG TotalUndoCommitment;
  372. LONGLONG MaxCurrentAvail;
  373. LONGLONG CurrentAvailable;
  374. LONGLONG ReservedLogPageSize;
  375. //
  376. // The following fields are used to store information about the
  377. // update sequence arrays.
  378. //
  379. USHORT RestartUsaOffset;
  380. USHORT UsaArraySize;
  381. USHORT LogRecordUsaOffset;
  382. //
  383. // Major and minor version numbers.
  384. //
  385. SHORT MajorVersion;
  386. SHORT MinorVersion;
  387. //
  388. // Log File Flags.
  389. //
  390. // LFCB_LOG_WRAPPED - We found an Lbcb which wraps the log file
  391. // LFCB_MULTIPLE_PAGE_IO - Write multiple pages if possible
  392. // LFCB_NO_LAST_LSN - There are no log records to return
  393. // LFCB_PACK_LOG - Pack the records into the pages
  394. // LFCB_REUSE_TAIL - We will be reusing the tail of the log file after restart
  395. // LFCB_NO_OLDEST_LSN - There is no oldest page being reserved
  396. //
  397. ULONG Flags;
  398. //
  399. // The following are the spare Lbcb's for the volume and a field with
  400. // the count for these.
  401. //
  402. ULONG SpareLbcbCount;
  403. LIST_ENTRY SpareLbcbList;
  404. //
  405. // The following are sparse LEB's to be used rather than having to allocate
  406. // then when reading log records
  407. //
  408. ULONG SpareLebCount;
  409. LIST_ENTRY SpareLebList;
  410. //
  411. // The following structure synchronizes access to this structure.
  412. //
  413. PLFCB_SYNC Sync;
  414. //
  415. // Count of waiters wanting access to flush the Lfcb. List synchronized
  416. // by the sync mutex of the waiters see LFS_WAITER
  417. //
  418. ULONG Waiters;
  419. LIST_ENTRY WaiterList;
  420. //
  421. // On-disk value for OpenLogCount. This is the value we will stuff into
  422. // the client handles.
  423. //
  424. ULONG CurrentOpenLogCount;
  425. //
  426. // Maintain the flush range for this file.
  427. //
  428. PLFS_WRITE_DATA UserWriteData;
  429. ERESOURCE_THREAD LfsIoThread;
  430. //
  431. // Buffer and mdls which hold down the first 4 pages at the head of the log
  432. // this includes the lfs restart areas and the ping pong pages. The partial mdl
  433. // is used to pin pieces of the total buffer
  434. //
  435. PMDL LogHeadMdl;
  436. PMDL LogHeadPartialMdl;
  437. PVOID LogHeadBuffer;
  438. //
  439. // preallocated error log packet for use logging errors to the eventlog
  440. //
  441. PIO_ERROR_LOG_PACKET ErrorLogPacket;
  442. #ifdef LFS_CLUSTER_CHECK
  443. LSN LsnAtMount;
  444. ULONG LsnRangeIndex;
  445. #endif
  446. ULONG LfsRestartBias;
  447. //
  448. // Embedded array with enough space for SYSTEM PAGE / LOG PAGE SIZE
  449. // used to facilitate flushing partial system pages
  450. //
  451. PLBCB DirtyLbcb[0];
  452. } LFCB, *PLFCB;
  453. #define LFCB_LOG_WRAPPED (0x00000001)
  454. #define LFCB_MULTIPLE_PAGE_IO (0x00000002)
  455. #define LFCB_NO_LAST_LSN (0x00000004)
  456. #define LFCB_PACK_LOG (0x00000008)
  457. #define LFCB_REUSE_TAIL (0x00000010)
  458. #define LFCB_NO_OLDEST_LSN (0x00000020)
  459. #define LFCB_LOG_FILE_CORRUPT (0x00000040)
  460. #define LFCB_FINAL_SHUTDOWN (0x00000080)
  461. #define LFCB_READ_FIRST_RESTART (0x00000100)
  462. #define LFCB_READ_SECOND_RESTART (0x00000200)
  463. #define LFCB_READ_ONLY (0x00000400)
  464. #ifdef LFS_CLUSTER_CHECK
  465. #define LFCB_DEVICE_OFFLINE_SEEN (0x80000000)
  466. #define LFCB_FLUSH_FAILED (0x40000000)
  467. #endif
  468. #define LFCB_RESERVE_LBCB_COUNT (5)
  469. #define LFCB_MAX_LBCB_COUNT (25)
  470. #define LFCB_RESERVE_LEB_COUNT (5)
  471. #define LFCB_MAX_LEB_COUNT (25)
  472. //
  473. // Global Log Data. The following structure has only one instance and
  474. // maintains global information for the entire logging service.
  475. //
  476. typedef struct _LFS_DATA {
  477. //
  478. // The type and size of this record (must be LFS_NTC_DATA)
  479. //
  480. NODE_TYPE_CODE NodeTypeCode;
  481. NODE_BYTE_SIZE NodeByteSize;
  482. //
  483. // The following field links all of the Log File Control Blocks for
  484. // the logging system.
  485. //
  486. LIST_ENTRY LfcbLinks;
  487. //
  488. // Flag field.
  489. //
  490. ULONG Flags;
  491. //
  492. // The following mutex controls access to this structure.
  493. //
  494. FAST_MUTEX LfsDataLock;
  495. //
  496. // Allocated buffers for reading spanning log records in low memory case.
  497. // Flags indicate which buffers owned.
  498. // LFS_BUFFER1_OWNED
  499. // LFS_BUFFER2_OWNED
  500. //
  501. PVOID Buffer1;
  502. PVOID Buffer2;
  503. ERESOURCE_THREAD BufferOwner;
  504. ULONG BufferFlags;
  505. FAST_MUTEX BufferLock;
  506. KEVENT BufferNotification;
  507. } LFS_DATA, *PLFS_DATA;
  508. #define LFS_DATA_INIT_FAILED (0x00000001)
  509. #define LFS_DATA_INITIALIZED (0x00000002)
  510. #define LFS_BUFFER1_OWNED (0x00000001)
  511. #define LFS_BUFFER2_OWNED (0x00000002)
  512. #define LFS_BUFFER_SIZE (0x10000)
  513. #define LFS_MAX_FLUSH_COUNT VACB_MAPPING_GRANULARITY / LFS_DEFAULT_LOG_PAGE_SIZE
  514. #endif // _LFSSTRUC_