ReactOS  0.4.14-dev-49-gfb4591c
close.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  Close.c
8 
9 Abstract:
10 
11  This module implements the File Close routine for Cdfs called by the
12  Fsd/Fsp dispatch routines.
13 
14  The close operation interacts with both the async and delayed close queues
15  in the CdData structure. Since close may be called recursively we may
16  violate the locking order in acquiring the Vcb or Fcb. In this case
17  we may move the request to the async close queue. If this is the last
18  reference on the Fcb and there is a chance the user may reopen this
19  file again soon we would like to defer the close. In this case we
20  may move the request to the async close queue.
21 
22  Once we are past the decode file operation there is no need for the
23  file object. If we are moving the request to either of the work
24  queues then we remember all of the information from the file object and
25  complete the request with STATUS_SUCCESS. The Io system can then
26  reuse the file object and we can complete the request when convenient.
27 
28  The async close queue consists of requests which we would like to
29  complete as soon as possible. They are queued using the original
30  IrpContext where some of the fields have been overwritten with
31  information from the file object. We will extract this information,
32  cleanup the IrpContext and then call the close worker routine.
33 
34  The delayed close queue consists of requests which we would like to
35  defer the close for. We keep size of this list within a range
36  determined by the size of the system. We let it grow to some maximum
37  value and then shrink to some minimum value. We allocate a small
38  structure which contains the key information from the file object
39  and use this information along with an IrpContext on the stack
40  to complete the request.
41 
42 
43 --*/
44 
45 #include "cdprocs.h"
46 
47 //
48 // The Bug check file id for this module
49 //
50 
51 #define BugCheckFileId (CDFS_BUG_CHECK_CLOSE)
52 
53 //
54 // Local support routines
55 //
56 
57 _Requires_lock_held_(_Global_critical_region_)
58 BOOLEAN
59 CdCommonClosePrivate (
60  _In_ PIRP_CONTEXT IrpContext,
61  _In_ PVCB Vcb,
62  _In_ PFCB Fcb,
63  _In_ ULONG UserReference,
64  _In_ BOOLEAN FromFsd
65  );
66 
67 VOID
69  _In_ PIRP_CONTEXT IrpContext,
70  _In_ PFCB Fcb,
71  _In_ ULONG UserReference,
72  _In_ BOOLEAN DelayedClose
73  );
74 
78  );
79 
80 // Tell prefast this is a workitem routine
81 IO_WORKITEM_ROUTINE CdCloseWorker;
82 
83 VOID
84 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
88  );
89 
90 #ifdef ALLOC_PRAGMA
91 #pragma alloc_text(PAGE, CdFspClose)
92 #pragma alloc_text(PAGE, CdCommonClose)
93 #pragma alloc_text(PAGE, CdCommonClosePrivate)
94 #pragma alloc_text(PAGE, CdQueueClose)
95 #pragma alloc_text(PAGE, CdRemoveClose)
96 #pragma alloc_text(PAGE, CdCloseWorker)
97 #endif
98 
99 
100 VOID
101 CdFspClose (
103  )
104 
105 /*++
106 
107 Routine Description:
108 
109  This routine is called to process the close queues in the CdData. If the
110  Vcb is passed then we want to remove all of the closes for this Vcb.
111  Otherwise we will do as many of the delayed closes as we need to do.
112 
113 Arguments:
114 
115  Vcb - If specified then we are looking for all of the closes for the
116  given Vcb.
117 
118 Return Value:
119 
120  None
121 
122 --*/
123 
124 {
125  PIRP_CONTEXT IrpContext;
126  IRP_CONTEXT StackIrpContext;
127 
128  THREAD_CONTEXT ThreadContext = {0};
129 
130  PFCB Fcb;
131  ULONG UserReference;
132 
133  ULONG VcbHoldCount = 0;
134  PVCB CurrentVcb = NULL;
135 
136  BOOLEAN PotentialVcbTeardown = FALSE;
137 
138  PAGED_CODE();
139 
141 
142  //
143  // Continue processing until there are no more closes to process.
144  //
145 
146  while ((IrpContext = CdRemoveClose( Vcb )) != NULL) {
147 
148  //
149  // If we don't have an IrpContext then use the one on the stack.
150  // Initialize it for this request.
151  //
152 
153  if (SafeNodeType( IrpContext ) != CDFS_NTC_IRP_CONTEXT ) {
154 
155  //
156  // Update the local values from the IrpContextLite.
157  //
158 
159  Fcb = ((PIRP_CONTEXT_LITE) IrpContext)->Fcb;
160  UserReference = ((PIRP_CONTEXT_LITE) IrpContext)->UserReference;
161 
162  //
163  // Update the stack irp context with the values from the
164  // IrpContextLite.
165  //
166 
167  CdInitializeStackIrpContext( &StackIrpContext,
168  (PIRP_CONTEXT_LITE) IrpContext );
169 
170  //
171  // Free the IrpContextLite.
172  //
173 
174  CdFreeIrpContextLite( *(PVOID*)&IrpContext ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */
175 
176  //
177  // Remember we have the IrpContext from the stack.
178  //
179 
180  IrpContext = &StackIrpContext;
181 
182  //
183  // Otherwise cleanup the existing IrpContext.
184  //
185 
186  } else {
187 
188  //
189  // Remember the Fcb and user reference count.
190  //
191 
192  Fcb = (PFCB) IrpContext->Irp;
193  IrpContext->Irp = NULL;
194 
195  UserReference = (ULONG) IrpContext->ExceptionStatus;
196  IrpContext->ExceptionStatus = STATUS_SUCCESS;
197  }
198 
199  _Analysis_assume_(Fcb != NULL && Fcb->Vcb != NULL);
200 
201  //
202  // We have an IrpContext. Now we need to set the top level thread
203  // context.
204  //
205 
206  SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS );
207 
208  //
209  // If we were given a Vcb then there is a request on top of this.
210  //
211 
212  if (ARGUMENT_PRESENT( Vcb )) {
213 
214  ClearFlag( IrpContext->Flags,
216  }
217 
218  CdSetThreadContext( IrpContext, &ThreadContext );
219 
220  //
221  // If we have hit the maximum number of requests to process without
222  // releasing the Vcb then release the Vcb now. If we are holding
223  // a different Vcb to this one then release the previous Vcb.
224  //
225  // In either case acquire the current Vcb.
226  //
227  // We use the MinDelayedCloseCount from the CdData since it is
228  // a convenient value based on the system size. Only thing we are trying
229  // to do here is prevent this routine starving other threads which
230  // may need this Vcb exclusively.
231  //
232  // Note that the check for potential teardown below is unsafe. We'll
233  // repeat later within the cddata lock.
234  //
235 
236  PotentialVcbTeardown = !ARGUMENT_PRESENT( Vcb ) &&
237  (Fcb->Vcb->VcbCondition != VcbMounted) &&
239  (Fcb->Vcb->VcbCleanup == 0);
240 
241  if (PotentialVcbTeardown ||
242  (VcbHoldCount > CdData.MinDelayedCloseCount) ||
243  (Fcb->Vcb != CurrentVcb)) {
244 
245  if (CurrentVcb != NULL) {
246 
247  CdReleaseVcb( IrpContext, CurrentVcb );
248  }
249 
250  if (PotentialVcbTeardown) {
251 
252  CdAcquireCdData( IrpContext );
253 
254  //
255  // Repeat the checks with global lock held. The volume could have
256  // been remounted while we didn't hold the lock.
257  //
258 
259  PotentialVcbTeardown = !ARGUMENT_PRESENT( Vcb ) &&
260  (Fcb->Vcb->VcbCondition != VcbMounted) &&
262  (Fcb->Vcb->VcbCleanup == 0);
263 
264  if (!PotentialVcbTeardown) {
265 
266  CdReleaseCdData( IrpContext);
267  }
268  }
269 
270  CurrentVcb = Fcb->Vcb;
271 
272  _Analysis_assume_( CurrentVcb != NULL );
273 
274  CdAcquireVcbShared( IrpContext, CurrentVcb, FALSE );
275 
276  VcbHoldCount = 0;
277 
278  } else {
279 
280  VcbHoldCount += 1;
281  }
282 
283  //
284  // Call our worker routine to perform the close operation.
285  //
286 
287  CdCommonClosePrivate( IrpContext, CurrentVcb, Fcb, UserReference, FALSE );
288 
289  //
290  // If the reference count on this Vcb is below our residual reference
291  // then check if we should dismount the volume.
292  //
293 
294  if (PotentialVcbTeardown) {
295 
296  CdReleaseVcb( IrpContext, CurrentVcb );
297  CdCheckForDismount( IrpContext, CurrentVcb, FALSE );
298 
299  CurrentVcb = NULL;
300 
301  CdReleaseCdData( IrpContext );
302  PotentialVcbTeardown = FALSE;
303  }
304 
305  //
306  // Complete the current request to cleanup the IrpContext.
307  //
308 
309  CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
310  }
311 
312  //
313  // Release any Vcb we may still hold.
314  //
315 
316  if (CurrentVcb != NULL) {
317 
318  CdReleaseVcb( IrpContext, CurrentVcb );
319 
320  }
321 
322 #ifdef _MSC_VER
323 #pragma prefast(suppress:26165, "Esp:1153")
324 #endif
326 }
327 
328 _Requires_lock_held_(_Global_critical_region_)
329 NTSTATUS
330 CdCommonClose (
331  _Inout_ PIRP_CONTEXT IrpContext,
333  )
334 
335 /*++
336 
337 Routine Description:
338 
339  This routine is the Fsd entry for the close operation. We decode the file
340  object to find the CDFS structures and type of open. We call our internal
341  worker routine to perform the actual work. If the work wasn't completed
342  then we post to one of our worker queues. The Ccb isn't needed after this
343  point so we delete the Ccb and return STATUS_SUCCESS to our caller in all
344  cases.
345 
346 Arguments:
347 
348  Irp - Supplies the Irp to process
349 
350 Return Value:
351 
352  STATUS_SUCCESS
353 
354 --*/
355 
356 {
358 
359  PVCB Vcb;
360  PFCB Fcb;
361  PCCB Ccb;
362  ULONG UserReference = 0;
363 
364  BOOLEAN PotentialVcbTeardown = FALSE;
365 
366  PAGED_CODE();
367 
368  ASSERT_IRP_CONTEXT( IrpContext );
369  ASSERT_IRP( Irp );
370 
371  //
372  // If we were called with our file system device object instead of a
373  // volume device object, just complete this request with STATUS_SUCCESS.
374  //
375 
376  if (IrpContext->Vcb == NULL) {
377 
378  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
379  return STATUS_SUCCESS;
380  }
381 
382  //
383  // Decode the file object to get the type of open and Fcb/Ccb.
384  //
385 
386  TypeOfOpen = CdDecodeFileObject( IrpContext,
388  &Fcb,
389  &Ccb );
390 
391  //
392  // No work to do for unopened file objects.
393  //
394 
396 
397  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
398 
399  return STATUS_SUCCESS;
400  }
401 
402  Vcb = Fcb->Vcb;
403 
404  //
405  // Clean up any CCB associated with this open.
406  //
407 
408  if (Ccb != NULL) {
409 
410  UserReference = 1;
411 
412  //
413  // We can always deallocate the Ccb if present.
414  //
415 
416  CdDeleteCcb( IrpContext, Ccb );
417  }
418 
419  //
420  // If this is the last reference to a user file or directory on a
421  // currently mounted volume, then post it to the delayed close queue. Note
422  // that the VcbCondition check is unsafe, but it doesn't really matter -
423  // we just might delay the volume teardown a little by posting this close.
424  //
425 
426  if ((Vcb->VcbCondition == VcbMounted) &&
427  (Fcb->FcbReference == 1) &&
428  ((TypeOfOpen == UserFileOpen) ||
430 
431  CdQueueClose( IrpContext, Fcb, UserReference, TRUE );
432  IrpContext = NULL;
433 
434  //
435  // Otherwise try to process this close. Post to the async close queue
436  // if we can't acquire all of the resources.
437  //
438 
439  }
440  else {
441 
442  //
443  // If we may be dismounting this volume then acquire the CdData
444  // resource.
445  //
446  // Since we now must make volumes go away as soon as reasonable after
447  // the last user handles closes, key off of the cleanup count. It is
448  // OK to do this more than neccesary. Since this Fcb could be holding
449  // a number of other Fcbs (and thus their references), a simple check
450  // on reference count is not appropriate.
451  //
452  // Do an unsafe check first to avoid taking the (global) cddata lock in the
453  // common case.
454  //
455 
456  if ((Vcb->VcbCleanup == 0) &&
457  (Vcb->VcbCondition != VcbMounted)) {
458 
459  //
460  // Possible dismount. Acquire CdData to synchronise with the remount path
461  // before looking at the vcb condition again.
462  //
463 
464  CdAcquireCdData( IrpContext );
465 
466  if ((Vcb->VcbCleanup == 0) &&
467  (Vcb->VcbCondition != VcbMounted) &&
468  (Vcb->VcbCondition != VcbMountInProgress) &&
469  FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS )) {
470 
471  PotentialVcbTeardown = TRUE;
472  }
473  else {
474 
475  //
476  // We can't dismount this volume now, there are other references or
477  // it's just been remounted.
478  //
479  }
480 
481  //
482  // Drop the global lock if we don't need it anymore.
483  //
484 
485  if (!PotentialVcbTeardown) {
486 
487  CdReleaseCdData( IrpContext );
488  }
489  }
490 
491  //
492  // Call the worker routine to perform the actual work. This routine
493  // should never raise except for a fatal error.
494  //
495 
496  if (!CdCommonClosePrivate( IrpContext, Vcb, Fcb, UserReference, TRUE )) {
497 
498  //
499  // If we didn't complete the request then post the request as needed.
500  //
501 
502  CdQueueClose( IrpContext, Fcb, UserReference, FALSE );
503  IrpContext = NULL;
504 
505  //
506  // Check whether we should be dismounting the volume and then complete
507  // the request.
508  //
509 
510  }
511  else if (PotentialVcbTeardown) {
512 
513  CdCheckForDismount( IrpContext, Vcb, FALSE );
514  }
515  }
516 
517  //
518  // Always complete this request with STATUS_SUCCESS.
519  //
520 
521  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
522 
523  if (PotentialVcbTeardown) {
524 
525  CdReleaseCdData( IrpContext );
526  }
527 
528  //
529  // Always return STATUS_SUCCESS for closes.
530  //
531 
532  return STATUS_SUCCESS;
533 }
534 
535 
536 //
537 // Local support routine
538 //
539 
540 _Requires_lock_held_(_Global_critical_region_)
541 BOOLEAN
542 CdCommonClosePrivate (
543  _In_ PIRP_CONTEXT IrpContext,
544  _In_ PVCB Vcb,
545  _In_ PFCB Fcb,
546  _In_ ULONG UserReference,
547  _In_ BOOLEAN FromFsd
548  )
549 
550 /*++
551 
552 Routine Description:
553 
554  This is the worker routine for the close operation. We can be called in
555  an Fsd thread or from a worker Fsp thread. If called from the Fsd thread
556  then we acquire the resources without waiting. Otherwise we know it is
557  safe to wait.
558 
559  We check to see whether we should post this request to the delayed close
560  queue. If we are to process the close here then we acquire the Vcb and
561  Fcb. We will adjust the counts and call our teardown routine to see
562  if any of the structures should go away.
563 
564 Arguments:
565 
566  Vcb - Vcb for this volume.
567 
568  Fcb - Fcb for this request.
569 
570  UserReference - Number of user references for this file object. This is
571  zero for an internal stream.
572 
573  FromFsd - This request was called from an Fsd thread. Indicates whether
574  we should wait to acquire resources.
575 
576  DelayedClose - Address to store whether we should try to put this on
577  the delayed close queue. Ignored if this routine can process this
578  close.
579 
580 Return Value:
581 
582  BOOLEAN - TRUE if this thread processed the close, FALSE otherwise.
583 
584 --*/
585 
586 {
587  BOOLEAN RemovedFcb;
588 
589  PAGED_CODE();
590 
591  ASSERT_IRP_CONTEXT( IrpContext );
592  ASSERT_FCB( Fcb );
593 
594  //
595  // Try to acquire the Vcb and Fcb. If we can't acquire them then return
596  // and let our caller know he should post the request to the async
597  // queue.
598  //
599 
600  if (CdAcquireVcbShared( IrpContext, Vcb, FromFsd )) {
601 
602  if (!CdAcquireFcbExclusive( IrpContext, Fcb, FromFsd )) {
603 
604  //
605  // We couldn't get the Fcb. Release the Vcb and let our caller
606  // know to post this request.
607  //
608 
609  CdReleaseVcb( IrpContext, Vcb );
610  return FALSE;
611  }
612 
613  //
614  // We didn't get the Vcb. Let our caller know to post this request.
615  //
616 
617  } else {
618 
619  return FALSE;
620  }
621 
622  //
623  // Lock the Vcb and decrement the reference counts.
624  //
625 
626  CdLockVcb( IrpContext, Vcb );
627  CdDecrementReferenceCounts( IrpContext, Fcb, 1, UserReference );
628  CdUnlockVcb( IrpContext, Vcb );
629 
630  //
631  // Call our teardown routine to see if this object can go away.
632  // If we don't remove the Fcb then release it.
633  //
634 
635  CdTeardownStructures( IrpContext, Fcb, &RemovedFcb );
636 
637  if (!RemovedFcb) {
638 
639  CdReleaseFcb( IrpContext, Fcb );
640  }
641  else {
643  }
644 
645  //
646  // Release the Vcb and return to our caller. Let him know we completed
647  // this request.
648  //
649 
650  CdReleaseVcb( IrpContext, Vcb );
651 
652  return TRUE;
653 }
654 
655 VOID
656 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
660  )
661 /*++
662 
663 Routine Description:
664 
665  Worker routine to call CsFspClose.
666 
667 Arguments:
668 
669  DeviceObject - Filesystem registration device object
670 
671  Context - Callers context
672 
673 Return Value:
674 
675  None
676 
677 --*/
678 
679 {
680  PAGED_CODE();
681 
684 
685  CdFspClose (NULL);
686 }
687 
688 
689 VOID
691  _In_ PIRP_CONTEXT IrpContext,
692  _In_ PFCB Fcb,
693  _In_ ULONG UserReference,
694  _In_ BOOLEAN DelayedClose
695  )
696 
697 /*++
698 
699 Routine Description:
700 
701  This routine is called to queue a request to either the async or delayed
702  close queue. For the delayed queue we need to allocate a smaller
703  structure to contain the information about the file object. We do
704  that so we don't put the larger IrpContext structures into this long
705  lived queue. If we can allocate this structure then we put this
706  on the async queue instead.
707 
708 Arguments:
709 
710  Fcb - Fcb for this file object.
711 
712  UserReference - Number of user references for this file object. This is
713  zero for an internal stream.
714 
715  DelayedClose - Indicates whether this should go on the async or delayed
716  close queue.
717 
718 Return Value:
719 
720  None
721 
722 --*/
723 
724 {
725  PIRP_CONTEXT_LITE IrpContextLite = NULL;
726  BOOLEAN StartWorker = FALSE;
727 
728  PAGED_CODE();
729 
730  ASSERT_IRP_CONTEXT( IrpContext );
731  ASSERT_FCB( Fcb );
732 
733  //
734  // Start with the delayed queue request. We can move this to the async
735  // queue if there is an allocation failure.
736  //
737 
738  if (DelayedClose) {
739 
740  //
741  // Try to allocate non-paged pool for the IRP_CONTEXT_LITE.
742  //
743 
744  IrpContextLite = CdCreateIrpContextLite( IrpContext );
745  }
746 
747  //
748  // We want to clear the top level context in this thread if
749  // necessary. Call our cleanup routine to do the work.
750  //
751 
752  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
753  CdCleanupIrpContext( IrpContext, TRUE );
754 
755  //
756  // Synchronize with the CdData lock.
757  //
758 
759  CdLockCdData();
760 
761  //
762  // If we have an IrpContext then put the request on the delayed close queue.
763  //
764 
765  if (IrpContextLite != NULL) {
766 
767  //
768  // Initialize the IrpContextLite.
769  //
770 
771  IrpContextLite->NodeTypeCode = CDFS_NTC_IRP_CONTEXT_LITE;
772  IrpContextLite->NodeByteSize = sizeof( IRP_CONTEXT_LITE );
773  IrpContextLite->Fcb = Fcb;
774  IrpContextLite->UserReference = UserReference;
775  IrpContextLite->RealDevice = IrpContext->RealDevice;
776 
777  //
778  // Add this to the delayed close list and increment
779  // the count.
780  //
781 
783  &IrpContextLite->DelayedCloseLinks );
784 
786 
787  //
788  // If we are above our threshold then start the delayed
789  // close operation.
790  //
791 
793 
795 
796  if (!CdData.FspCloseActive) {
797 
799  StartWorker = TRUE;
800  }
801  }
802 
803  //
804  // Unlock the CdData.
805  //
806 
807  CdUnlockCdData();
808 
809  //
810  // Cleanup the IrpContext.
811  //
812 
813  CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
814 
815  //
816  // Otherwise drop into the async case below.
817  //
818 
819  } else {
820 
821  //
822  // Store the information about the file object into the IrpContext.
823  //
824 
825  IrpContext->Irp = (PIRP) Fcb;
826  IrpContext->ExceptionStatus = (NTSTATUS) UserReference;
827 
828  //
829  // Add this to the async close list and increment the count.
830  //
831 
833  &IrpContext->WorkQueueItem.List );
834 
835  CdData.AsyncCloseCount += 1;
836 
837  //
838  // Remember to start the Fsp close thread if not currently started.
839  //
840 
841  if (!CdData.FspCloseActive) {
842 
844 
845  StartWorker = TRUE;
846  }
847 
848  //
849  // Unlock the CdData.
850  //
851 
852  CdUnlockCdData();
853  }
854 
855  //
856  // Start the FspClose thread if we need to.
857  //
858 
859  if (StartWorker) {
860 
862  }
863 
864  //
865  // Return to our caller.
866  //
867 
868  return;
869 }
870 
871 
872 //
873 // Local support routine
874 //
875 
879  )
880 
881 /*++
882 
883 Routine Description:
884 
885 Arguments:
886 
887  This routine is called to scan the async and delayed close queues looking
888  for a suitable entry. If the Vcb is specified then we scan both queues
889  looking for an entry with the same Vcb. Otherwise we will look in the
890  async queue first for any close item. If none found there then we look
891  in the delayed close queue provided that we have triggered the delayed
892  close operation.
893 
894 Return Value:
895 
896  PIRP_CONTEXT - NULL if no work item found. Otherwise it is the pointer to
897  either the IrpContext or IrpContextLite for this request.
898 
899 --*/
900 
901 {
902  PIRP_CONTEXT IrpContext = NULL;
903  PIRP_CONTEXT NextIrpContext;
904  PIRP_CONTEXT_LITE NextIrpContextLite;
905 
907 
908  PAGED_CODE();
909 
911 
912  //
913  // Lock the CdData to perform the scan.
914  //
915 
916  CdLockCdData();
917 
918  //
919  // First check the list of async closes.
920  //
921 
923 
924  while (Entry != &CdData.AsyncCloseQueue) {
925 
926  //
927  // Extract the IrpContext.
928  //
929 
930  NextIrpContext = CONTAINING_RECORD( Entry,
931  IRP_CONTEXT,
932  WorkQueueItem.List );
933 
934  //
935  // If no Vcb was specified or this Vcb is for our volume
936  // then perform the close.
937  //
938 
939  if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContext->Vcb == Vcb)) {
940 
942  CdData.AsyncCloseCount -= 1;
943 
944  IrpContext = NextIrpContext;
945  break;
946  }
947 
948  //
949  // Move to the next entry.
950  //
951 
952  Entry = Entry->Flink;
953  }
954 
955  //
956  // If we didn't find anything look through the delayed close
957  // queue.
958  //
959  // We will only check the delayed close queue if we were given
960  // a Vcb or the delayed close operation is active.
961  //
962 
963  if ((IrpContext == NULL) &&
964  (ARGUMENT_PRESENT( Vcb ) ||
967 
969 
970  while (Entry != &CdData.DelayedCloseQueue) {
971 
972  //
973  // Extract the IrpContext.
974  //
975 
976  NextIrpContextLite = CONTAINING_RECORD( Entry,
978  DelayedCloseLinks );
979 
980  //
981  // If no Vcb was specified or this Vcb is for our volume
982  // then perform the close.
983  //
984 
985  if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContextLite->Fcb->Vcb == Vcb)) {
986 
989 
990  IrpContext = (PIRP_CONTEXT) NextIrpContextLite;
991  break;
992  }
993 
994  //
995  // Move to the next entry.
996  //
997 
998  Entry = Entry->Flink;
999  }
1000  }
1001 
1002  //
1003  // If the Vcb wasn't specified and we couldn't find an entry
1004  // then turn off the Fsp thread.
1005  //
1006 
1007  if (!ARGUMENT_PRESENT( Vcb ) && (IrpContext == NULL)) {
1008 
1011  }
1012 
1013  //
1014  // Unlock the CdData.
1015  //
1016 
1017  CdUnlockCdData();
1018 
1019  return IrpContext;
1020 }
1021 
1022 
1023 
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
ULONG MaxDelayedCloseCount
Definition: cdstruc.h:394
#define TRUE
Definition: types.h:120
#define FsRtlEnterFileSystem
#define CdAcquireVcbShared(IC, V, I)
Definition: cdprocs.h:987
NODE_BYTE_SIZE NodeByteSize
Definition: cdstruc.h:1287
LIST_ENTRY AsyncCloseQueue
Definition: cdstruc.h:382
ULONG UserReference
Definition: cdstruc.h:1305
struct _Entry Entry
Definition: kefuncs.h:640
PIRP Irp
Definition: usbstor.h:298
#define FsRtlExitFileSystem
IRP_CONTEXT * PIRP_CONTEXT
Definition: cdstruc.h:1217
_In_ PIRP Irp
Definition: csq.h:116
_Requires_lock_held_(_Global_critical_region_)
Definition: close.c:57
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
ULONG AsyncCloseCount
Definition: cdstruc.h:383
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1220
Definition: cdstruc.h:1073
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS
Definition: cdstruc.h:1224
#define CdReleaseFcb(IC, F)
Definition: cdprocs.h:1017
PDEVICE_OBJECT RealDevice
Definition: cdstruc.h:1311
Definition: cdstruc.h:504
#define InsertTailList(ListHead, Entry)
VOID CdInitializeStackIrpContext(_Out_ PIRP_CONTEXT IrpContext, _In_ PIRP_CONTEXT_LITE IrpContextLite)
Definition: strucsup.c:1839
#define ASSERT_FCB(F)
Definition: cddata.h:243
#define CdAcquireFcbExclusive(IC, F, I)
Definition: cdprocs.h:1011
#define PAGED_CODE()
Definition: video.h:57
#define _In_opt_
Definition: no_sal2.h:213
VOID CdFspClose(_In_opt_ PVCB Vcb)
VOID CdQueueClose(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ ULONG UserReference, _In_ BOOLEAN DelayedClose)
Definition: close.c:690
#define ASSERT_OPTIONAL_VCB(V)
Definition: cddata.h:242
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
PIO_WORKITEM CloseItem
Definition: cdstruc.h:422
VOID NTAPI CdCloseWorker(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
Definition: close.c:657
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define ASSERT_IRP_CONTEXT(IC)
Definition: cddata.h:249
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
struct _IRP_CONTEXT_LITE IRP_CONTEXT_LITE
#define IRP_CONTEXT_FSP_FLAGS
Definition: cdstruc.h:1267
__volatile LONG FcbReference
Definition: cdstruc.h:970
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PIRP_CONTEXT CdRemoveClose(_In_opt_ PVCB Vcb)
Definition: close.c:877
#define CdDecrementReferenceCounts(IC, F, C, UC)
Definition: cdprocs.h:1330
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
CD_DATA CdData
Definition: cddata.c:42
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:990
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1033
FCB * PFCB
Definition: cdstruc.h:1046
#define ARGUMENT_PRESENT(ArgumentPointer)
LIST_ENTRY DelayedCloseLinks
Definition: cdstruc.h:1299
#define Vcb
Definition: cdprocs.h:1425
#define CdLockCdData()
Definition: cdprocs.h:1020
#define _Inout_
Definition: no_sal2.h:244
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1028
VOID CdDeleteCcb(_In_ PIRP_CONTEXT IrpContext, _In_ __drv_freesMem(Pool) PCCB Ccb)
Definition: strucsup.c:1462
#define NTSTATUS
Definition: precomp.h:20
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define CdFreeIrpContextLite(ICL)
Definition: cdprocs.h:1257
#define CdAcquireCdData(IC)
Definition: cdprocs.h:978
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define CDFS_NTC_IRP_CONTEXT_LITE
Definition: nodetype.h:35
#define ASSERT_IRP(I)
Definition: cddata.h:251
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
VCB_CONDITION VcbCondition
Definition: cdstruc.h:547
ERESOURCE FcbResource
Definition: cdstruc.h:885
#define IRP_CONTEXT_FLAG_TOP_LEVEL
Definition: cdstruc.h:1223
struct _FCB::@693::@696 Fcb
ULONG DelayedCloseCount
Definition: cdstruc.h:393
LIST_ENTRY DelayedCloseQueue
Definition: cdstruc.h:392
#define CdReleaseCdData(IC)
Definition: cdprocs.h:981
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
#define CdCreateIrpContextLite(IC)
Definition: cdprocs.h:1254
BOOLEAN FspCloseActive
Definition: cdstruc.h:384
#define CDFS_NTC_IRP_CONTEXT
Definition: nodetype.h:34
BOOLEAN ReduceDelayedClose
Definition: cdstruc.h:385
PVOID PIRP
Definition: usb.h:38
unsigned int ULONG
Definition: retypes.h:1
IRP_CONTEXT_LITE * PIRP_CONTEXT_LITE
Definition: cdstruc.h:1314
PVCB Vcb
Definition: cdstruc.h:939
#define _Analysis_assume_lock_not_held_(lock)
Definition: no_sal2.h:683
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
PFCB_NONPAGED FcbNonpaged
Definition: cdstruc.h:1009
ULONG MinDelayedCloseCount
Definition: cdstruc.h:395
base of all file and directory entries
Definition: entries.h:82
#define CdUnlockCdData()
Definition: cdprocs.h:1024
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
ULONG VcbCleanup
Definition: cdstruc.h:557