3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the Cdfs Resource acquisition routines
19 // The Bug check file id for this module
22 #define BugCheckFileId (CDFS_BUG_CHECK_RESRCSUP)
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)
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
))
43 _In_ PIRP_CONTEXT IrpContext
,
44 _Inout_ PERESOURCE Resource
,
45 _In_ BOOLEAN IgnoreWait
,
46 _In_ TYPE_OF_ACQUIRE Type
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.
61 Resource - This is the resource to try and acquire.
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.
68 Type - Indicates how we should try to get the resource.
72 BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and
73 IgnoreWait is specified. Otherwise we raise CANT_WAIT.
83 // We look first at the IgnoreWait flag, next at the flag in the Irp
84 // Context to decide how to acquire this resource.
87 if (!IgnoreWait
&& FlagOn( IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
)) {
93 // Attempt to acquire the resource either shared or exclusively.
97 case AcquireExclusive
:
100 #pragma prefast( suppress:28137, "prefast believes Wait should be a constant, but this is ok for CDFS" )
102 Acquired
= ExAcquireResourceExclusiveLite( Resource
, Wait
);
107 Acquired
= ExAcquireResourceSharedLite( Resource
, Wait
);
110 case AcquireSharedStarveExclusive
:
112 Acquired
= ExAcquireSharedStarveExclusive( Resource
, Wait
);
121 // If not acquired and the user didn't specifiy IgnoreWait then
125 if (!Acquired
&& !IgnoreWait
) {
127 CdRaiseStatus( IrpContext
, STATUS_CANT_WAIT
);
135 _Requires_lock_held_(_Global_critical_region_
)
136 _When_(return!=0, _Acquires_shared_lock_(*Fcb
->Resource
))
138 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
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.
153 Fcb - The pointer supplied as context to the cache initialization
156 Wait - TRUE if the caller is willing to block.
167 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
172 NT_ASSERT(IoGetTopLevelIrp() == NULL
);
173 IoSetTopLevelIrp((PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
);
179 _Requires_lock_held_(_Global_critical_region_
)
180 _Releases_lock_(*Fcb
->Resource
)
182 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
191 The address of this routine is specified when creating a CacheMap for
192 a virtual file. It is subsequently called by the Lazy Writer to release
193 a resource acquired above.
197 Fcb - The pointer supplied as context to the cache initialization
209 NT_ASSERT(IoGetTopLevelIrp() == (PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
);
210 IoSetTopLevelIrp( NULL
);
212 ExReleaseResourceLite( Fcb
->Resource
);
217 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
227 This routine does nothing.
231 Fcb - The Fcb/Vcb which was specified as a context parameter for this
234 Wait - TRUE if the caller is willing to block.
245 UNREFERENCED_PARAMETER( Fcb
);
246 UNREFERENCED_PARAMETER( Wait
);
253 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
262 This routine does nothing.
266 Fcb - The Fcb/Vcb which was specified as a context parameter for this
278 UNREFERENCED_PARAMETER( Fcb
);
282 _Requires_lock_held_(_Global_critical_region_
)
284 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
285 CdFilterCallbackAcquireForCreateSection (
286 _In_ PFS_FILTER_CALLBACK_DATA CallbackData
,
287 _Unreferenced_parameter_ PVOID
*CompletionContext
294 This is the callback routine for MM to use to acquire the file exclusively.
298 FS_FILTER_CALLBACK_DATA - Filter based callback data that provides the file object we
301 CompletionContext - Ignored.
305 On success we return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
307 If SyncType is SyncTypeCreateSection, we return a status that indicates there are no
308 writers to this file.
313 PFILE_OBJECT FileObject
;
318 NT_ASSERT( CallbackData
->Operation
== FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
);
319 NT_ASSERT( CallbackData
->SizeOfFsFilterCallbackData
== sizeof(FS_FILTER_CALLBACK_DATA
) );
322 // Get the file object from the callback data.
325 FileObject
= CallbackData
->FileObject
;
328 // Get the Fcb resource exclusively.
331 ExAcquireResourceExclusiveLite( &((PFCB
) FileObject
->FsContext
)->FcbNonpaged
->FcbResource
,
335 // Take the File resource shared. We need this later on when MM calls
336 // QueryStandardInfo to get the file size.
338 // If we don't use StarveExclusive, then we can get wedged behind an
339 // exclusive waiter who is waiting on someone else holding it shared in the
340 // read->initializecachemap path (which calls createsection) who is in turn
341 // waiting on us to finish the create section.
344 ExAcquireSharedStarveExclusive( ((PFCB
) FileObject
->FsContext
)->Resource
,
348 // CDFS is a read-only file system, so we can always indicate no writers.
349 // We only do this for create section synchronization. For others we
350 // return the generic success STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
353 if (CallbackData
->Parameters
.AcquireForSectionSynchronization
.SyncType
== SyncTypeCreateSection
) {
355 return STATUS_FILE_LOCKED_WITH_ONLY_READERS
;
359 return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY
;
362 UNREFERENCED_PARAMETER( CompletionContext
);
366 _Function_class_(FAST_IO_RELEASE_FILE
)
367 _Requires_lock_held_(_Global_critical_region_
)
369 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
370 CdReleaseForCreateSection (
371 _In_ PFILE_OBJECT FileObject
378 This is the callback routine for MM to use to release a file acquired with
379 the AcquireForCreateSection call above.
383 FileObject - File object for a Cdfs stream.
395 // Release the resources.
398 ExReleaseResourceLite( &((PFCB
) FileObject
->FsContext
)->FcbNonpaged
->FcbResource
);
399 ExReleaseResourceLite( ((PFCB
) FileObject
->FsContext
)->Resource
);