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.

508 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: RCSTRMHD.HXX
  7. //
  8. // Contents: Header information for the Recoverable Storage Object.
  9. // This header information must be updated atomically.
  10. //
  11. //
  12. // Classes: CRcovStorageHdr
  13. // SRcovStorageHdr
  14. //
  15. // History: 25-Jan-94 SrikantS Created.
  16. //
  17. //----------------------------------------------------------------------------
  18. #pragma once
  19. #include <pshpack4.h>
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Struct: CRcovStrmHdr,
  23. //
  24. // Purpose: Stream management header associated with each copy of the
  25. // recoverable streams.
  26. //
  27. // History: 1-25-94 SrikantS Created
  28. //
  29. //----------------------------------------------------------------------------
  30. //
  31. // A stream can be "decommitted in the front" only in units of
  32. // VACB_MAPPING_GRANULARITY which is 256K. So, we have to accumulate the bytes
  33. // to be "shrinked" until we reach the 256K number. In the picture below, that
  34. // region is "B". The region "A" is the part that has already been de-committed
  35. // by OFS.
  36. //
  37. // The stream may look like this
  38. //
  39. // |-----//-------|--------|------------------|---------------|
  40. // | A // A | B | C | D |
  41. // |---//---------|--------|------------------|---------------|
  42. //
  43. // A = "Hole" - n * SHRINK_FROM_FRONT_PAGE_SIZE. This is the region which
  44. // is de-committed as part of the "OFS ShrinkFromFront" operation.
  45. //
  46. // B = the committed region which is not visible to the user . These are the
  47. // bytes being accumulated to be "decommitted" once we reach the magic
  48. // SHRINK_FROM_FRONT_PAGE_SIZE. B is always < SHRINK_FROM_FRONT_PAGE_SIZE.
  49. //
  50. // A + B = _cbSkip
  51. //
  52. // C = _cbValid. This is the "user visible data".
  53. //
  54. // B + C + D = Committed Region. This is in units of 64K chunks because that
  55. // is the mapping granularity in memory mapped files.
  56. //
  57. // When B reaches the size of "SHRINK_FROM_FRONT_PAGE_SIZE", it will be
  58. // made into a "hole" as part of A.
  59. //
  60. class CRcovStrmHdr
  61. {
  62. public:
  63. ULONG _nRec; // Count of records in the stream.
  64. ULONG _cbValid; // Number of valid bytes in the stream.
  65. LONGLONG _cbSkip; // Number of bytes to be skipped in the front.
  66. // Needed for shrink from front.
  67. };
  68. //
  69. // Minimum size for doing a shrink from front. It is 256K but for now
  70. // just make it the COMMON_PAGE_SIZE to do testing.
  71. //
  72. const SHRINK_FROM_FRONT_PAGE_SIZE = 262144; // VACB_MAPPING_GRANULARITY;
  73. inline ULONG VACBPageOffset( const LONGLONG & cb )
  74. {
  75. return lltoul( cb & (SHRINK_FROM_FRONT_PAGE_SIZE-1) );
  76. }
  77. inline LONGLONG llVACBPageRound( const LONGLONG & cb )
  78. {
  79. return ( cb + (SHRINK_FROM_FRONT_PAGE_SIZE-1) ) & ~(SHRINK_FROM_FRONT_PAGE_SIZE-1);
  80. }
  81. inline LONGLONG llVACBPageTrunc( const LONGLONG & cb )
  82. {
  83. return( cb & ~(SHRINK_FROM_FRONT_PAGE_SIZE-1));
  84. }
  85. inline ULONG VACBPageTrunc( ULONG cb )
  86. {
  87. return( cb & ~(SHRINK_FROM_FRONT_PAGE_SIZE-1));
  88. }
  89. //+---------------------------------------------------------------------------
  90. //
  91. // Struct: CRcovUsrHdr
  92. //
  93. // Purpose: User (stream client) header associated with each copy of the
  94. // recoverable streams. This provides for atomic storage of any
  95. // small header information that the client may want to
  96. // store.
  97. //
  98. // History: 1-25-94 SrikantS Created
  99. //
  100. //----------------------------------------------------------------------------
  101. struct CRcovUserHdr
  102. {
  103. enum { CB_USRHDR = 92 };
  104. ULONG GetSize() { return sizeof(_abHdr); }
  105. BYTE _abHdr[CB_USRHDR];
  106. };
  107. //
  108. // RcovOpType : RecoverableOperationType - operations on the storage
  109. // object that are transacted.
  110. //
  111. enum RcovOpType
  112. {
  113. opNone, // No operation is being performed
  114. opRead, // Read operation - for read locking.
  115. opAppend, // Appending to the current stream
  116. opModify, // "Party-On" operation
  117. opMetaData, // Operations on the metadata of the object.
  118. opDirty // To indicate that the backup is just dirty and
  119. // not know which specific operation
  120. };
  121. //+---------------------------------------------------------------------------
  122. //
  123. // Class: CRcovStorageHdr
  124. //
  125. // Purpose: Data format of the information stored in the atomic
  126. // stream of the recoverable storage object. This header
  127. // information keeps track of the current primary copy,
  128. // the recovery operations on the backup (if necessary),
  129. // etc.
  130. //
  131. // This structure MUST be stored atomically. The only
  132. // user of this data must be the PRcovStream class.
  133. //
  134. // History: 1-25-94 SrikantS Created
  135. //
  136. // Notes: The total size of this must be < CB_TINYMAX because
  137. // this stream must be stored as a TINY stream in OFS.
  138. //
  139. //----------------------------------------------------------------------------
  140. class CRcovStorageHdr {
  141. enum { SIGHDR1 = 0x46524853, SIGHDR2 = 0x49524853 };
  142. public:
  143. CRcovStorageHdr(ULONG ulVer)
  144. {
  145. Init(ulVer);
  146. }
  147. CRcovStorageHdr( const void *pvHdr, ULONG cbHdr );
  148. void Init( const void *pvHdr, ULONG cbHdr );
  149. void Init(ULONG ulVer);
  150. enum DataCopyNum { idxOne, idxTwo };
  151. enum { NUMCOPIES = 2 };
  152. BOOL IsValid(ULONG ulExpectedVer) const;
  153. void SetRcovOp( RcovOpType op ) { _opCurr = op; }
  154. BOOL IsInTransaction() const { return opNone != _opCurr; }
  155. BOOL IsWritable() const
  156. {
  157. return (opNone != _opCurr) && (opRead != _opCurr) ;
  158. }
  159. DataCopyNum GetPrimary() const { return _iPrimary; }
  160. DataCopyNum GetBackup() const
  161. {
  162. return idxOne == _iPrimary ? idxTwo : idxOne;
  163. }
  164. BOOL IsBackupClean() const { return opNone == _opCurr; }
  165. void SyncBackup();
  166. void SwitchPrimary();
  167. void GetUserHdr( DataCopyNum nCopy, CRcovUserHdr & hdr ) const
  168. {
  169. hdr = _ahdrUser[nCopy];
  170. }
  171. void SetUserHdr( DataCopyNum nCopy, const CRcovUserHdr & hdr )
  172. {
  173. _ahdrUser[nCopy] = hdr;
  174. }
  175. ULONG GetCount( DataCopyNum nCopy ) const
  176. {
  177. return _ahdrStrm[nCopy]._nRec;
  178. }
  179. void SetCount( DataCopyNum nCopy, ULONG nRec )
  180. {
  181. _ahdrStrm[nCopy]._nRec = nRec;
  182. }
  183. void IncrementCount( DataCopyNum nCopy, ULONG nDelta = 1 )
  184. {
  185. _ahdrStrm[nCopy]._nRec += nDelta;
  186. }
  187. void DecrementCount( DataCopyNum nCopy, ULONG nDelta = 1 )
  188. {
  189. Win4Assert( nDelta <= _ahdrStrm[nCopy]._nRec );
  190. _ahdrStrm[nCopy]._nRec -= nDelta;
  191. }
  192. ULONG GetUserDataSize( DataCopyNum nCopy ) const;
  193. void SetUserDataSize( DataCopyNum nCopy, ULONG cbNew );
  194. ULONG GetFullSize( DataCopyNum nCopy ) const;
  195. ULONG GetUserDataStart( DataCopyNum nCopy ) const;
  196. void SetCbToSkip( DataCopyNum nCopy, const LONGLONG & cbSkip );
  197. LONGLONG GetCbToSkip( DataCopyNum nCopy ) const;
  198. LONGLONG GetHoleLength( DataCopyNum nCopy ) const;
  199. ULONG GetVersion() const { return _version; }
  200. void SetVersion( ULONG version ) { _version = version; }
  201. ULONG GetFlags() const { return _flags; }
  202. void SetFlags( ULONG flags ) { _flags = flags; }
  203. #ifdef CIEXTMODE
  204. void CiExtDump(void *ciExtSelf);
  205. #endif
  206. private:
  207. //
  208. // DO NOT MOVE THE _version FIELD - IT MUST BE THE FIRST FOUR
  209. // BYTES IN THE HEADER.
  210. //
  211. ULONG _version; // Version Number information
  212. ULONG _flags; // Flags for use by the recoverable object.
  213. DataCopyNum _iPrimary; // Current primary copy num.
  214. RcovOpType _opCurr; // Operation that needs to be recovered.
  215. CRcovStrmHdr _ahdrStrm[NUMCOPIES];
  216. // Two copies of the stream header.
  217. ULONG _sigHdr1; // Signature to check for overruns.
  218. CRcovUserHdr _ahdrUser[NUMCOPIES];
  219. // Two copies of the user defined header.
  220. ULONG _sigHdr2;
  221. };
  222. #include <poppack.h>
  223. inline
  224. CRcovStorageHdr::CRcovStorageHdr( const void * pvBuf, ULONG cbData )
  225. {
  226. Init( pvBuf, cbData );
  227. }
  228. inline
  229. void CRcovStorageHdr::Init( const void * pvBuf, ULONG cbData )
  230. {
  231. Win4Assert( cbData == sizeof(CRcovStorageHdr) );
  232. memcpy( this, pvBuf, sizeof(CRcovStorageHdr) );
  233. }
  234. //+---------------------------------------------------------------------------
  235. //
  236. // Function: SwitchPrimary
  237. //
  238. // Synopsis: Switches the current primary and backup stream
  239. // indices.
  240. //
  241. // History: 2-10-94 srikants Created
  242. //
  243. // Notes:
  244. //
  245. //----------------------------------------------------------------------------
  246. inline void CRcovStorageHdr::SwitchPrimary( )
  247. {
  248. _iPrimary = GetBackup();
  249. }
  250. //+---------------------------------------------------------------------------
  251. //
  252. // Function: SyncBackup
  253. //
  254. // Synopsis: Synchronizes the backup stream header with the primary
  255. // stream header. It also marks that backup is clean.
  256. //
  257. // History: 1-25-94 srikants Created
  258. //
  259. // Notes:
  260. //
  261. //----------------------------------------------------------------------------
  262. inline void CRcovStorageHdr::SyncBackup()
  263. {
  264. DataCopyNum iBackup = GetBackup();
  265. _ahdrUser[iBackup] = _ahdrUser[_iPrimary];
  266. _ahdrStrm[iBackup] = _ahdrStrm[_iPrimary];
  267. _opCurr = opNone;
  268. }
  269. //+---------------------------------------------------------------------------
  270. //
  271. // Member: CRcovStorageHdr::GetUserDataSize
  272. //
  273. // Synopsis: Returns the size data that is visible to the user in the
  274. // given stream.
  275. //
  276. // Arguments: [nCopy] -
  277. //
  278. // History: 9-13-95 srikants Created
  279. //
  280. // Notes: In the picture this is region marked "C"
  281. //
  282. //----------------------------------------------------------------------------
  283. inline ULONG CRcovStorageHdr::GetUserDataSize( DataCopyNum nCopy ) const
  284. {
  285. return _ahdrStrm[nCopy]._cbValid;
  286. }
  287. //+---------------------------------------------------------------------------
  288. //
  289. // Member: CRcovStorageHdr::SetUserDataSize
  290. //
  291. // Synopsis: Sets the size of the data that is visible to the user in
  292. // the given stream.
  293. //
  294. // Arguments: [nCopy] -
  295. // [cbNew] -
  296. //
  297. // History: 9-13-95 srikants Created
  298. //
  299. // Notes: In the picture this is region marked "C"
  300. //
  301. //----------------------------------------------------------------------------
  302. inline void CRcovStorageHdr::SetUserDataSize( DataCopyNum nCopy, ULONG cbNew )
  303. {
  304. _ahdrStrm[nCopy]._cbValid = cbNew;
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // Member: CRcovStorageHdr::GetFullSize
  309. //
  310. // Synopsis: Returns the size of the user visible part + the initial bytes
  311. // which must be skipped. Note that this does NOT include the
  312. // length of the "hole" in the front.
  313. //
  314. // Arguments: [nCopy] -
  315. //
  316. // History: 9-13-95 srikants Created
  317. //
  318. // Notes: In the picture, this is "B+C"
  319. //
  320. //----------------------------------------------------------------------------
  321. inline ULONG CRcovStorageHdr::GetFullSize( DataCopyNum nCopy ) const
  322. {
  323. return GetUserDataStart( nCopy ) + _ahdrStrm[nCopy]._cbValid;
  324. }
  325. //+---------------------------------------------------------------------------
  326. //
  327. // Member: CRcovStorageHdr::GetUserDataStart
  328. //
  329. // Synopsis: Returns the offset of the user data from the "hole" in the
  330. // front. Note that this is NOT the offset from the beginning
  331. // of the stream.
  332. //
  333. // Arguments: [nCopy] -
  334. //
  335. // History: 9-13-95 srikants Created
  336. //
  337. // Notes: In the picture, this is "B"
  338. //
  339. //----------------------------------------------------------------------------
  340. inline ULONG CRcovStorageHdr::GetUserDataStart( DataCopyNum nCopy ) const
  341. {
  342. return VACBPageOffset( _ahdrStrm[nCopy]._cbSkip );
  343. }
  344. //+---------------------------------------------------------------------------
  345. //
  346. // Member: CRcovStorageHdr::GetCbToSkip
  347. //
  348. // Synopsis: The number of bytes from the front of the stream that are
  349. // NOT visible to the user. This is from the beginning of the
  350. // stream.
  351. //
  352. // Arguments: [nCopy] -
  353. //
  354. // History: 9-13-95 srikants Created
  355. //
  356. // Notes: In the picture, this is "A+B"
  357. //
  358. //----------------------------------------------------------------------------
  359. inline LONGLONG CRcovStorageHdr::GetCbToSkip( DataCopyNum nCopy ) const
  360. {
  361. return _ahdrStrm[nCopy]._cbSkip;
  362. }
  363. //+---------------------------------------------------------------------------
  364. //
  365. // Member: CRcovStorageHdr::SetCbToSkip
  366. //
  367. // Synopsis: Sets the number of bytes invisible to the user in the front.
  368. //
  369. // Arguments: [nCopy] -
  370. // [cbSkip] -
  371. //
  372. // History: 9-13-95 srikants Created
  373. //
  374. // Notes: In the picture, this is "A+B"
  375. //
  376. //----------------------------------------------------------------------------
  377. inline void CRcovStorageHdr::SetCbToSkip( DataCopyNum nCopy,
  378. const LONGLONG & cbSkip )
  379. {
  380. _ahdrStrm[nCopy]._cbSkip = cbSkip;
  381. }
  382. //+---------------------------------------------------------------------------
  383. //
  384. // Member: CRcovStorageHdr::GetHoleLength
  385. //
  386. // Synopsis: Returns the length of the "hole" in the front of the stream.
  387. //
  388. // Arguments: [nCopy] -
  389. //
  390. // History: 9-13-95 srikants Created
  391. //
  392. // Notes: In the picture, this is "A"
  393. //
  394. //----------------------------------------------------------------------------
  395. inline LONGLONG CRcovStorageHdr::GetHoleLength( DataCopyNum nCopy ) const
  396. {
  397. return llVACBPageTrunc( _ahdrStrm[nCopy]._cbSkip );
  398. }
  399. //
  400. // SRcovStorageHdr : Safe Pointer to CRcovStorageHdr.
  401. //
  402. class SRcovStorageHdr
  403. {
  404. public:
  405. SRcovStorageHdr(ULONG ulVer)
  406. {
  407. _pRcovStorageHdr = new CRcovStorageHdr(ulVer);
  408. }
  409. SRcovStorageHdr( void *pvHdr, ULONG cbHdr )
  410. {
  411. _pRcovStorageHdr = new CRcovStorageHdr ( pvHdr, cbHdr );
  412. END_CONSTRUCTION( SRcovStorageHdr );
  413. }
  414. ~SRcovStorageHdr()
  415. {
  416. delete _pRcovStorageHdr;
  417. }
  418. CRcovStorageHdr * operator->() { return _pRcovStorageHdr; }
  419. private:
  420. CRcovStorageHdr * _pRcovStorageHdr;
  421. };