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.

340 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. ResrcSup.c
  5. Abstract:
  6. This module implements the Cdfs Resource acquisition routines
  7. // @@BEGIN_DDKSPLIT
  8. Author:
  9. Brian Andrew [BrianAn] 01-July-1995
  10. Revision History:
  11. // @@END_DDKSPLIT
  12. --*/
  13. #include "CdProcs.h"
  14. //
  15. // The Bug check file id for this module
  16. //
  17. #define BugCheckFileId (CDFS_BUG_CHECK_RESRCSUP)
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text(PAGE, CdAcquireForCache)
  20. #pragma alloc_text(PAGE, CdAcquireForCreateSection)
  21. #pragma alloc_text(PAGE, CdAcquireResource)
  22. #pragma alloc_text(PAGE, CdNoopAcquire)
  23. #pragma alloc_text(PAGE, CdNoopRelease)
  24. #pragma alloc_text(PAGE, CdReleaseForCreateSection)
  25. #pragma alloc_text(PAGE, CdReleaseFromCache)
  26. #endif
  27. BOOLEAN
  28. CdAcquireResource (
  29. IN PIRP_CONTEXT IrpContext,
  30. IN PERESOURCE Resource,
  31. IN BOOLEAN IgnoreWait,
  32. IN TYPE_OF_ACQUIRE Type
  33. )
  34. /*++
  35. Routine Description:
  36. This is the single routine used to acquire file system resources. It
  37. looks at the IgnoreWait flag to determine whether to try to acquire the
  38. resource without waiting. Returning TRUE/FALSE to indicate success or
  39. failure. Otherwise it is driven by the WAIT flag in the IrpContext and
  40. will raise CANT_WAIT on a failure.
  41. Arguments:
  42. Resource - This is the resource to try and acquire.
  43. IgnoreWait - If TRUE then this routine will not wait to acquire the
  44. resource and will return a boolean indicating whether the resource was
  45. acquired. Otherwise we use the flag in the IrpContext and raise
  46. if the resource is not acquired.
  47. Type - Indicates how we should try to get the resource.
  48. Return Value:
  49. BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and
  50. IgnoreWait is specified. Otherwise we raise CANT_WAIT.
  51. --*/
  52. {
  53. BOOLEAN Wait = FALSE;
  54. BOOLEAN Acquired;
  55. PAGED_CODE();
  56. //
  57. // We look first at the IgnoreWait flag, next at the flag in the Irp
  58. // Context to decide how to acquire this resource.
  59. //
  60. if (!IgnoreWait && FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
  61. Wait = TRUE;
  62. }
  63. //
  64. // Attempt to acquire the resource either shared or exclusively.
  65. //
  66. switch (Type) {
  67. case AcquireExclusive:
  68. Acquired = ExAcquireResourceExclusiveLite( Resource, Wait );
  69. break;
  70. case AcquireShared:
  71. Acquired = ExAcquireResourceSharedLite( Resource, Wait );
  72. break;
  73. case AcquireSharedStarveExclusive:
  74. Acquired = ExAcquireSharedStarveExclusive( Resource, Wait );
  75. break;
  76. default:
  77. Acquired = FALSE;
  78. ASSERT( FALSE );
  79. }
  80. //
  81. // If not acquired and the user didn't specifiy IgnoreWait then
  82. // raise CANT_WAIT.
  83. //
  84. if (!Acquired && !IgnoreWait) {
  85. CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
  86. }
  87. return Acquired;
  88. }
  89. BOOLEAN
  90. CdAcquireForCache (
  91. IN PFCB Fcb,
  92. IN BOOLEAN Wait
  93. )
  94. /*++
  95. Routine Description:
  96. The address of this routine is specified when creating a CacheMap for
  97. a file. It is subsequently called by the Lazy Writer for synchronization.
  98. Arguments:
  99. Fcb - The pointer supplied as context to the cache initialization
  100. routine.
  101. Wait - TRUE if the caller is willing to block.
  102. Return Value:
  103. None
  104. --*/
  105. {
  106. PAGED_CODE();
  107. ASSERT(IoGetTopLevelIrp() == NULL);
  108. IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
  109. return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
  110. }
  111. VOID
  112. CdReleaseFromCache (
  113. IN PFCB Fcb
  114. )
  115. /*++
  116. Routine Description:
  117. The address of this routine is specified when creating a CacheMap for
  118. a virtual file. It is subsequently called by the Lazy Writer to release
  119. a resource acquired above.
  120. Arguments:
  121. Fcb - The pointer supplied as context to the cache initialization
  122. routine.
  123. Return Value:
  124. None
  125. --*/
  126. {
  127. PAGED_CODE();
  128. ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
  129. IoSetTopLevelIrp( NULL );
  130. ExReleaseResourceLite( Fcb->Resource );
  131. }
  132. BOOLEAN
  133. CdNoopAcquire (
  134. IN PVOID Fcb,
  135. IN BOOLEAN Wait
  136. )
  137. /*++
  138. Routine Description:
  139. This routine does nothing.
  140. Arguments:
  141. Fcb - The Fcb/Vcb which was specified as a context parameter for this
  142. routine.
  143. Wait - TRUE if the caller is willing to block.
  144. Return Value:
  145. TRUE
  146. --*/
  147. {
  148. PAGED_CODE();
  149. return TRUE;
  150. }
  151. VOID
  152. CdNoopRelease (
  153. IN PVOID Fcb
  154. )
  155. /*++
  156. Routine Description:
  157. This routine does nothing.
  158. Arguments:
  159. Fcb - The Fcb/Vcb which was specified as a context parameter for this
  160. routine.
  161. Return Value:
  162. None
  163. --*/
  164. {
  165. PAGED_CODE();
  166. }
  167. VOID
  168. CdAcquireForCreateSection (
  169. IN PFILE_OBJECT FileObject
  170. )
  171. /*++
  172. Routine Description:
  173. This is the callback routine for MM to use to acquire the file exclusively.
  174. Arguments:
  175. FileObject - File object for a Cdfs stream.
  176. Return Value:
  177. None
  178. --*/
  179. {
  180. PAGED_CODE();
  181. //
  182. // Get the Fcb resource exclusively.
  183. //
  184. ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource,
  185. TRUE );
  186. //
  187. // Take the File resource shared. We need this later on when MM calls
  188. // QueryStandardInfo to get the file size.
  189. //
  190. // If we don't use StarveExclusive, then we can get wedged behind an
  191. // exclusive waiter who is waiting on someone else holding it shared in the
  192. // read->initializecachemap path (which calls createsection) who is in turn
  193. // waiting on us to finish the create section.
  194. //
  195. ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource,
  196. TRUE );
  197. }
  198. VOID
  199. CdReleaseForCreateSection (
  200. IN PFILE_OBJECT FileObject
  201. )
  202. /*++
  203. Routine Description:
  204. This is the callback routine for MM to use to release a file acquired with
  205. the AcquireForCreateSection call above.
  206. Arguments:
  207. FileObject - File object for a Cdfs stream.
  208. Return Value:
  209. None
  210. --*/
  211. {
  212. PAGED_CODE();
  213. //
  214. // Release the resources.
  215. //
  216. ExReleaseResourceLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource );
  217. ExReleaseResourceLite( ((PFCB) FileObject->FsContext)->Resource);
  218. }