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.

378 lines
13 KiB

  1. #ifdef FCB_INCLUDED
  2. #error fcb.h already included
  3. #endif /* FCB_INCLUDED */
  4. #define FCB_INCLUDED
  5. /* unique sequential key
  6. /**/
  7. typedef ULONG DBK;
  8. #define FFCBDeletePending( pfcb ) ( (pfcb)->fFCBDeletePending )
  9. #define FCBSetDeletePending( pfcb ) ( (pfcb)->fFCBDeletePending = 1 )
  10. #define FCBResetDeletePending( pfcb ) ( (pfcb)->fFCBDeletePending = 0 )
  11. #define FFCBOLCStatsAvail( pfcb ) ( (pfcb)->fFCBOLCStatsAvail )
  12. #define FCBSetOLCStatsAvail( pfcb ) ( (pfcb)->fFCBOLCStatsAvail = 1 )
  13. #define FCBResetOLCStatsAvail( pfcb ) ( (pfcb)->fFCBOLCStatsAvail = 0 )
  14. #define FFCBOLCStatsChange( pfcb ) ( (pfcb)->fFCBOLCStatsChange )
  15. #define FCBSetOLCStatsChange( pfcb ) ( (pfcb)->fFCBOLCStatsChange = 1 )
  16. #define FCBResetOLCStatsChange( pfcb ) ( (pfcb)->fFCBOLCStatsChange = 0 )
  17. #define FFCBTemporaryTable( pfcb ) ( (pfcb)->fFCBTemporaryTable )
  18. #define FCBSetTemporaryTable( pfcb ) ( (pfcb)->fFCBTemporaryTable = 1 )
  19. #define FCBResetTemporaryTable( pfcb ) ( (pfcb)->fFCBTemporaryTable = 0 )
  20. #define FFCBSystemTable( pfcb ) \
  21. ( UtilCmpName( (pfcb)->szFileName, szScTable ) == 0 || \
  22. UtilCmpName( (pfcb)->szFileName, szSiTable ) == 0 || \
  23. UtilCmpName( (pfcb)->szFileName, szSoTable ) == 0 )
  24. #define FFCBClusteredIndex( pfcb ) ( (pfcb)->fFCBClusteredIndex )
  25. #define FCBSetClusteredIndex( pfcb ) ( (pfcb)->fFCBClusteredIndex = 1 )
  26. #define FCBResetClusteredIndex( pfcb ) ( (pfcb)->fFCBClusteredIndex = 0 )
  27. #define FFCBDomainDenyWrite( pfcb ) ( (pfcb)->crefDomainDenyWrite > 0 )
  28. #define FCBSetDomainDenyWrite( pfcb ) ( (pfcb)->crefDomainDenyWrite++ )
  29. #define FCBResetDomainDenyWrite( pfcb ) \
  30. { \
  31. Assert( (pfcb)->crefDomainDenyWrite > 0 ); \
  32. --(pfcb)->crefDomainDenyWrite; \
  33. }
  34. #define FFCBDomainDenyRead( pfcb, ppib ) ( (pfcb)->fFCBDomainDenyRead && (ppib) != (pfcb)->ppibDomainDenyRead )
  35. #define FCBSetDomainDenyRead( pfcb, ppib ) \
  36. { \
  37. if ( (pfcb)->crefDomainDenyRead++ == 0 ) \
  38. { \
  39. Assert( (pfcb)->ppibDomainDenyRead == ppibNil ); \
  40. (pfcb)->ppibDomainDenyRead = (ppib); \
  41. (pfcb)->fFCBDomainDenyRead = 1; \
  42. } \
  43. else \
  44. { \
  45. Assert( (pfcb)->ppibDomainDenyRead == (ppib) ); \
  46. Assert( (pfcb)->fFCBDomainDenyRead ); \
  47. } \
  48. }
  49. #define FCBResetDomainDenyRead( pfcb ) \
  50. { \
  51. Assert( (pfcb)->crefDomainDenyRead > 0 ); \
  52. Assert( (pfcb)->ppibDomainDenyRead != ppibNil ); \
  53. Assert( (pfcb)->fFCBDomainDenyRead ); \
  54. if ( --(pfcb)->crefDomainDenyRead == 0 ) \
  55. { \
  56. (pfcb)->fFCBDomainDenyRead = 0; \
  57. (pfcb)->ppibDomainDenyRead = ppibNil; \
  58. } \
  59. }
  60. #define FFCBDomainDenyReadByUs( pfcb, ppib ) ( (pfcb)->fFCBDomainDenyRead && (ppib) == (pfcb)->ppibDomainDenyRead )
  61. // Don't have an explicit fSort flag, but we can tell if it's a sort FCB by
  62. // examining certain fields.
  63. #define FFCBSort( pfcb ) ( (pfcb)->pgnoFDP > pgnoSystemRoot && \
  64. (pfcb)->pfdb == pfdbNil && \
  65. (pfcb)->pfcbNextIndex == pfcbNil && \
  66. (pfcb)->pfcbTable == pfcbNil && \
  67. (pfcb)->pidb == pidbNil && \
  68. (pfcb)->dbid == dbidTemp && \
  69. !FFCBTemporaryTable( pfcb ) && \
  70. !FFCBClusteredIndex( pfcb ) )
  71. #define FFCBReadLatch( pfcb ) ( (pfcb)->crefReadLatch > 0 )
  72. #define FCBSetReadLatch( pfcb ) \
  73. { \
  74. Assert( FFCBClusteredIndex( pfcb ) || \
  75. ( (pfcb)->pgnoFDP == pgnoSystemRoot ) || \
  76. FFCBSort( pfcb ) ); \
  77. (pfcb)->crefReadLatch++; \
  78. }
  79. #define FCBResetReadLatch( pfcb ) \
  80. { \
  81. Assert( (pfcb)->crefReadLatch > 0 ); \
  82. --(pfcb)->crefReadLatch; \
  83. }
  84. #define FFCBSentinel( pfcb ) ( (pfcb)->fFCBSentinel )
  85. #define FCBSetSentinel( pfcb ) ( (pfcb)->fFCBSentinel = 1 )
  86. #define FCBResetSentinel( pfcb ) ( (pfcb)->fFCBSentinel = 0 )
  87. #define FFCBWriteLatch( pfcb, ppib ) ( (pfcb)->crefWriteLatch > 0 && (ppib) != (pfcb)->ppibWriteLatch )
  88. #define FFCBWriteLatchByUs( pfcb, ppib ) ( (pfcb)->crefWriteLatch > 0 && (ppib) == (pfcb)->ppibWriteLatch )
  89. #define FCBSetWriteLatch( pfcb, ppib ) \
  90. { \
  91. Assert( FFCBClusteredIndex( pfcb ) || \
  92. FFCBSentinel( pfcb ) ); \
  93. if ( (pfcb)->crefWriteLatch++ == 0 ) \
  94. { \
  95. Assert( (pfcb)->ppibWriteLatch == ppibNil ); \
  96. (pfcb)->ppibWriteLatch = (ppib); \
  97. } \
  98. else \
  99. { \
  100. Assert( (pfcb)->ppibWriteLatch == ppib ); \
  101. } \
  102. }
  103. #define FCBResetWriteLatch( pfcb, ppib ) \
  104. { \
  105. Assert( FFCBWriteLatchByUs( pfcb, ppib ) ); \
  106. Assert( (pfcb)->crefWriteLatch > 0 ); \
  107. Assert( (pfcb)->ppibWriteLatch != ppibNil ); \
  108. if ( --(pfcb)->crefWriteLatch == 0 ) \
  109. { \
  110. (pfcb)->ppibWriteLatch = ppibNil; \
  111. } \
  112. }
  113. #define FFCBWait( pfcb ) ( (pfcb)->fFCBWait )
  114. #define FCBSetWait( pfcb ) \
  115. { \
  116. Assert( !FFCBWait( pfcb ) ); \
  117. (pfcb)->fFCBWait = 1; \
  118. }
  119. #define FCBResetWait( pfcb ) \
  120. { \
  121. Assert( FFCBWait( pfcb ) ); \
  122. (pfcb)->fFCBWait = 0; \
  123. }
  124. #define FFCBInLRU( pfcb ) ( (pfcb)->fFCBInLRU )
  125. #define FCBSetInLRU( pfcb ) \
  126. { \
  127. Assert( !FFCBInLRU( pfcb ) ); \
  128. (pfcb)->fFCBInLRU = 1; \
  129. }
  130. #define FCBResetInLRU( pfcb ) \
  131. { \
  132. Assert( FFCBInLRU( pfcb ) ); \
  133. (pfcb)->fFCBInLRU = 0; \
  134. }
  135. #define CVersionFCB( pfcb ) (pfcb)->cVersion
  136. #define FCBVersionIncrement( pfcb ) (pfcb)->cVersion++;
  137. #define FCBVersionDecrement( pfcb ) \
  138. { \
  139. if ( (pfcb) != pfcbNil ) \
  140. { \
  141. Assert( cVersion-- > 0 ); \
  142. Assert( (pfcb)->cVersion > 0 ); \
  143. (pfcb)->cVersion--; \
  144. (pfcb) = pfcbNil; \
  145. } \
  146. }
  147. // File Control Block
  148. //
  149. typedef struct _fcb
  150. {
  151. //--------------------USED BY DATA & INDEX FCB---------------------
  152. struct _fdb volatile *pfdb; // field descriptors
  153. struct _fcb *pfcbNextIndex; // chain of indexes for this file
  154. struct _fcb *pfcbLRU; // next LRU FCB in global LRU list
  155. struct _fcb *pfcbMRU; // previous LRU FCB in global LRU list
  156. INT fFCBInLRU : 1; // in LRU list
  157. struct _fcb *pfcbNextInHashBucket;
  158. struct _fcb *pfcbTable; // points to FCB of table for an index FCB
  159. struct _idb *pidb; // index info (NULL if "seq." file)
  160. FUCB *pfucb; // chain of FUCBs open on this file
  161. PGNO pgnoFDP; // FDP of this file/index
  162. DBID dbid; // which database
  163. SHORT cbDensityFree; // loading density parameter:
  164. // # of bytes free w/o using new page
  165. INT wRefCnt; // # of FUCBs for this file/index
  166. INT volatile cVersion; // # of RCEs for this file/index
  167. INT crefDomainDenyRead; // # of FUCBs with deny read flag
  168. INT crefDomainDenyWrite;// # of FUCBs with deny write flag
  169. INT crefReadLatch; // # of read latch on this FCB.
  170. INT crefWriteLatch; // # of FUCB ( of the same ppib ) with write
  171. // latch on this FCB.
  172. PIB *ppibWriteLatch; // ppib of process updating index/adding column
  173. PIB *ppibDomainDenyRead;// ppib of process holding exclusive lock
  174. /* flags for FCB
  175. /**/
  176. union {
  177. ULONG ulFlags;
  178. struct {
  179. INT fFCBTemporaryTable : 1; // This is a temporary file
  180. INT fFCBClusteredIndex : 1; // This FCB is for data records.
  181. INT fFCBDomainDenyRead : 1; // no other session can read domain
  182. INT fFCBSentinel : 1; // FCB is only flag holder
  183. INT fFCBWait : 1; // wait flag
  184. INT fFCBOLCStatsAvail : 1; // are OLC Stats available?
  185. INT fFCBOLCStatsChange : 1; // have OLC Stats changed since last open?
  186. INT fFCBDeletePending : 1; // is a delete pending on this table/index?
  187. };
  188. };
  189. //--------------------USED ONLY BY FCB OF DATA---------------------
  190. CHAR *szFileName; // name of file (for GetTableInfo)
  191. DBK dbkMost; // greatest DBK in use
  192. ULONG ulLongIdMax; // max long field id
  193. BYTE rgbitAllIndex[32]; // used for clustered index FCB only
  194. //-------------------------INSTRUMENTATION----------------------------
  195. ULONG cpgCompactFreed;
  196. P_OLC_DATA olc_data;
  197. /* PCACHE_OPTIMIZATION pads to multiple of 32 bytes.
  198. /* We're currently 4 bytes short, so even if COSTLY_PERF is disabled, add
  199. /* lClass anyways to pad to our requisite 32-byte boundary.
  200. /**/
  201. #if defined( COSTLY_PERF ) || defined( PCACHE_OPTIMIZATION )
  202. ULONG lClass; // table stats class (for BF performance)
  203. #endif
  204. BYTE rgbFiller[20];
  205. } FCB;
  206. /* hash table for FCB
  207. /**/
  208. #define cFCBBuckets 256
  209. FCB* pfcbHash[cFCBBuckets];
  210. #define FCBHashInit() \
  211. { \
  212. Assert( pfcbNil == (FCB *) 0 ); \
  213. memset( pfcbHash, '\0', sizeof( pfcbHash ) ); \
  214. }
  215. #define FCBInitFCB( pfcb ) \
  216. { \
  217. memset( pfcb, '\0', sizeof(FCB) ); \
  218. }
  219. #define PfcbMEMAlloc() ( (FCB *)PbMEMAlloc( iresFCB ) )
  220. #define PfcbMEMPreferredThreshold() ( (FCB *)PbMEMPreferredThreshold( iresFCB ) )
  221. #define PfcbMEMMax() ( (FCB *)PbMEMMax( iresFCB ) )
  222. #ifdef DEBUG /* Debug check for illegal use of freed fcb */
  223. #define MEMReleasePfcb(pfcb) \
  224. { \
  225. Assert( PfcbFCBGet( (pfcb)->dbid, (pfcb)->pgnoFDP ) != pfcb ); \
  226. Assert( (pfcb)->pfdb == pfdbNil ); \
  227. MEMRelease( iresFCB, (BYTE*)(pfcb) ); \
  228. (pfcb) = pfcbNil; \
  229. }
  230. #else
  231. #define MEMReleasePfcb(pfcb) \
  232. { \
  233. MEMRelease( iresFCB, (BYTE*)(pfcb) ); \
  234. }
  235. #endif
  236. ERR ErrFCBISetMode( PIB *ppib, FCB *pfcb, JET_GRBIT grbit );
  237. /* if opening domain for read, write or read write, and not with
  238. /* deny read or deny write, and domain does not have deny read or
  239. /* deny write set, then return JET_errSuccess, else call
  240. /* ErrFCBISetMode to determine if lock is by other session or to
  241. /* put lock on domain.
  242. /**/
  243. INLINE LOCAL ERR ErrFCBSetMode( PIB *ppib, FCB *pfcb, ULONG grbit )
  244. {
  245. if ( ( grbit & ( JET_bitTableDenyRead | JET_bitTableDenyWrite ) ) == 0 )
  246. {
  247. // No read/write restrictions. Ensure no other session has any locks.
  248. if ( !( FFCBWriteLatch( pfcb, ppib ) ||
  249. FFCBDomainDenyRead( pfcb, ppib ) ||
  250. FFCBDomainDenyWrite( pfcb ) ||
  251. FFCBDeletePending( pfcb ) ) )
  252. return JET_errSuccess;
  253. }
  254. return ErrFCBISetMode( ppib, pfcb, grbit );
  255. }
  256. /* reset DDL is same as reset Delete. Both use deny read flags
  257. /* or sentinel.
  258. /**/
  259. #define FCBResetRenameTable FCBResetDeleteTable
  260. extern BYTE * rgfcb;
  261. extern FCB * pfcbGlobalMRU;
  262. extern CRIT critGlobalFCBList;
  263. /* outstanding versions may be on non-clustered index and not on
  264. /* table FCB, so must check all non-clustered indexes before
  265. /* freeing table FCBs.
  266. /**/
  267. STATIC INLINE BOOL FFCBINoVersion( FCB *pfcbTable )
  268. {
  269. FCB *pfcbT;
  270. for ( pfcbT = pfcbTable; pfcbT != pfcbNil; pfcbT = pfcbT->pfcbNextIndex )
  271. {
  272. if ( pfcbT->cVersion > 0 )
  273. {
  274. return fFalse;
  275. }
  276. }
  277. return fTrue;
  278. }
  279. #define FFCBAvail( pfcb, ppib ) \
  280. ( pfcb->wRefCnt == 0 && \
  281. pfcb->pgnoFDP != 1 && \
  282. !FFCBReadLatch( pfcb ) && \
  283. !FFCBSentinel( pfcb ) && \
  284. !FFCBDomainDenyRead( pfcb, ppib ) && \
  285. !FFCBWait( pfcb ) && \
  286. FFCBINoVersion( pfcb ) )
  287. VOID FCBTerm( VOID );
  288. VOID FCBInsert( FCB *pfcb );
  289. VOID FCBLink( FUCB *pfucb, FCB *pfcb );
  290. VOID FCBInsertHashTable( FCB *pfcb );
  291. VOID FCBDeleteHashTable( FCB *pfcb );
  292. VOID FCBUnlink( FUCB *pfucb );
  293. FCB *PfcbFCBGet( DBID dbid, PGNO pgnoFDP );
  294. ERR ErrFCBAlloc( PIB *ppib, FCB **ppfcb );
  295. VOID FCBPurgeDatabase( DBID dbid );
  296. VOID FCBPurgeTable( DBID dbid, PGNO pgnoFDP );
  297. ERR ErrFCBNew( PIB *ppib, DBID dbid, PGNO pgno, FCB **ppfcb );
  298. VOID FCBResetMode( PIB *ppib, FCB *pfcb, JET_GRBIT grbit );
  299. ERR ErrFCBSetDeleteTable( PIB *ppib, DBID dbid, PGNO pgnoFDP );
  300. VOID FCBResetDeleteTable( FCB *pfcb );
  301. ERR ErrFCBSetRenameTable( PIB *ppib, DBID dbid, PGNO pgno );
  302. FCB *FCBResetAfterRedo( void );
  303. BOOL FFCBTableOpen ( DBID dbid, PGNO pgno );
  304. VOID FCBLinkIndex( FCB *pfcbTable, FCB *pfcbIndex );
  305. VOID FCBUnlinkIndex( FCB *pfcbTable, FCB *pfcbIndex );
  306. BOOL FFCBUnlinkIndexIfFound( FCB *pfcbTable, FCB *pfcbIndex );
  307. FCB *PfcbFCBUnlinkIndexByName( FCB *pfcb, CHAR *szIndex );
  308. ERR ErrFCBSetDeleteIndex( PIB *ppib, FCB *pfcbTable, CHAR *szIndex );
  309. VOID FCBResetDeleteIndex( FCB *pfcbIndex );
  310. INLINE STATIC VOID FCBLinkClusteredIdx( FCB *pfcbClustered )
  311. {
  312. FCB *pfcbIdx;
  313. for ( pfcbIdx = pfcbClustered->pfcbNextIndex; pfcbIdx != pfcbNil; pfcbIdx = pfcbIdx->pfcbNextIndex )
  314. {
  315. pfcbIdx->pfcbTable = pfcbClustered;
  316. }
  317. }