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.

955 lines
27 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. NtfsLog.h
  5. Abstract:
  6. This module defines the Ntfs-specific log file structures.
  7. Author:
  8. Tom Miller [TomM] 21-Jul-1991
  9. Revision History:
  10. --*/
  11. #ifndef _NTFSLOG_
  12. #define _NTFSLOG_
  13. //
  14. // The following type defines the Ntfs log operations.
  15. //
  16. // The comment specifies the record type which follows the record.
  17. // These record types are defined either here or in ntfs.h.
  18. //
  19. typedef enum _NTFS_LOG_OPERATION {
  20. Noop = 0x00, //
  21. CompensationLogRecord = 0x01, //
  22. InitializeFileRecordSegment = 0x02, // FILE_RECORD_SEGMENT_HEADER
  23. DeallocateFileRecordSegment = 0x03, //
  24. WriteEndOfFileRecordSegment = 0x04, // ATTRIBUTE_RECORD_HEADER
  25. CreateAttribute = 0x05, // ATTRIBUTE_RECORD_HEADER
  26. DeleteAttribute = 0x06, //
  27. UpdateResidentValue = 0x07, // (value)
  28. UpdateNonresidentValue = 0x08, // (value)
  29. UpdateMappingPairs = 0x09, // (value = mapping pairs bytes)
  30. DeleteDirtyClusters = 0x0A, // array of LCN_RANGE
  31. SetNewAttributeSizes = 0x0B, // NEW_ATTRIBUTE_SIZES
  32. AddIndexEntryRoot = 0x0C, // INDEX_ENTRY
  33. DeleteIndexEntryRoot = 0x0D, // INDEX_ENTRY
  34. AddIndexEntryAllocation = 0x0E, // INDEX_ENTRY
  35. DeleteIndexEntryAllocation = 0x0F, // INDEX_ENTRY
  36. WriteEndOfIndexBuffer = 0x10, // INDEX_ENTRY
  37. SetIndexEntryVcnRoot = 0x11, // VCN
  38. SetIndexEntryVcnAllocation = 0x12, // VCN
  39. UpdateFileNameRoot = 0x13, // DUPLICATED_INFORMATION
  40. UpdateFileNameAllocation = 0x14, // DUPLICATED_INFORMATION
  41. SetBitsInNonresidentBitMap = 0x15, // BITMAP_RANGE
  42. ClearBitsInNonresidentBitMap = 0x16, // BITMAP_RANGE
  43. HotFix = 0x17, //
  44. EndTopLevelAction = 0x18, //
  45. PrepareTransaction = 0x19, //
  46. CommitTransaction = 0x1A, //
  47. ForgetTransaction = 0x1B, //
  48. OpenNonresidentAttribute = 0x1C, // OPEN_ATTRIBUTE_ENTRY+ATTRIBUTE_NAME_ENTRY
  49. OpenAttributeTableDump = 0x1D, // OPEN_ATTRIBUTE_ENTRY array
  50. AttributeNamesDump = 0x1E, // (all attribute names)
  51. DirtyPageTableDump = 0x1F, // DIRTY_PAGE_ENTRY array
  52. TransactionTableDump = 0x20, // TRANSACTION_ENTRY array
  53. UpdateRecordDataRoot = 0x21, // (value)
  54. UpdateRecordDataAllocation = 0x22 // (value)
  55. } NTFS_LOG_OPERATION, *PNTFS_LOG_OPERATION;
  56. //
  57. // The Ntfs log record header precedes every log record written to
  58. // disk by Ntfs.
  59. //
  60. //
  61. // Log record header.
  62. //
  63. typedef struct _NTFS_LOG_RECORD_HEADER {
  64. //
  65. // Log Operations (LOG_xxx codes)
  66. //
  67. USHORT RedoOperation;
  68. USHORT UndoOperation;
  69. //
  70. // Offset to Redo record, and its length
  71. //
  72. USHORT RedoOffset;
  73. USHORT RedoLength;
  74. //
  75. // Offset to Undo record, and its length. Note, for some Redo/Undo
  76. // combinations, the expected records may be the same, and thus
  77. // these two values will be identical to the above values.
  78. //
  79. USHORT UndoOffset;
  80. USHORT UndoLength;
  81. //
  82. // Open attribute table index to which this update applies. Index 0 is
  83. // always reserved for the MFT itself. The value of this field
  84. // essentially distinguishes two cases for this update, which will be
  85. // referred to as MFT update and nonresident attribute update.
  86. //
  87. // MFT updates are for initialization and deletion of file record
  88. // segments and updates to resident attributes.
  89. //
  90. // Nonresident attribute updates are used to update attributes which
  91. // have been allocated externally to the MFT.
  92. //
  93. USHORT TargetAttribute;
  94. //
  95. // Number of Lcns in use at end of header.
  96. //
  97. USHORT LcnsToFollow;
  98. //
  99. // Byte offset and Vcn for which this update is to be applied. If the
  100. // TargetAttribute is the MFT, then the Vcn will always be the exact
  101. // Vcn of the start of the file record segment being modified, even
  102. // if the modification happens to be in a subsequent cluster of the
  103. // same file record. The byte offset in this case is the offset to
  104. // the attribute being changed. For the Mft, AttributeOffset may be used
  105. // to represent the offset from the start of the attribute record
  106. // at which an update is to be applied.
  107. //
  108. // If the update is to some other (nonresident) attribute, then
  109. // TargetVcn and RecordOffset may be used to calculate the reference
  110. // point for the update. The ClusterBlockOffset refers to the number
  111. // of 512 byte blocks this structure is from the beginning of the
  112. // logged Vcn.
  113. //
  114. // As a bottom line, the exact use of these fields is up to the
  115. // writer of this particular log operation, and the associated
  116. // restart routines for this attribute.
  117. //
  118. USHORT RecordOffset;
  119. USHORT AttributeOffset;
  120. USHORT ClusterBlockOffset;
  121. USHORT Reserved;
  122. VCN TargetVcn;
  123. //
  124. // Run information. This is a variable-length array of LcnsToFollow
  125. // entries, only the first of which is declared. Note that the writer
  126. // always writes log records according to the physical page size on his
  127. // machine, however whenever the log file is being read, no assumption
  128. // is made about page size. This is to facilitate moving disks between
  129. // systems with different page sizes.
  130. //
  131. LCN LcnsForPage[1];
  132. //
  133. // Immediately following the last run is a log-operation-specific record
  134. // whose length may be calculated by subtracting the length of this header
  135. // from the length of the entire record returned by LFS. These records
  136. // are defined below.
  137. //
  138. } NTFS_LOG_RECORD_HEADER, *PNTFS_LOG_RECORD_HEADER;
  139. //
  140. // RESTART AREA STRUCTURES
  141. //
  142. // The following structures are present in the Restart Area.
  143. //
  144. //
  145. // Generic Restart Table
  146. //
  147. // This is a generic table definition for the purpose of describing one
  148. // of the three table structures used at Restart: the Open Attribute Table,
  149. // the Dirty Pages Table, and the Transaction Table. This simple structure
  150. // allows for common initialization and free list management. Allocation
  151. // and Deallocation and lookup by index are extremely fast, while lookup
  152. // by value (only performed in the Dirty Pages Table during Restart) is
  153. // a little slower. I.e., all accesses to these tables during normal
  154. // operation are extremely fast.
  155. //
  156. // If fast access to a table entry by value becomes an issue, then the
  157. // table may be supplemented by an external Generic Table - it is probably
  158. // not a good idea to make the Generic Table be part of the structure
  159. // written to the Log File.
  160. //
  161. // Entries in a Restart Table should start with:
  162. //
  163. // ULONG AllocatedOrNextFree;
  164. //
  165. // An allocated entry will have the pattern RESTART_ENTRY_ALLOCATED
  166. // in this field.
  167. //
  168. #define RESTART_ENTRY_ALLOCATED (0xFFFFFFFF)
  169. typedef struct _RESTART_TABLE {
  170. //
  171. // Entry size, in bytes
  172. //
  173. USHORT EntrySize;
  174. //
  175. // Total number of entries in table
  176. //
  177. USHORT NumberEntries;
  178. //
  179. // Number entries that are allocated
  180. //
  181. USHORT NumberAllocated;
  182. //
  183. // Reserved for alignment
  184. //
  185. USHORT Reserved[3];
  186. //
  187. // Free goal - Offset after which entries should be freed to end of
  188. // list, as opposed to front. At each checkpoint, the table may be
  189. // truncated if there are enough free entries at the end of the list.
  190. // Expressed as an offset from the start of this structure.
  191. //
  192. ULONG FreeGoal;
  193. //
  194. // First Free entry (head of list) and Last Free entry (used to deallocate
  195. // beyond Free Goal). Expressed as an offset from the start of this
  196. // structure.
  197. //
  198. ULONG FirstFree;
  199. ULONG LastFree;
  200. //
  201. // The table itself starts here.
  202. //
  203. } RESTART_TABLE, *PRESTART_TABLE;
  204. //
  205. // Macro to get a pointer to an entry in a Restart Table, from the Table
  206. // pointer and entry index. NOTE - Don't generate the index in a call
  207. // to NtfsAllocateRestartTableIndex within this macro. The macro code
  208. // tends to capture the Table pointer before generating the index. If the
  209. // table needs to grow then the captured value may be invalid.
  210. //
  211. #define GetRestartEntryFromIndex(TBL,INDX) ( \
  212. (PVOID)((PCHAR)(TBL)->Table + (INDX)) \
  213. )
  214. //
  215. // Macro to get an index for an entry in a Restart Table, from the Table
  216. // pointer and entry pointer.
  217. //
  218. #define GetIndexFromRestartEntry(TBL,ENTRY) ( \
  219. (ULONG)((PCHAR)(ENTRY) - (PCHAR)(TBL)->Table) \
  220. )
  221. //
  222. // Macro to see if an entry in a Restart Table is allocated.
  223. //
  224. #define IsRestartTableEntryAllocated(PTR) ( \
  225. (BOOLEAN)(*(PULONG)(PTR) == RESTART_ENTRY_ALLOCATED) \
  226. )
  227. //
  228. // Macro to retrieve the size of a Restart Table in bytes.
  229. //
  230. #define SizeOfRestartTable(TBL) ( \
  231. (ULONG)(((TBL)->Table->NumberEntries * \
  232. (TBL)->Table->EntrySize) + \
  233. sizeof(RESTART_TABLE)) \
  234. )
  235. #define AllocatedSizeOfRestartTable(TBL) ( \
  236. (ULONG)(((TBL)->Table->NumberAllocated * \
  237. (TBL)->Table->EntrySize) + \
  238. sizeof(RESTART_TABLE)) \
  239. )
  240. //
  241. // Macro to see if Restart Table is empty. It is empty if the
  242. // number allocated is zero.
  243. //
  244. #define IsRestartTableEmpty(TBL) (!(TBL)->Table->NumberAllocated)
  245. //
  246. // Macro to see if an index is within the current range and entry
  247. // boundary of the table.
  248. //
  249. #define IsRestartIndexWithinTable(TBL,INDX) ( \
  250. (BOOLEAN)(((INDX) >= sizeof(RESTART_TABLE)) && \
  251. ((INDX) < SizeOfRestartTable(TBL)) && \
  252. ((((INDX) - sizeof(RESTART_TABLE)) % (TBL)->Table->EntrySize) == 0)) \
  253. )
  254. //
  255. // Macros to acquire and release a Restart Table.
  256. //
  257. #define NtfsAcquireExclusiveRestartTable(TBL,WAIT) { \
  258. ExAcquireResourceExclusiveLite( &(TBL)->Resource,(WAIT)); \
  259. }
  260. #define NtfsAcquireSharedStarveExRestartTable(TBL,WAIT) { \
  261. ExAcquireSharedStarveExclusive( &(TBL)->Resource,(WAIT)); \
  262. }
  263. #define NtfsAcquireSharedRestartTable(TBL,WAIT) { \
  264. ExAcquireResourceSharedLite( &(TBL)->Resource,(WAIT)); \
  265. }
  266. #define NtfsReleaseRestartTable(TBL) { \
  267. ExReleaseResourceLite(&(TBL)->Resource); \
  268. }
  269. //
  270. // Define some tuning parameters to keep the restart tables a
  271. // reasonable size.
  272. //
  273. #define INITIAL_NUMBER_TRANSACTIONS (5)
  274. #define HIGHWATER_TRANSACTION_COUNT (10)
  275. #define INITIAL_NUMBER_ATTRIBUTES (8)
  276. #define HIGHWATER_ATTRIBUTE_COUNT (16)
  277. //
  278. // Attribute Name Entry. This is a simple structure used to store
  279. // all of the attribute names for the Open Attribute Table during
  280. // checkpoint processing. The Attribute Names record written to the log
  281. // is a series of Attribute Name Entries terminated by an entry with
  282. // Index == NameLength == 0. The end of the table may be tested for by
  283. // looking for either of these fields to be 0, as 0 is otherwise invalid
  284. // for both.
  285. //
  286. // Note that the size of this structure is equal to the overhead for storing
  287. // an attribute name in the table, including the UNICODE_NULL.
  288. //
  289. typedef struct _ATTRIBUTE_NAME_ENTRY {
  290. //
  291. // Index for Attibute with this name in the Open Attribute Table.
  292. //
  293. USHORT Index;
  294. //
  295. // Length of attribute name to follow in bytes, including a terminating
  296. // UNICODE_NULL.
  297. //
  298. USHORT NameLength;
  299. //
  300. // Start of attribute name
  301. //
  302. WCHAR Name[1];
  303. } ATTRIBUTE_NAME_ENTRY, *PATTRIBUTE_NAME_ENTRY;
  304. //
  305. // Open Attribute Table. This is the on-disk structure for version 0.
  306. //
  307. // One entry exists in the Open Attribute Table for each nonresident
  308. // attribute of each file that is open with modify access.
  309. //
  310. // This table is initialized at Restart to the maximum of
  311. // DEFAULT_ATTRIBUTE_TABLE_SIZE or the size of the table in the log file.
  312. // It is maintained in the running system.
  313. //
  314. #pragma pack(4)
  315. typedef struct _OPEN_ATTRIBUTE_ENTRY_V0 {
  316. //
  317. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  318. // Otherwise, it is a free link.
  319. //
  320. ULONG AllocatedOrNextFree;
  321. //
  322. // Placeholder for Scb in V0. We use it to point to the index
  323. // in the in-memory structure.
  324. //
  325. ULONG OatIndex;
  326. //
  327. // File Reference of file containing attribute.
  328. //
  329. FILE_REFERENCE FileReference;
  330. //
  331. // Lsn of OpenNonresidentAttribute log record, to distinguish reuses
  332. // of this open file record. Log records referring to this Open
  333. // Attribute Entry Index, but with Lsns older than this field, can
  334. // only occur when the attribute was subsequently deleted - these
  335. // log records can be ignored.
  336. //
  337. LSN LsnOfOpenRecord;
  338. //
  339. // Flag to say if dirty pages seen for this attribute during dirty
  340. // page scan.
  341. //
  342. BOOLEAN DirtyPagesSeen;
  343. //
  344. // Flag to indicate if the pointer in Overlay above is to an Scb or
  345. // attribute name. It is only used during restart when cleaning up
  346. // the open attribute table.
  347. //
  348. BOOLEAN AttributeNamePresent;
  349. //
  350. // Reserved for alignment
  351. //
  352. UCHAR Reserved[2];
  353. //
  354. // The following two fields identify the actual attribute
  355. // with respect to its file. We identify the attribute by
  356. // its type code and name. When the Restart Area is written,
  357. // all of the names for all of the open attributes are temporarily
  358. // copied to the end of the Restart Area.
  359. // The name is not used on disk but must be a 64-bit value.
  360. //
  361. ATTRIBUTE_TYPE_CODE AttributeTypeCode;
  362. LONGLONG AttributeName;
  363. //
  364. // This field is only relevant to indices, i.e., if AttributeTypeCode
  365. // above is $INDEX_ALLOCATION.
  366. //
  367. ULONG BytesPerIndexBuffer;
  368. } OPEN_ATTRIBUTE_ENTRY_V0, *POPEN_ATTRIBUTE_ENTRY_V0;
  369. #pragma pack()
  370. #define SIZEOF_OPEN_ATTRIBUTE_ENTRY_V0 ( \
  371. FIELD_OFFSET( OPEN_ATTRIBUTE_ENTRY_V0, BytesPerIndexBuffer ) + 4 \
  372. )
  373. //
  374. // Auxiliary OpenAttribute data. This is the data that doesn't need to be
  375. // logged.
  376. //
  377. typedef struct OPEN_ATTRIBUTE_DATA {
  378. //
  379. // Queue of these structures attached to the Vcb.
  380. // NOTE - This must be the first entry in this structure.
  381. //
  382. LIST_ENTRY Links;
  383. //
  384. // Index for this entry in the On-disk open attribute table.
  385. //
  386. ULONG OnDiskAttributeIndex;
  387. BOOLEAN AttributeNamePresent;
  388. //
  389. // The following overlay either contains an optional pointer to an
  390. // Attribute Name Entry from the Analysis Phase of Restart, or a
  391. // pointer to an Scb once attributes have been open and in the normal
  392. // running system.
  393. //
  394. // Specifically, after the Analysis Phase of Restart:
  395. //
  396. // AttributeName == NULL if there is no attribute name, or the
  397. // attribute name was captured in the Attribute
  398. // Names Dump in the last successful checkpoint.
  399. // AttributeName != NULL if an OpenNonresidentAttribute log record
  400. // was encountered, and an Attribute Name Entry
  401. // was allocated at that time (and must be
  402. // deallocated when no longer needed).
  403. //
  404. // Once the Nonresident Attributes have been opened during Restart,
  405. // and in the running system, this is an Scb pointer.
  406. //
  407. union {
  408. PWSTR AttributeName;
  409. PSCB Scb;
  410. } Overlay;
  411. //
  412. // Store the unicode string for the attribute name.
  413. //
  414. UNICODE_STRING AttributeName;
  415. } OPEN_ATTRIBUTE_DATA, *POPEN_ATTRIBUTE_DATA;
  416. //
  417. // Open Attribute Table. This is the on-disk structure for version 1 and
  418. // it is the version we always use in-memory.
  419. //
  420. // One entry exists in the Open Attribute Table for each nonresident
  421. // attribute of each file that is open with modify access.
  422. //
  423. // This table is initialized at Restart to the maximum of
  424. // DEFAULT_ATTRIBUTE_TABLE_SIZE or the size of the table in the log file.
  425. // It is maintained in the running system.
  426. //
  427. typedef struct _OPEN_ATTRIBUTE_ENTRY {
  428. //
  429. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  430. // Otherwise, it is a free link.
  431. //
  432. ULONG AllocatedOrNextFree;
  433. //
  434. // This field is only relevant to indices, i.e., if AttributeTypeCode
  435. // above is $INDEX_ALLOCATION.
  436. //
  437. ULONG BytesPerIndexBuffer;
  438. //
  439. // The following two fields identify the actual attribute
  440. // with respect to its file. We identify the attribute by
  441. // its type code and name. When the Restart Area is written,
  442. // all of the names for all of the open attributes are temporarily
  443. // copied to the end of the Restart Area.
  444. //
  445. ATTRIBUTE_TYPE_CODE AttributeTypeCode;
  446. //
  447. // Flag to say if dirty pages seen for this attribute during dirty
  448. // page scan.
  449. //
  450. BOOLEAN DirtyPagesSeen;
  451. CHAR Unused[3];
  452. //
  453. // File Reference of file containing attribute.
  454. //
  455. FILE_REFERENCE FileReference;
  456. //
  457. // Lsn of OpenNonresidentAttribute log record, to distinguish reuses
  458. // of this open file record. Log records referring to this Open
  459. // Attribute Entry Index, but with Lsns older than this field, can
  460. // only occur when the attribute was subsequently deleted - these
  461. // log records can be ignored.
  462. //
  463. LSN LsnOfOpenRecord;
  464. //
  465. // Point to the OpenAttribute data.
  466. //
  467. union {
  468. POPEN_ATTRIBUTE_DATA OatData;
  469. ULONGLONG Alignment;
  470. };
  471. } OPEN_ATTRIBUTE_ENTRY, *POPEN_ATTRIBUTE_ENTRY;
  472. //
  473. // VOID
  474. // NtfsFreeAllOpenAttributeData (
  475. // IN PVCB vCB
  476. // );
  477. //
  478. #define NtfsFreeAllOpenAttributeData(V) { \
  479. while (!IsListEmpty( &(V)->OpenAttributeData )) { \
  480. POPEN_ATTRIBUTE_DATA _Next = CONTAINING_RECORD( (V)->OpenAttributeData.Flink, \
  481. OPEN_ATTRIBUTE_DATA, \
  482. Links ); \
  483. NtfsFreeOpenAttributeData( _Next ); \
  484. } \
  485. }
  486. //
  487. // Dirty Pages Table - Version 0
  488. //
  489. // This entry is for restart version 0. It is inadvertently misaligned.
  490. //
  491. // One entry exists in the Dirty Pages Table for each page which is
  492. // dirty at the time the Restart Area is written.
  493. //
  494. // This table is initialized at Restart to the maximum of
  495. // DEFAULT_DIRTY_PAGES_TABLE_SIZE or the size of the table in the log file.
  496. // It is *not* maintained in the running system.
  497. //
  498. #pragma pack(4)
  499. typedef struct _DIRTY_PAGE_ENTRY_V0 {
  500. //
  501. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  502. // Otherwise, it is a free link.
  503. //
  504. ULONG AllocatedOrNextFree;
  505. //
  506. // Target attribute index. This is the index into the Open Attribute
  507. // Table to which this dirty page entry applies.
  508. //
  509. ULONG TargetAttribute;
  510. //
  511. // Length of transfer, in case this is the end of file, and we cannot
  512. // write an entire page.
  513. //
  514. ULONG LengthOfTransfer;
  515. //
  516. // Number of Lcns in the array at end of this structure. See comment
  517. // with this array.
  518. //
  519. ULONG LcnsToFollow;
  520. //
  521. // Reserved for alignment
  522. //
  523. ULONG Reserved;
  524. //
  525. // Vcn of dirty page.
  526. //
  527. VCN Vcn;
  528. //
  529. // OldestLsn for log record for which the update has not yet been
  530. // written through to disk.
  531. //
  532. LSN OldestLsn;
  533. //
  534. // Run information. This is a variable-length array of LcnsToFollow
  535. // entries, only the first of which is declared. Note that the writer
  536. // always writes pages according to the physical page size on his
  537. // machine, however whenever the log file is being read, no assumption
  538. // is made about page size. This is to facilitate moving disks between
  539. // systems with different page sizes.
  540. //
  541. LCN LcnsForPage[1];
  542. } DIRTY_PAGE_ENTRY_V0, *PDIRTY_PAGE_ENTRY_V0;
  543. #pragma pack()
  544. //
  545. // Dirty Pages Table - Version 1
  546. //
  547. // This version correctly aligns the 64-bit fields.
  548. //
  549. // One entry exists in the Dirty Pages Table for each page which is
  550. // dirty at the time the Restart Area is written.
  551. //
  552. // This table is initialized at Restart to the maximum of
  553. // DEFAULT_DIRTY_PAGES_TABLE_SIZE or the size of the table in the log file.
  554. // It is *not* maintained in the running system.
  555. //
  556. typedef struct _DIRTY_PAGE_ENTRY {
  557. //
  558. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  559. // Otherwise, it is a free link.
  560. //
  561. ULONG AllocatedOrNextFree;
  562. //
  563. // Target attribute index. This is the index into the Open Attribute
  564. // Table to which this dirty page entry applies.
  565. //
  566. ULONG TargetAttribute;
  567. //
  568. // Length of transfer, in case this is the end of file, and we cannot
  569. // write an entire page.
  570. //
  571. ULONG LengthOfTransfer;
  572. //
  573. // Number of Lcns in the array at end of this structure. See comment
  574. // with this array.
  575. //
  576. ULONG LcnsToFollow;
  577. //
  578. // Vcn of dirty page.
  579. //
  580. VCN Vcn;
  581. //
  582. // OldestLsn for log record for which the update has not yet been
  583. // written through to disk.
  584. //
  585. LSN OldestLsn;
  586. //
  587. // Run information. This is a variable-length array of LcnsToFollow
  588. // entries, only the first of which is declared. Note that the writer
  589. // always writes pages according to the physical page size on his
  590. // machine, however whenever the log file is being read, no assumption
  591. // is made about page size. This is to facilitate moving disks between
  592. // systems with different page sizes.
  593. //
  594. LCN LcnsForPage[1];
  595. } DIRTY_PAGE_ENTRY, *PDIRTY_PAGE_ENTRY;
  596. //
  597. // Transaction Table
  598. //
  599. // One transaction entry exists for each existing transaction at the time
  600. // the Restart Area is written.
  601. //
  602. // Currently only local transactions are supported, and the transaction
  603. // ID is simply used to index into this table.
  604. //
  605. // This table is initialized at Restart to the maximum of
  606. // DEFAULT_TRANSACTION_TABLE_SIZE or the size of the table in the log file.
  607. // It is maintained in the running system.
  608. //
  609. typedef struct _TRANSACTION_ENTRY {
  610. //
  611. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  612. // Otherwise, it is a free link.
  613. //
  614. ULONG AllocatedOrNextFree;
  615. //
  616. // Transaction State
  617. //
  618. UCHAR TransactionState;
  619. //
  620. // Reserved for proper alignment
  621. //
  622. UCHAR Reserved[3];
  623. //
  624. // First Lsn for transaction. This tells us how far back in the log
  625. // we may have to read to abort the transaction.
  626. //
  627. LSN FirstLsn;
  628. //
  629. // PreviousLsn written for the transaction and UndoNextLsn (next record
  630. // which should be undone in the event of a rollback.
  631. //
  632. LSN PreviousLsn;
  633. LSN UndoNextLsn;
  634. //
  635. // Number of of undo log records pending abort, and total undo size.
  636. //
  637. ULONG UndoRecords;
  638. LONG UndoBytes;
  639. } TRANSACTION_ENTRY, *PTRANSACTION_ENTRY;
  640. //
  641. // Restart record
  642. //
  643. // The Restart record used by NTFS is small, and it only describes where
  644. // the above information has been written to the log. The above records
  645. // may be considered logically part of NTFS's restart area.
  646. //
  647. typedef struct _RESTART_AREA {
  648. //
  649. // Version numbers of NTFS Restart Implementation
  650. //
  651. ULONG MajorVersion;
  652. ULONG MinorVersion;
  653. //
  654. // Lsn of Start of Checkpoint. This is the Lsn at which the Analysis
  655. // Phase of Restart must begin.
  656. //
  657. LSN StartOfCheckpoint;
  658. //
  659. // Lsns at which the four tables above plus the attribute names reside.
  660. //
  661. LSN OpenAttributeTableLsn;
  662. LSN AttributeNamesLsn;
  663. LSN DirtyPageTableLsn;
  664. LSN TransactionTableLsn;
  665. //
  666. // Lengths of the above structures in bytes.
  667. //
  668. ULONG OpenAttributeTableLength;
  669. ULONG AttributeNamesLength;
  670. ULONG DirtyPageTableLength;
  671. ULONG TransactionTableLength;
  672. //
  673. // Oldest Usn from which scan must occur to pickup all files which
  674. // have not been through cleanup.
  675. //
  676. USN LowestOpenUsn;
  677. LSN CurrentLsnAtMount;
  678. ULONG BytesPerCluster;
  679. ULONG Reserved;
  680. //
  681. // Keep some additional information about the Usn journal so we
  682. // can reduce the amount of caching we do.
  683. //
  684. FILE_REFERENCE UsnJournalReference;
  685. LONGLONG UsnCacheBias;
  686. } RESTART_AREA, *PRESTART_AREA;
  687. //
  688. // This symbols is used to accept Restart Areas with or without the OldestUsn
  689. //
  690. #define SIZEOF_OLD_RESTART_AREA (FIELD_OFFSET( RESTART_AREA, LowestOpenUsn ))
  691. //
  692. // RECORD STRUCTURES USED BY LOG RECORDS
  693. //
  694. //
  695. // Set new attribute sizes
  696. //
  697. typedef struct _NEW_ATTRIBUTE_SIZES {
  698. LONGLONG AllocationSize;
  699. LONGLONG ValidDataLength;
  700. LONGLONG FileSize;
  701. LONGLONG TotalAllocated;
  702. } NEW_ATTRIBUTE_SIZES, *PNEW_ATTRIBUTE_SIZES;
  703. #define SIZEOF_FULL_ATTRIBUTE_SIZES ( \
  704. sizeof( NEW_ATTRIBUTE_SIZES ) \
  705. )
  706. #define SIZEOF_PARTIAL_ATTRIBUTE_SIZES ( \
  707. FIELD_OFFSET( NEW_ATTRIBUTE_SIZES, TotalAllocated ) \
  708. )
  709. //
  710. // Describe a bitmap range
  711. //
  712. typedef struct _BITMAP_RANGE {
  713. ULONG BitMapOffset;
  714. ULONG NumberOfBits;
  715. } BITMAP_RANGE, *PBITMAP_RANGE;
  716. //
  717. // Describe a range of Lcns
  718. //
  719. typedef struct _LCN_RANGE {
  720. LCN StartLcn;
  721. LONGLONG Count;
  722. } LCN_RANGE, *PLCN_RANGE;
  723. #define MAX_RESTART_TABLE_SIZE 0xF000
  724. #endif // _NTFSLOG_