Revert "[CDFS_NEW] Use CdAcquireForCreateSection from the old driver in place of...
[reactos.git] / drivers / filesystems / cdfs_new / resrcsup.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 ResrcSup.c
8
9 Abstract:
10
11 This module implements the Cdfs Resource acquisition routines
12
13
14 --*/
15
16 #include "cdprocs.h"
17
18 //
19 // The Bug check file id for this module
20 //
21
22 #define BugCheckFileId (CDFS_BUG_CHECK_RESRCSUP)
23
24 #ifdef ALLOC_PRAGMA
25 #pragma alloc_text(PAGE, CdAcquireForCache)
26 #pragma alloc_text(PAGE, CdFilterCallbackAcquireForCreateSection)
27 #pragma alloc_text(PAGE, CdAcquireResource)
28 #pragma alloc_text(PAGE, CdNoopAcquire)
29 #pragma alloc_text(PAGE, CdNoopRelease)
30 #pragma alloc_text(PAGE, CdReleaseForCreateSection)
31 #pragma alloc_text(PAGE, CdReleaseFromCache)
32 #endif
33
34 \f
35
36 _Requires_lock_held_(_Global_critical_region_)
37 _When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
38 _When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
39 _When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
40 _When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
41 BOOLEAN
42 CdAcquireResource (
43 _In_ PIRP_CONTEXT IrpContext,
44 _Inout_ PERESOURCE Resource,
45 _In_ BOOLEAN IgnoreWait,
46 _In_ TYPE_OF_ACQUIRE Type
47 )
48
49 /*++
50
51 Routine Description:
52
53 This is the single routine used to acquire file system resources. It
54 looks at the IgnoreWait flag to determine whether to try to acquire the
55 resource without waiting. Returning TRUE/FALSE to indicate success or
56 failure. Otherwise it is driven by the WAIT flag in the IrpContext and
57 will raise CANT_WAIT on a failure.
58
59 Arguments:
60
61 Resource - This is the resource to try and acquire.
62
63 IgnoreWait - If TRUE then this routine will not wait to acquire the
64 resource and will return a boolean indicating whether the resource was
65 acquired. Otherwise we use the flag in the IrpContext and raise
66 if the resource is not acquired.
67
68 Type - Indicates how we should try to get the resource.
69
70 Return Value:
71
72 BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and
73 IgnoreWait is specified. Otherwise we raise CANT_WAIT.
74
75 --*/
76
77 {
78 BOOLEAN Wait = FALSE;
79 BOOLEAN Acquired;
80 PAGED_CODE();
81
82 //
83 // We look first at the IgnoreWait flag, next at the flag in the Irp
84 // Context to decide how to acquire this resource.
85 //
86
87 if (!IgnoreWait && FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
88
89 Wait = TRUE;
90 }
91
92 //
93 // Attempt to acquire the resource either shared or exclusively.
94 //
95
96 switch (Type) {
97 case AcquireExclusive:
98
99 #ifdef _MSC_VER
100 #pragma prefast( suppress:28137, "prefast believes Wait should be a constant, but this is ok for CDFS" )
101 #endif
102 Acquired = ExAcquireResourceExclusiveLite( Resource, Wait );
103 break;
104
105 case AcquireShared:
106
107 Acquired = ExAcquireResourceSharedLite( Resource, Wait );
108 break;
109
110 case AcquireSharedStarveExclusive:
111
112 Acquired = ExAcquireSharedStarveExclusive( Resource, Wait );
113 break;
114
115 default:
116 Acquired = FALSE;
117 NT_ASSERT( FALSE );
118 }
119
120 //
121 // If not acquired and the user didn't specifiy IgnoreWait then
122 // raise CANT_WAIT.
123 //
124
125 if (!Acquired && !IgnoreWait) {
126
127 CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
128 }
129
130 return Acquired;
131 }
132
133 \f
134
135 _Requires_lock_held_(_Global_critical_region_)
136 _When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
137 BOOLEAN
138 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
139 CdAcquireForCache (
140 _Inout_ PFCB Fcb,
141 _In_ BOOLEAN Wait
142 )
143
144 /*++
145
146 Routine Description:
147
148 The address of this routine is specified when creating a CacheMap for
149 a file. It is subsequently called by the Lazy Writer for synchronization.
150
151 Arguments:
152
153 Fcb - The pointer supplied as context to the cache initialization
154 routine.
155
156 Wait - TRUE if the caller is willing to block.
157
158 Return Value:
159
160 None
161
162 --*/
163
164 {
165 PAGED_CODE();
166
167 NT_ASSERT(IoGetTopLevelIrp() == NULL);
168 IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
169
170 return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
171 }
172
173 \f
174 _Requires_lock_held_(_Global_critical_region_)
175 _Releases_lock_(*Fcb->Resource)
176 VOID
177 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
178 CdReleaseFromCache (
179 _Inout_ PFCB Fcb
180 )
181
182 /*++
183
184 Routine Description:
185
186 The address of this routine is specified when creating a CacheMap for
187 a virtual file. It is subsequently called by the Lazy Writer to release
188 a resource acquired above.
189
190 Arguments:
191
192 Fcb - The pointer supplied as context to the cache initialization
193 routine.
194
195 Return Value:
196
197 None
198
199 --*/
200
201 {
202 PAGED_CODE();
203
204 NT_ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
205 IoSetTopLevelIrp( NULL );
206
207 ExReleaseResourceLite( Fcb->Resource );
208 }
209
210 \f
211 BOOLEAN
212 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
213 CdNoopAcquire (
214 _In_ PVOID Fcb,
215 _In_ BOOLEAN Wait
216 )
217
218 /*++
219
220 Routine Description:
221
222 This routine does nothing.
223
224 Arguments:
225
226 Fcb - The Fcb/Vcb which was specified as a context parameter for this
227 routine.
228
229 Wait - TRUE if the caller is willing to block.
230
231 Return Value:
232
233 TRUE
234
235 --*/
236
237 {
238 PAGED_CODE();
239
240 UNREFERENCED_PARAMETER( Fcb );
241 UNREFERENCED_PARAMETER( Wait );
242
243 return TRUE;
244 }
245
246 \f
247 VOID
248 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
249 CdNoopRelease (
250 _In_ PVOID Fcb
251 )
252
253 /*++
254
255 Routine Description:
256
257 This routine does nothing.
258
259 Arguments:
260
261 Fcb - The Fcb/Vcb which was specified as a context parameter for this
262 routine.
263
264 Return Value:
265
266 None
267
268 --*/
269
270 {
271 PAGED_CODE();
272
273 UNREFERENCED_PARAMETER( Fcb );
274 }
275
276
277 _Requires_lock_held_(_Global_critical_region_)
278 NTSTATUS
279 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
280 CdFilterCallbackAcquireForCreateSection (
281 _In_ PFS_FILTER_CALLBACK_DATA CallbackData,
282 _Unreferenced_parameter_ PVOID *CompletionContext
283 )
284
285 /*++
286
287 Routine Description:
288
289 This is the callback routine for MM to use to acquire the file exclusively.
290
291 Arguments:
292
293 FS_FILTER_CALLBACK_DATA - Filter based callback data that provides the file object we
294 want to acquire.
295
296 CompletionContext - Ignored.
297
298 Return Value:
299
300 On success we return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
301
302 If SyncType is SyncTypeCreateSection, we return a status that indicates there are no
303 writers to this file.
304
305 --*/
306
307 {
308 PFILE_OBJECT FileObject;
309
310
311 PAGED_CODE();
312
313 NT_ASSERT( CallbackData->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION );
314 NT_ASSERT( CallbackData->SizeOfFsFilterCallbackData == sizeof(FS_FILTER_CALLBACK_DATA) );
315
316 //
317 // Get the file object from the callback data.
318 //
319
320 FileObject = CallbackData->FileObject;
321
322 //
323 // Get the Fcb resource exclusively.
324 //
325
326 ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource,
327 TRUE );
328
329 //
330 // Take the File resource shared. We need this later on when MM calls
331 // QueryStandardInfo to get the file size.
332 //
333 // If we don't use StarveExclusive, then we can get wedged behind an
334 // exclusive waiter who is waiting on someone else holding it shared in the
335 // read->initializecachemap path (which calls createsection) who is in turn
336 // waiting on us to finish the create section.
337 //
338
339 ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource,
340 TRUE );
341
342 //
343 // CDFS is a read-only file system, so we can always indicate no writers.
344 // We only do this for create section synchronization. For others we
345 // return the generic success STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
346 //
347
348 if (CallbackData->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection) {
349
350 return STATUS_FILE_LOCKED_WITH_ONLY_READERS;
351
352 } else {
353
354 return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY;
355 }
356
357 UNREFERENCED_PARAMETER( CompletionContext );
358 }
359
360 \f
361 _Function_class_(FAST_IO_RELEASE_FILE)
362 _Requires_lock_held_(_Global_critical_region_)
363 VOID
364 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
365 CdReleaseForCreateSection (
366 _In_ PFILE_OBJECT FileObject
367 )
368
369 /*++
370
371 Routine Description:
372
373 This is the callback routine for MM to use to release a file acquired with
374 the AcquireForCreateSection call above.
375
376 Arguments:
377
378 FileObject - File object for a Cdfs stream.
379
380 Return Value:
381
382 None
383
384 --*/
385
386 {
387 PAGED_CODE();
388
389 //
390 // Release the resources.
391 //
392
393 ExReleaseResourceLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource );
394 ExReleaseResourceLite( ((PFCB) FileObject->FsContext)->Resource);
395 }
396