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.

346 lines
6.8 KiB

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