Source code of Windows XP (NT5)
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.

943 lines
25 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. //
  236. // Macro to see if Restart Table is empty. It is empty if the
  237. // number allocated is zero.
  238. //
  239. #define IsRestartTableEmpty(TBL) (!(TBL)->Table->NumberAllocated)
  240. //
  241. // Macro to see if an index is within the currently allocated size
  242. // for that table.
  243. //
  244. #define IsRestartIndexWithinTable(TBL,INDX) ( \
  245. (BOOLEAN)((INDX) < SizeOfRestartTable(TBL)) \
  246. )
  247. //
  248. // Macros to acquire and release a Restart Table.
  249. //
  250. #define NtfsAcquireExclusiveRestartTable(TBL,WAIT) { \
  251. ExAcquireResourceExclusiveLite( &(TBL)->Resource,(WAIT)); \
  252. }
  253. #define NtfsAcquireSharedStartExRestartTable(TBL,WAIT) { \
  254. ExAcquireSharedStarveExclusive( &(TBL)->Resource,(WAIT)); \
  255. }
  256. #define NtfsAcquireSharedRestartTable(TBL,WAIT) { \
  257. ExAcquireResourceSharedLite( &(TBL)->Resource,(WAIT)); \
  258. }
  259. #define NtfsReleaseRestartTable(TBL) { \
  260. ExReleaseResourceLite(&(TBL)->Resource); \
  261. }
  262. //
  263. // Define some tuning parameters to keep the restart tables a
  264. // reasonable size.
  265. //
  266. #define INITIAL_NUMBER_TRANSACTIONS (5)
  267. #define HIGHWATER_TRANSACTION_COUNT (10)
  268. #define INITIAL_NUMBER_ATTRIBUTES (8)
  269. #define HIGHWATER_ATTRIBUTE_COUNT (16)
  270. //
  271. // Attribute Name Entry. This is a simple structure used to store
  272. // all of the attribute names for the Open Attribute Table during
  273. // checkpoint processing. The Attribute Names record written to the log
  274. // is a series of Attribute Name Entries terminated by an entry with
  275. // Index == NameLength == 0. The end of the table may be tested for by
  276. // looking for either of these fields to be 0, as 0 is otherwise invalid
  277. // for both.
  278. //
  279. // Note that the size of this structure is equal to the overhead for storing
  280. // an attribute name in the table, including the UNICODE_NULL.
  281. //
  282. typedef struct _ATTRIBUTE_NAME_ENTRY {
  283. //
  284. // Index for Attibute with this name in the Open Attribute Table.
  285. //
  286. USHORT Index;
  287. //
  288. // Length of attribute name to follow in bytes, including a terminating
  289. // UNICODE_NULL.
  290. //
  291. USHORT NameLength;
  292. //
  293. // Start of attribute name
  294. //
  295. WCHAR Name[1];
  296. } ATTRIBUTE_NAME_ENTRY, *PATTRIBUTE_NAME_ENTRY;
  297. //
  298. // Open Attribute Table. This is the on-disk structure for version 0.
  299. //
  300. // One entry exists in the Open Attribute Table for each nonresident
  301. // attribute of each file that is open with modify access.
  302. //
  303. // This table is initialized at Restart to the maximum of
  304. // DEFAULT_ATTRIBUTE_TABLE_SIZE or the size of the table in the log file.
  305. // It is maintained in the running system.
  306. //
  307. #pragma pack(4)
  308. typedef struct _OPEN_ATTRIBUTE_ENTRY_V0 {
  309. //
  310. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  311. // Otherwise, it is a free link.
  312. //
  313. ULONG AllocatedOrNextFree;
  314. //
  315. // Placeholder for Scb in V0. We use it to point to the index
  316. // in the in-memory structure.
  317. //
  318. ULONG OatIndex;
  319. //
  320. // File Reference of file containing attribute.
  321. //
  322. FILE_REFERENCE FileReference;
  323. //
  324. // Lsn of OpenNonresidentAttribute log record, to distinguish reuses
  325. // of this open file record. Log records referring to this Open
  326. // Attribute Entry Index, but with Lsns older than this field, can
  327. // only occur when the attribute was subsequently deleted - these
  328. // log records can be ignored.
  329. //
  330. LSN LsnOfOpenRecord;
  331. //
  332. // Flag to say if dirty pages seen for this attribute during dirty
  333. // page scan.
  334. //
  335. BOOLEAN DirtyPagesSeen;
  336. //
  337. // Flag to indicate if the pointer in Overlay above is to an Scb or
  338. // attribute name. It is only used during restart when cleaning up
  339. // the open attribute table.
  340. //
  341. BOOLEAN AttributeNamePresent;
  342. //
  343. // Reserved for alignment
  344. //
  345. UCHAR Reserved[2];
  346. //
  347. // The following two fields identify the actual attribute
  348. // with respect to its file. We identify the attribute by
  349. // its type code and name. When the Restart Area is written,
  350. // all of the names for all of the open attributes are temporarily
  351. // copied to the end of the Restart Area.
  352. // The name is not used on disk but must be a 64-bit value.
  353. //
  354. ATTRIBUTE_TYPE_CODE AttributeTypeCode;
  355. LONGLONG AttributeName;
  356. //
  357. // This field is only relevant to indices, i.e., if AttributeTypeCode
  358. // above is $INDEX_ALLOCATION.
  359. //
  360. ULONG BytesPerIndexBuffer;
  361. } OPEN_ATTRIBUTE_ENTRY_V0, *POPEN_ATTRIBUTE_ENTRY_V0;
  362. #pragma pack()
  363. #define SIZEOF_OPEN_ATTRIBUTE_ENTRY_V0 ( \
  364. FIELD_OFFSET( OPEN_ATTRIBUTE_ENTRY_V0, BytesPerIndexBuffer ) + 4 \
  365. )
  366. //
  367. // Auxiliary OpenAttribute data. This is the data that doesn't need to be
  368. // logged.
  369. //
  370. typedef struct OPEN_ATTRIBUTE_DATA {
  371. //
  372. // Queue of these structures attached to the Vcb.
  373. // NOTE - This must be the first entry in this structure.
  374. //
  375. LIST_ENTRY Links;
  376. //
  377. // Index for this entry in the On-disk open attribute table.
  378. //
  379. ULONG OnDiskAttributeIndex;
  380. BOOLEAN AttributeNamePresent;
  381. //
  382. // The following overlay either contains an optional pointer to an
  383. // Attribute Name Entry from the Analysis Phase of Restart, or a
  384. // pointer to an Scb once attributes have been open and in the normal
  385. // running system.
  386. //
  387. // Specifically, after the Analysis Phase of Restart:
  388. //
  389. // AttributeName == NULL if there is no attribute name, or the
  390. // attribute name was captured in the Attribute
  391. // Names Dump in the last successful checkpoint.
  392. // AttributeName != NULL if an OpenNonresidentAttribute log record
  393. // was encountered, and an Attribute Name Entry
  394. // was allocated at that time (and must be
  395. // deallocated when no longer needed).
  396. //
  397. // Once the Nonresident Attributes have been opened during Restart,
  398. // and in the running system, this is an Scb pointer.
  399. //
  400. union {
  401. PWSTR AttributeName;
  402. PSCB Scb;
  403. } Overlay;
  404. //
  405. // Store the unicode string for the attribute name.
  406. //
  407. UNICODE_STRING AttributeName;
  408. } OPEN_ATTRIBUTE_DATA, *POPEN_ATTRIBUTE_DATA;
  409. //
  410. // Open Attribute Table. This is the on-disk structure for version 1 and
  411. // it is the version we always use in-memory.
  412. //
  413. // One entry exists in the Open Attribute Table for each nonresident
  414. // attribute of each file that is open with modify access.
  415. //
  416. // This table is initialized at Restart to the maximum of
  417. // DEFAULT_ATTRIBUTE_TABLE_SIZE or the size of the table in the log file.
  418. // It is maintained in the running system.
  419. //
  420. typedef struct _OPEN_ATTRIBUTE_ENTRY {
  421. //
  422. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  423. // Otherwise, it is a free link.
  424. //
  425. ULONG AllocatedOrNextFree;
  426. //
  427. // This field is only relevant to indices, i.e., if AttributeTypeCode
  428. // above is $INDEX_ALLOCATION.
  429. //
  430. ULONG BytesPerIndexBuffer;
  431. //
  432. // The following two fields identify the actual attribute
  433. // with respect to its file. We identify the attribute by
  434. // its type code and name. When the Restart Area is written,
  435. // all of the names for all of the open attributes are temporarily
  436. // copied to the end of the Restart Area.
  437. //
  438. ATTRIBUTE_TYPE_CODE AttributeTypeCode;
  439. //
  440. // Flag to say if dirty pages seen for this attribute during dirty
  441. // page scan.
  442. //
  443. BOOLEAN DirtyPagesSeen;
  444. CHAR Unused[3];
  445. //
  446. // File Reference of file containing attribute.
  447. //
  448. FILE_REFERENCE FileReference;
  449. //
  450. // Lsn of OpenNonresidentAttribute log record, to distinguish reuses
  451. // of this open file record. Log records referring to this Open
  452. // Attribute Entry Index, but with Lsns older than this field, can
  453. // only occur when the attribute was subsequently deleted - these
  454. // log records can be ignored.
  455. //
  456. LSN LsnOfOpenRecord;
  457. //
  458. // Point to the OpenAttribute data.
  459. //
  460. union {
  461. POPEN_ATTRIBUTE_DATA OatData;
  462. ULONGLONG Alignment;
  463. };
  464. } OPEN_ATTRIBUTE_ENTRY, *POPEN_ATTRIBUTE_ENTRY;
  465. //
  466. // VOID
  467. // NtfsFreeAllOpenAttributeData (
  468. // IN PVCB vCB
  469. // );
  470. //
  471. #define NtfsFreeAllOpenAttributeData(V) { \
  472. while (!IsListEmpty( &(V)->OpenAttributeData )) { \
  473. POPEN_ATTRIBUTE_DATA _Next = CONTAINING_RECORD( (V)->OpenAttributeData.Flink, \
  474. OPEN_ATTRIBUTE_DATA, \
  475. Links ); \
  476. NtfsFreeOpenAttributeData( _Next ); \
  477. } \
  478. }
  479. //
  480. // Dirty Pages Table - Version 0
  481. //
  482. // This entry is for restart version 0. It is inadvertently misaligned.
  483. //
  484. // One entry exists in the Dirty Pages Table for each page which is
  485. // dirty at the time the Restart Area is written.
  486. //
  487. // This table is initialized at Restart to the maximum of
  488. // DEFAULT_DIRTY_PAGES_TABLE_SIZE or the size of the table in the log file.
  489. // It is *not* maintained in the running system.
  490. //
  491. #pragma pack(4)
  492. typedef struct _DIRTY_PAGE_ENTRY_V0 {
  493. //
  494. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  495. // Otherwise, it is a free link.
  496. //
  497. ULONG AllocatedOrNextFree;
  498. //
  499. // Target attribute index. This is the index into the Open Attribute
  500. // Table to which this dirty page entry applies.
  501. //
  502. ULONG TargetAttribute;
  503. //
  504. // Length of transfer, in case this is the end of file, and we cannot
  505. // write an entire page.
  506. //
  507. ULONG LengthOfTransfer;
  508. //
  509. // Number of Lcns in the array at end of this structure. See comment
  510. // with this array.
  511. //
  512. ULONG LcnsToFollow;
  513. //
  514. // Reserved for alignment
  515. //
  516. ULONG Reserved;
  517. //
  518. // Vcn of dirty page.
  519. //
  520. VCN Vcn;
  521. //
  522. // OldestLsn for log record for which the update has not yet been
  523. // written through to disk.
  524. //
  525. LSN OldestLsn;
  526. //
  527. // Run information. This is a variable-length array of LcnsToFollow
  528. // entries, only the first of which is declared. Note that the writer
  529. // always writes pages according to the physical page size on his
  530. // machine, however whenever the log file is being read, no assumption
  531. // is made about page size. This is to facilitate moving disks between
  532. // systems with different page sizes.
  533. //
  534. LCN LcnsForPage[1];
  535. } DIRTY_PAGE_ENTRY_V0, *PDIRTY_PAGE_ENTRY_V0;
  536. #pragma pack()
  537. //
  538. // Dirty Pages Table - Version 1
  539. //
  540. // This version correctly aligns the 64-bit fields.
  541. //
  542. // One entry exists in the Dirty Pages Table for each page which is
  543. // dirty at the time the Restart Area is written.
  544. //
  545. // This table is initialized at Restart to the maximum of
  546. // DEFAULT_DIRTY_PAGES_TABLE_SIZE or the size of the table in the log file.
  547. // It is *not* maintained in the running system.
  548. //
  549. typedef struct _DIRTY_PAGE_ENTRY {
  550. //
  551. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  552. // Otherwise, it is a free link.
  553. //
  554. ULONG AllocatedOrNextFree;
  555. //
  556. // Target attribute index. This is the index into the Open Attribute
  557. // Table to which this dirty page entry applies.
  558. //
  559. ULONG TargetAttribute;
  560. //
  561. // Length of transfer, in case this is the end of file, and we cannot
  562. // write an entire page.
  563. //
  564. ULONG LengthOfTransfer;
  565. //
  566. // Number of Lcns in the array at end of this structure. See comment
  567. // with this array.
  568. //
  569. ULONG LcnsToFollow;
  570. //
  571. // Vcn of dirty page.
  572. //
  573. VCN Vcn;
  574. //
  575. // OldestLsn for log record for which the update has not yet been
  576. // written through to disk.
  577. //
  578. LSN OldestLsn;
  579. //
  580. // Run information. This is a variable-length array of LcnsToFollow
  581. // entries, only the first of which is declared. Note that the writer
  582. // always writes pages according to the physical page size on his
  583. // machine, however whenever the log file is being read, no assumption
  584. // is made about page size. This is to facilitate moving disks between
  585. // systems with different page sizes.
  586. //
  587. LCN LcnsForPage[1];
  588. } DIRTY_PAGE_ENTRY, *PDIRTY_PAGE_ENTRY;
  589. //
  590. // Transaction Table
  591. //
  592. // One transaction entry exists for each existing transaction at the time
  593. // the Restart Area is written.
  594. //
  595. // Currently only local transactions are supported, and the transaction
  596. // ID is simply used to index into this table.
  597. //
  598. // This table is initialized at Restart to the maximum of
  599. // DEFAULT_TRANSACTION_TABLE_SIZE or the size of the table in the log file.
  600. // It is maintained in the running system.
  601. //
  602. typedef struct _TRANSACTION_ENTRY {
  603. //
  604. // Entry is allocated if this field contains RESTART_ENTRY_ALLOCATED.
  605. // Otherwise, it is a free link.
  606. //
  607. ULONG AllocatedOrNextFree;
  608. //
  609. // Transaction State
  610. //
  611. UCHAR TransactionState;
  612. //
  613. // Reserved for proper alignment
  614. //
  615. UCHAR Reserved[3];
  616. //
  617. // First Lsn for transaction. This tells us how far back in the log
  618. // we may have to read to abort the transaction.
  619. //
  620. LSN FirstLsn;
  621. //
  622. // PreviousLsn written for the transaction and UndoNextLsn (next record
  623. // which should be undone in the event of a rollback.
  624. //
  625. LSN PreviousLsn;
  626. LSN UndoNextLsn;
  627. //
  628. // Number of of undo log records pending abort, and total undo size.
  629. //
  630. ULONG UndoRecords;
  631. LONG UndoBytes;
  632. } TRANSACTION_ENTRY, *PTRANSACTION_ENTRY;
  633. //
  634. // Restart record
  635. //
  636. // The Restart record used by NTFS is small, and it only describes where
  637. // the above information has been written to the log. The above records
  638. // may be considered logically part of NTFS's restart area.
  639. //
  640. typedef struct _RESTART_AREA {
  641. //
  642. // Version numbers of NTFS Restart Implementation
  643. //
  644. ULONG MajorVersion;
  645. ULONG MinorVersion;
  646. //
  647. // Lsn of Start of Checkpoint. This is the Lsn at which the Analysis
  648. // Phase of Restart must begin.
  649. //
  650. LSN StartOfCheckpoint;
  651. //
  652. // Lsns at which the four tables above plus the attribute names reside.
  653. //
  654. LSN OpenAttributeTableLsn;
  655. LSN AttributeNamesLsn;
  656. LSN DirtyPageTableLsn;
  657. LSN TransactionTableLsn;
  658. //
  659. // Lengths of the above structures in bytes.
  660. //
  661. ULONG OpenAttributeTableLength;
  662. ULONG AttributeNamesLength;
  663. ULONG DirtyPageTableLength;
  664. ULONG TransactionTableLength;
  665. //
  666. // Oldest Usn from which scan must occur to pickup all files which
  667. // have not been through cleanup.
  668. //
  669. USN LowestOpenUsn;
  670. LSN CurrentLsnAtMount;
  671. ULONG BytesPerCluster;
  672. ULONG Reserved;
  673. //
  674. // Keep some additional information about the Usn journal so we
  675. // can reduce the amount of caching we do.
  676. //
  677. FILE_REFERENCE UsnJournalReference;
  678. LONGLONG UsnCacheBias;
  679. } RESTART_AREA, *PRESTART_AREA;
  680. //
  681. // This symbols is used to accept Restart Areas with or without the OldestUsn
  682. //
  683. #define SIZEOF_OLD_RESTART_AREA (FIELD_OFFSET( RESTART_AREA, LowestOpenUsn ))
  684. //
  685. // RECORD STRUCTURES USED BY LOG RECORDS
  686. //
  687. //
  688. // Set new attribute sizes
  689. //
  690. typedef struct _NEW_ATTRIBUTE_SIZES {
  691. LONGLONG AllocationSize;
  692. LONGLONG ValidDataLength;
  693. LONGLONG FileSize;
  694. LONGLONG TotalAllocated;
  695. } NEW_ATTRIBUTE_SIZES, *PNEW_ATTRIBUTE_SIZES;
  696. #define SIZEOF_FULL_ATTRIBUTE_SIZES ( \
  697. sizeof( NEW_ATTRIBUTE_SIZES ) \
  698. )
  699. #define SIZEOF_PARTIAL_ATTRIBUTE_SIZES ( \
  700. FIELD_OFFSET( NEW_ATTRIBUTE_SIZES, TotalAllocated ) \
  701. )
  702. //
  703. // Describe a bitmap range
  704. //
  705. typedef struct _BITMAP_RANGE {
  706. ULONG BitMapOffset;
  707. ULONG NumberOfBits;
  708. } BITMAP_RANGE, *PBITMAP_RANGE;
  709. //
  710. // Describe a range of Lcns
  711. //
  712. typedef struct _LCN_RANGE {
  713. LCN StartLcn;
  714. LONGLONG Count;
  715. } LCN_RANGE, *PLCN_RANGE;
  716. #endif // _NTFSLOG_