Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

close.c File Reference

#include "UdfProcs.h"

Go to the source code of this file.

Defines

#define BugCheckFileId   (UDFS_BUG_CHECK_CLOSE)
#define Dbg   (UDFS_DEBUG_LEVEL_CLOSE)

Functions

BOOLEAN UdfCommonClosePrivate (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFCB Fcb, IN ULONG UserReference, IN BOOLEAN FromFsd)
VOID UdfQueueClose (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN ULONG UserReference, IN BOOLEAN DelayedClose)
PIRP_CONTEXT UdfRemoveClose (IN PVCB Vcb OPTIONAL)
VOID UdfFspClose (IN PVCB Vcb OPTIONAL)
NTSTATUS UdfCommonClose (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)


Define Documentation

#define BugCheckFileId   (UDFS_BUG_CHECK_CLOSE)
 

Definition at line 56 of file close.c.

#define Dbg   (UDFS_DEBUG_LEVEL_CLOSE)
 

Definition at line 62 of file close.c.


Function Documentation

NTSTATUS UdfCommonClose IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 319 of file close.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, FALSE, _FCB::FcbReference, FlagOn, IoGetCurrentIrpStackLocation, Irp, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, NULL, PAGED_CODE, TRUE, TYPE_OF_OPEN, UdfAcquireUdfData, UdfCheckForDismount(), UdfCommonClosePrivate(), UdfCompleteRequest(), UdfDecodeFileObject(), UdfDeleteCcb(), UdfQueueClose(), UdfReleaseUdfData, UnopenedFileObject, UserDirectoryOpen, UserFileOpen, _FCB::Vcb, _VCB::VcbCleanup, _VCB::VcbCondition, VcbMounted, and VcbMountInProgress.

Referenced by UdfFsdDispatch().

00326 : 00327 00328 This routine is the Fsd entry for the close operation. We decode the file 00329 object to find the UDFS structures and type of open. We call our internal 00330 worker routine to perform the actual work. If the work wasn't completed 00331 then we post to one of our worker queues. The Ccb isn't needed after this 00332 point so we delete the Ccb and return STATUS_SUCCESS to our caller in all 00333 cases. 00334 00335 Arguments: 00336 00337 Irp - Supplies the Irp to process 00338 00339 Return Value: 00340 00341 STATUS_SUCCESS 00342 00343 --*/ 00344 00345 { 00346 TYPE_OF_OPEN TypeOfOpen; 00347 00348 PVCB Vcb; 00349 PFCB Fcb; 00350 PCCB Ccb; 00351 ULONG UserReference = 0; 00352 00353 BOOLEAN DelayedClose; 00354 BOOLEAN ReleaseUdfData = FALSE; 00355 00356 PAGED_CODE(); 00357 00358 // 00359 // Check input. 00360 // 00361 00362 ASSERT_IRP_CONTEXT( IrpContext ); 00363 ASSERT_IRP( Irp ); 00364 00365 // 00366 // If we were called with our file system device object instead of a 00367 // volume device object, just complete this request with STATUS_SUCCESS. 00368 // 00369 00370 if (IrpContext->Vcb == NULL) { 00371 00372 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00373 return STATUS_SUCCESS; 00374 } 00375 00376 // 00377 // Decode the file object to get the type of open and Fcb/Ccb. 00378 // 00379 00380 TypeOfOpen = UdfDecodeFileObject( IoGetCurrentIrpStackLocation( Irp )->FileObject, 00381 &Fcb, 00382 &Ccb ); 00383 00384 // 00385 // No work to do for unopened file objects. 00386 // 00387 00388 if (TypeOfOpen == UnopenedFileObject) { 00389 00390 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00391 00392 return STATUS_SUCCESS; 00393 } 00394 00395 Vcb = Fcb->Vcb; 00396 00397 // 00398 // Call the worker routine to perform the actual work. This routine 00399 // should never raise except for a fatal error. 00400 // 00401 00402 if (Ccb != NULL) { 00403 00404 UserReference = 1; 00405 00406 // 00407 // We can always deallocate the Ccb if present. 00408 // 00409 00410 UdfDeleteCcb( IrpContext, Ccb ); 00411 } 00412 00413 // 00414 // If this is a user file or directory then check if we should post 00415 // this to the delayed close queue. This has to be the last reference 00416 // for a user file or directory open. 00417 // 00418 00419 if ((Vcb->VcbCondition == VcbMounted) && 00420 (Fcb->FcbReference == 1) && 00421 ((TypeOfOpen == UserFileOpen) || 00422 (TypeOfOpen == UserDirectoryOpen))) { 00423 00424 UdfQueueClose( IrpContext, Fcb, UserReference, TRUE ); 00425 IrpContext = NULL; 00426 00427 // 00428 // Otherwise try to process this close. Post to the async close queue 00429 // if we can't acquire all of the resources. 00430 // 00431 00432 } else { 00433 00434 // 00435 // If we may be dismounting this volume then acquire the UdfData 00436 // resource. 00437 // 00438 // Since we now must make volumes go away as soon as reasonable after 00439 // the last user handles closes, key off of the cleanup count. It is 00440 // OK to do this more than neccesary. Since this Fcb could be holding 00441 // a number of other Fcbs (and thus their references), a simple check 00442 // on reference count is not appropriate. 00443 // 00444 00445 if ((Vcb->VcbCleanup == 0) && 00446 (Vcb->VcbCondition != VcbMounted) && 00447 (Vcb->VcbCondition != VcbMountInProgress) && 00448 FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS )) { 00449 00450 UdfAcquireUdfData( IrpContext ); 00451 ReleaseUdfData = TRUE; 00452 } 00453 00454 if (!UdfCommonClosePrivate( IrpContext, Vcb, Fcb, UserReference, TRUE )) { 00455 00456 // 00457 // If we didn't complete the request then post the request as needed. 00458 // 00459 00460 UdfQueueClose( IrpContext, Fcb, UserReference, FALSE ); 00461 IrpContext = NULL; 00462 00463 // 00464 // Check whether we should be dismounting the volume and then complete 00465 // the request. 00466 // 00467 00468 } else if (ReleaseUdfData) { 00469 00470 UdfCheckForDismount( IrpContext, Vcb, FALSE ); 00471 } 00472 } 00473 00474 // 00475 // Always complete this request with STATUS_SUCCESS. 00476 // 00477 00478 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00479 00480 if (ReleaseUdfData) { 00481 00482 UdfReleaseUdfData( IrpContext ); 00483 } 00484 00485 // 00486 // Always return STATUS_SUCCESS for closes. 00487 // 00488 00489 return STATUS_SUCCESS; 00490 }

BOOLEAN UdfCommonClosePrivate IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFCB  Fcb,
IN ULONG  UserReference,
IN BOOLEAN  FromFsd
 

Definition at line 498 of file close.c.

References ASSERT_FCB, ASSERT_IRP_CONTEXT, ASSERT_VCB, Dbg, DebugTrace, FALSE, PAGED_CODE, TRUE, UdfAcquireFcbExclusive, UdfAcquireVcbShared, UdfDecrementReferenceCounts, UdfLockVcb, UdfReleaseFcb, UdfReleaseVcb, UdfTeardownStructures(), and UdfUnlockVcb.

Referenced by UdfCommonClose(), and UdfFspClose().

00508 : 00509 00510 This is the worker routine for the close operation. We can be called in 00511 an Fsd thread or from a worker Fsp thread. If called from the Fsd thread 00512 then we acquire the resources without waiting. Otherwise we know it is 00513 safe to wait. 00514 00515 We check to see whether we should post this request to the delayed close 00516 queue. If we are to process the close here then we acquire the Vcb and 00517 Fcb. We will adjust the counts and call our teardown routine to see 00518 if any of the structures should go away. 00519 00520 Arguments: 00521 00522 Vcb - Vcb for this volume. 00523 00524 Fcb - Fcb for this request. 00525 00526 UserReference - Number of user references for this file object. This is 00527 zero for an internal stream. 00528 00529 FromFsd - This request was called from an Fsd thread. Indicates whether 00530 we should wait to acquire resources. 00531 00532 Return Value: 00533 00534 BOOLEAN - TRUE if this thread processed the close, FALSE otherwise. 00535 00536 --*/ 00537 00538 { 00539 BOOLEAN CompletedClose; 00540 BOOLEAN RemovedFcb; 00541 00542 PAGED_CODE(); 00543 00544 // 00545 // Check inputs. 00546 // 00547 00548 ASSERT_IRP_CONTEXT( IrpContext ); 00549 ASSERT_VCB( Vcb ); 00550 ASSERT_FCB( Fcb ); 00551 00552 // 00553 // Try to acquire the Vcb and Fcb. If we can't acquire them then return 00554 // and let our caller know he should post the request to the async 00555 // queue. 00556 // 00557 00558 if (UdfAcquireVcbShared( IrpContext, Vcb, FromFsd )) { 00559 00560 if (!UdfAcquireFcbExclusive( IrpContext, Fcb, FromFsd )) { 00561 00562 // 00563 // We couldn't get the Fcb. Release the Vcb and let our caller 00564 // know to post this request. 00565 // 00566 00567 UdfReleaseVcb( IrpContext, Vcb ); 00568 return FALSE; 00569 } 00570 00571 // 00572 // We didn't get the Vcb. Let our caller know to post this request. 00573 // 00574 00575 } else { 00576 00577 return FALSE; 00578 } 00579 00580 // 00581 // Lock the Vcb and decrement the reference counts. 00582 // 00583 00584 UdfLockVcb( IrpContext, Vcb ); 00585 00586 DebugTrace(( +1, Dbg, 00587 "UdfCommonClosePrivate, Fcb %08x %4s Vcb %d/%d Fcb %d/%d\n", Fcb, 00588 ( UserReference? "USER" : "SYS" ), 00589 Vcb->VcbReference, 00590 Vcb->VcbUserReference, 00591 Fcb->FcbReference, 00592 Fcb->FcbUserReference )); 00593 00594 UdfDecrementReferenceCounts( IrpContext, Fcb, 1, UserReference ); 00595 00596 DebugTrace(( +0, Dbg, 00597 "UdfCommonClosePrivate, Vcb %d/%d Fcb %d/%d\n", 00598 Vcb->VcbReference, 00599 Vcb->VcbUserReference, 00600 Fcb->FcbReference, 00601 Fcb->FcbUserReference )); 00602 00603 UdfUnlockVcb( IrpContext, Vcb ); 00604 00605 // 00606 // Call our teardown routine to see if this object can go away. 00607 // If we don't remove the Fcb then release it. 00608 // 00609 00610 UdfTeardownStructures( IrpContext, Fcb, FALSE, &RemovedFcb ); 00611 00612 if (!RemovedFcb) { 00613 00614 UdfReleaseFcb( IrpContext, Fcb ); 00615 } 00616 00617 DebugTrace(( -1, Dbg, 00618 "UdfCommonClosePrivate, RemovedFcb %08x -> %c\n", 00619 Fcb, 00620 ( RemovedFcb? 'T' : 'F' ))); 00621 00622 // 00623 // Release the Vcb and return to our caller. Let him know we completed 00624 // this request. 00625 // 00626 00627 UdfReleaseVcb( IrpContext, Vcb ); 00628 00629 return TRUE; 00630 }

VOID UdfFspClose IN PVCB Vcb  OPTIONAL  ) 
 

Definition at line 99 of file close.c.

References ASSERT_OPTIONAL_VCB, ClearFlag, Dbg, DebugTrace, _IRP_CONTEXT::ExceptionStatus, FALSE, _FCB::FcbReference, _FCB::FcbUserReference, _IRP_CONTEXT::Flags, FsRtlEnterFileSystem, FsRtlExitFileSystem, _IRP_CONTEXT::Irp, IRP_CONTEXT, IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, IRP_CONTEXT_FSP_FLAGS, _UDF_DATA::MinDelayedCloseCount, NULL, PAGED_CODE, PIRP_CONTEXT_LITE, SafeNodeType, SetFlag, THREAD_CONTEXT, ThreadContext, UdfAcquireUdfData, UdfAcquireVcbShared, UdfCheckForDismount(), UdfCommonClosePrivate(), UdfCompleteRequest(), UdfData, UdfFreeIrpContextLite, UdfInitializeStackIrpContext(), UdfReleaseUdfData, UdfReleaseVcb, UdfRemoveClose(), UDFS_NTC_IRP_CONTEXT, UdfSetThreadContext(), _FCB::Vcb, _VCB::VcbCleanup, _VCB::VcbCondition, VcbMounted, VcbMountInProgress, _VCB::VcbReference, and _VCB::VcbUserReference.

Referenced by UdfCheckForDismount(), UdfCompleteFcbOpen(), UdfDismountVcb(), UdfInitializeGlobalData(), UdfLockVolumeInternal(), and UdfPurgeVolume().

00105 : 00106 00107 This routine is called to process the close queues in the UdfData. If the 00108 Vcb is passed then we want to remove all of the closes for this Vcb. 00109 Otherwise we will do as many of the delayed closes as we need to do. 00110 00111 Arguments: 00112 00113 Vcb - If specified then we are looking for all of the closes for the 00114 given Vcb. 00115 00116 Return Value: 00117 00118 None 00119 00120 --*/ 00121 00122 { 00123 PIRP_CONTEXT IrpContext; 00124 IRP_CONTEXT StackIrpContext; 00125 00126 THREAD_CONTEXT ThreadContext; 00127 00128 PFCB Fcb; 00129 ULONG UserReference; 00130 00131 ULONG VcbHoldCount = 0; 00132 PVCB CurrentVcb = NULL; 00133 00134 BOOLEAN ReleaseUdfData = FALSE; 00135 00136 PAGED_CODE(); 00137 00138 // 00139 // Check input. 00140 // 00141 00142 ASSERT_OPTIONAL_VCB( Vcb ); 00143 00144 FsRtlEnterFileSystem(); 00145 00146 // 00147 // Continue processing until there are no more closes to process. 00148 // 00149 00150 while (IrpContext = UdfRemoveClose( Vcb )) { 00151 00152 // 00153 // If we don't have an IrpContext then use the one on the stack. 00154 // Initialize it for this request. 00155 // 00156 00157 if (SafeNodeType( IrpContext ) != UDFS_NTC_IRP_CONTEXT ) { 00158 00159 // 00160 // Update the local values from the IrpContextLite. 00161 // 00162 00163 Fcb = ((PIRP_CONTEXT_LITE) IrpContext)->Fcb; 00164 UserReference = ((PIRP_CONTEXT_LITE) IrpContext)->UserReference; 00165 00166 // 00167 // Update the stack irp context with the values from the 00168 // IrpContextLite. 00169 // 00170 00171 UdfInitializeStackIrpContext( &StackIrpContext, 00172 (PIRP_CONTEXT_LITE) IrpContext ); 00173 00174 // 00175 // Free the IrpContextLite. 00176 // 00177 00178 UdfFreeIrpContextLite( (PIRP_CONTEXT_LITE) IrpContext ); 00179 00180 // 00181 // Remember we have the IrpContext from the stack. 00182 // 00183 00184 IrpContext = &StackIrpContext; 00185 00186 // 00187 // Otherwise cleanup the existing IrpContext. 00188 // 00189 00190 } else { 00191 00192 // 00193 // Remember the Fcb and user reference count. 00194 // 00195 00196 Fcb = (PFCB) IrpContext->Irp; 00197 IrpContext->Irp = NULL; 00198 00199 UserReference = (ULONG) IrpContext->ExceptionStatus; 00200 IrpContext->ExceptionStatus = STATUS_SUCCESS; 00201 } 00202 00203 // 00204 // We have an IrpContext. Now we need to set the top level thread 00205 // context. 00206 // 00207 00208 SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); 00209 00210 // 00211 // If we were given a Vcb then there is a request on top of this. 00212 // 00213 00214 if (ARGUMENT_PRESENT( Vcb )) { 00215 00216 ClearFlag( IrpContext->Flags, 00217 IRP_CONTEXT_FLAG_TOP_LEVEL | IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS ); 00218 } 00219 00220 UdfSetThreadContext( IrpContext, &ThreadContext ); 00221 00222 // 00223 // If we have hit the maximum number of requests to process without 00224 // releasing the Vcb then release the Vcb now. If we are holding 00225 // a different Vcb to this one then release the previous Vcb. 00226 // 00227 // In either case acquire the current Vcb. 00228 // 00229 // We use the MinDelayedCloseCount from the UdfData since it is 00230 // a convenient value based on the system size. Only thing we are trying 00231 // to do here is prevent this routine starving other threads which 00232 // may need this Vcb exclusively. 00233 // 00234 00235 ReleaseUdfData = !ARGUMENT_PRESENT( Vcb ) && 00236 (Fcb->Vcb->VcbCondition != VcbMounted) && 00237 (Fcb->Vcb->VcbCondition != VcbMountInProgress) && 00238 (Fcb->Vcb->VcbCleanup == 0); 00239 00240 if (ReleaseUdfData || 00241 (VcbHoldCount > UdfData.MinDelayedCloseCount) || 00242 (Fcb->Vcb != CurrentVcb)) { 00243 00244 if (CurrentVcb != NULL) { 00245 00246 UdfReleaseVcb( IrpContext, CurrentVcb ); 00247 } 00248 00249 if (ReleaseUdfData) { 00250 00251 UdfAcquireUdfData( IrpContext ); 00252 } 00253 00254 CurrentVcb = Fcb->Vcb; 00255 UdfAcquireVcbShared( IrpContext, CurrentVcb, FALSE ); 00256 00257 VcbHoldCount = 0; 00258 00259 } else { 00260 00261 VcbHoldCount += 1; 00262 } 00263 00264 DebugTrace(( +1, Dbg, 00265 "UdfFspClose, Fcb %08x %4s Vcb %d/%d Fcb %d/%d\n", 00266 Fcb, 00267 ( UserReference? "USER" : "SYS" ), 00268 CurrentVcb->VcbReference, 00269 CurrentVcb->VcbUserReference, 00270 Fcb->FcbReference, 00271 Fcb->FcbUserReference )); 00272 00273 // 00274 // Call our worker routine to perform the close operation. 00275 // 00276 00277 UdfCommonClosePrivate( IrpContext, CurrentVcb, Fcb, UserReference, FALSE ); 00278 00279 // 00280 // If the reference count on this Vcb is below our residual reference 00281 // then check if we should dismount the volume. 00282 // 00283 00284 if (ReleaseUdfData) { 00285 00286 UdfReleaseVcb( IrpContext, CurrentVcb ); 00287 UdfCheckForDismount( IrpContext, CurrentVcb, FALSE ); 00288 00289 CurrentVcb = NULL; 00290 00291 UdfReleaseUdfData( IrpContext ); 00292 ReleaseUdfData = FALSE; 00293 } 00294 00295 // 00296 // Complete the current request to cleanup the IrpContext. 00297 // 00298 00299 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00300 00301 DebugTrace(( -1, Dbg, "UdfFspClose -> VOID\n" )); 00302 } 00303 00304 // 00305 // Release any Vcb we may still hold. 00306 // 00307 00308 if (CurrentVcb != NULL) { 00309 00310 UdfReleaseVcb( IrpContext, CurrentVcb ); 00311 } 00312 00313 FsRtlExitFileSystem(); 00314 return; 00315 }

VOID UdfQueueClose IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN ULONG  UserReference,
IN BOOLEAN  DelayedClose
 

Definition at line 634 of file close.c.

References ASSERT_FCB, ASSERT_IRP_CONTEXT, _UDF_DATA::AsyncCloseCount, _UDF_DATA::AsyncCloseQueue, _UDF_DATA::CloseItem, CriticalWorkQueue, Dbg, DebugTrace, _UDF_DATA::DelayedCloseCount, _IRP_CONTEXT_LITE::DelayedCloseLinks, _UDF_DATA::DelayedCloseQueue, ExQueueWorkItem(), FALSE, _IRP_CONTEXT_LITE::Fcb, _UDF_DATA::FspCloseActive, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_LITE, _UDF_DATA::MaxDelayedCloseCount, _IRP_CONTEXT_LITE::NodeByteSize, _IRP_CONTEXT_LITE::NodeTypeCode, NTSTATUS(), NULL, PAGED_CODE, _IRP_CONTEXT_LITE::RealDevice, _UDF_DATA::ReduceDelayedClose, SetFlag, TRUE, UdfCleanupIrpContext(), UdfCompleteRequest(), UdfCreateIrpContextLite, UdfData, UdfLockUdfData, UDFS_NTC_IRP_CONTEXT_LITE, UdfUnlockUdfData, and _IRP_CONTEXT_LITE::UserReference.

Referenced by UdfCommonClose().

00643 : 00644 00645 This routine is called to queue a request to either the async or delayed 00646 close queue. For the delayed queue we need to allocate a smaller 00647 structure to contain the information about the file object. We do 00648 that so we don't put the larger IrpContext structures into this long 00649 lived queue. If we can allocate this structure then we put this 00650 on the async queue instead. 00651 00652 Arguments: 00653 00654 Fcb - Fcb for this file object. 00655 00656 UserReference - Number of user references for this file object. This is 00657 zero for an internal stream. 00658 00659 DelayedClose - Indicates whether this should go on the async or delayed 00660 close queue. 00661 00662 Return Value: 00663 00664 None 00665 00666 --*/ 00667 00668 { 00669 PIRP_CONTEXT_LITE IrpContextLite = NULL; 00670 BOOLEAN StartWorker = FALSE; 00671 00672 PAGED_CODE(); 00673 00674 // 00675 // Check inputs. 00676 // 00677 00678 ASSERT_IRP_CONTEXT( IrpContext ); 00679 ASSERT_FCB( Fcb ); 00680 00681 // 00682 // Start with the delayed queue request. We can move this to the async 00683 // queue if there is an allocation failure. 00684 // 00685 00686 if (DelayedClose) { 00687 00688 // 00689 // Try to allocate non-paged pool for the IRP_CONTEXT_LITE. 00690 // 00691 00692 IrpContextLite = UdfCreateIrpContextLite( IrpContext ); 00693 } 00694 00695 // 00696 // We want to clear the top level context in this thread if 00697 // necessary. Call our cleanup routine to do the work. 00698 // 00699 00700 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00701 UdfCleanupIrpContext( IrpContext, TRUE ); 00702 00703 // 00704 // Synchronize with the UdfData lock. 00705 // 00706 00707 UdfLockUdfData(); 00708 00709 DebugTrace(( +1, Dbg, 00710 "UdfQueueClose, Fcb %08x %4s %5s\n", 00711 Fcb, 00712 ( UserReference? "USER" : "SYS" ), 00713 ( IrpContextLite? "DELAY" : "ASYNC" ))); 00714 00715 00716 // 00717 // If we have an IrpContext then put the request on the delayed close queue. 00718 // 00719 00720 if (IrpContextLite != NULL) { 00721 00722 // 00723 // Initialize the IrpContextLite. 00724 // 00725 00726 IrpContextLite->NodeTypeCode = UDFS_NTC_IRP_CONTEXT_LITE; 00727 IrpContextLite->NodeByteSize = sizeof( IRP_CONTEXT_LITE ); 00728 IrpContextLite->Fcb = Fcb; 00729 IrpContextLite->UserReference = UserReference; 00730 IrpContextLite->RealDevice = IrpContext->RealDevice; 00731 00732 // 00733 // Add this to the delayed close list and increment 00734 // the count. 00735 // 00736 00737 InsertTailList( &UdfData.DelayedCloseQueue, 00738 &IrpContextLite->DelayedCloseLinks ); 00739 00740 UdfData.DelayedCloseCount += 1; 00741 00742 // 00743 // If we are above our threshold then start the delayed 00744 // close operation. 00745 // 00746 00747 if (UdfData.DelayedCloseCount > UdfData.MaxDelayedCloseCount) { 00748 00749 UdfData.ReduceDelayedClose = TRUE; 00750 00751 if (!UdfData.FspCloseActive) { 00752 00753 UdfData.FspCloseActive = TRUE; 00754 StartWorker = TRUE; 00755 } 00756 } 00757 00758 // 00759 // Unlock the global data. 00760 // 00761 00762 UdfUnlockUdfData(); 00763 00764 // 00765 // Cleanup the IrpContext. 00766 // 00767 00768 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00769 00770 // 00771 // Otherwise drop into the async case below. 00772 // 00773 00774 } else { 00775 00776 // 00777 // Store the information about the file object into the IrpContext. 00778 // 00779 00780 IrpContext->Irp = (PIRP) Fcb; 00781 IrpContext->ExceptionStatus = (NTSTATUS) UserReference; 00782 00783 // 00784 // Add this to the async close list and increment the count. 00785 // 00786 00787 InsertTailList( &UdfData.AsyncCloseQueue, 00788 &IrpContext->WorkQueueItem.List ); 00789 00790 UdfData.AsyncCloseCount += 1; 00791 00792 // 00793 // Remember to start the Fsp close thread if not currently started. 00794 // 00795 00796 if (!UdfData.FspCloseActive) { 00797 00798 UdfData.FspCloseActive = TRUE; 00799 StartWorker = TRUE; 00800 } 00801 00802 // 00803 // Unlock the global data. 00804 // 00805 00806 UdfUnlockUdfData(); 00807 } 00808 00809 // 00810 // Start the FspClose thread if we need to. 00811 // 00812 00813 if (StartWorker) { 00814 00815 ExQueueWorkItem( &UdfData.CloseItem, CriticalWorkQueue ); 00816 } 00817 00818 DebugTrace(( -1, Dbg, "UdfQueueClose -> VOID\n" )); 00819 00820 // 00821 // Return to our caller. 00822 // 00823 00824 return; 00825 }

PIRP_CONTEXT UdfRemoveClose IN PVCB Vcb  OPTIONAL  ) 
 

Definition at line 833 of file close.c.

References ASSERT_OPTIONAL_VCB, _UDF_DATA::AsyncCloseCount, _UDF_DATA::AsyncCloseQueue, _UDF_DATA::DelayedCloseCount, _UDF_DATA::DelayedCloseQueue, FALSE, _IRP_CONTEXT_LITE::Fcb, _UDF_DATA::FspCloseActive, _UDF_DATA::MinDelayedCloseCount, NULL, PAGED_CODE, _UDF_DATA::ReduceDelayedClose, UdfData, UdfLockUdfData, UdfUnlockUdfData, _FCB::Vcb, and _IRP_CONTEXT::Vcb.

Referenced by UdfFspClose().

00839 : 00840 00841 Arguments: 00842 00843 This routine is called to scan the async and delayed close queues looking 00844 for a suitable entry. If the Vcb is specified then we scan both queues 00845 looking for an entry with the same Vcb. Otherwise we will look in the 00846 async queue first for any close item. If none found there then we look 00847 in the delayed close queue provided that we have triggered the delayed 00848 close operation. 00849 00850 Return Value: 00851 00852 PIRP_CONTEXT - NULL if no work item found. Otherwise it is the pointer to 00853 either the IrpContext or IrpContextLite for this request. 00854 00855 --*/ 00856 00857 { 00858 PIRP_CONTEXT IrpContext = NULL; 00859 PIRP_CONTEXT NextIrpContext; 00860 PIRP_CONTEXT_LITE NextIrpContextLite; 00861 00862 PLIST_ENTRY Entry; 00863 00864 PAGED_CODE(); 00865 00866 ASSERT_OPTIONAL_VCB( Vcb ); 00867 00868 // 00869 // Lock the UdfData to perform the scan. 00870 // 00871 00872 UdfLockUdfData(); 00873 00874 // 00875 // First check the list of async closes. 00876 // 00877 00878 Entry = UdfData.AsyncCloseQueue.Flink; 00879 00880 while (Entry != &UdfData.AsyncCloseQueue) { 00881 00882 // 00883 // Extract the IrpContext. 00884 // 00885 00886 NextIrpContext = CONTAINING_RECORD( Entry, 00887 IRP_CONTEXT, 00888 WorkQueueItem.List ); 00889 00890 // 00891 // If no Vcb was specified or this Vcb is for our volume 00892 // then perform the close. 00893 // 00894 00895 if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContext->Vcb == Vcb)) { 00896 00897 RemoveEntryList( Entry ); 00898 UdfData.AsyncCloseCount -= 1; 00899 00900 IrpContext = NextIrpContext; 00901 break; 00902 } 00903 00904 // 00905 // Move to the next entry. 00906 // 00907 00908 Entry = Entry->Flink; 00909 } 00910 00911 // 00912 // If we didn't find anything look through the delayed close 00913 // queue. 00914 // 00915 // We will only check the delayed close queue if we were given 00916 // a Vcb or the delayed close operation is active. 00917 // 00918 00919 if ((IrpContext == NULL) && 00920 (ARGUMENT_PRESENT( Vcb ) || 00921 (UdfData.ReduceDelayedClose && 00922 (UdfData.DelayedCloseCount > UdfData.MinDelayedCloseCount)))) { 00923 00924 Entry = UdfData.DelayedCloseQueue.Flink; 00925 00926 while (Entry != &UdfData.DelayedCloseQueue) { 00927 00928 // 00929 // Extract the IrpContext. 00930 // 00931 00932 NextIrpContextLite = CONTAINING_RECORD( Entry, 00933 IRP_CONTEXT_LITE, 00934 DelayedCloseLinks ); 00935 00936 // 00937 // If no Vcb was specified or this Vcb is for our volume 00938 // then perform the close. 00939 // 00940 00941 if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContextLite->Fcb->Vcb == Vcb)) { 00942 00943 RemoveEntryList( Entry ); 00944 UdfData.DelayedCloseCount -= 1; 00945 00946 IrpContext = (PIRP_CONTEXT) NextIrpContextLite; 00947 break; 00948 } 00949 00950 // 00951 // Move to the next entry. 00952 // 00953 00954 Entry = Entry->Flink; 00955 } 00956 } 00957 00958 // 00959 // If the Vcb wasn't specified and we couldn't find an entry 00960 // then turn off the Fsp thread. 00961 // 00962 00963 if (!ARGUMENT_PRESENT( Vcb ) && (IrpContext == NULL)) { 00964 00965 UdfData.FspCloseActive = FALSE; 00966 UdfData.ReduceDelayedClose = FALSE; 00967 } 00968 00969 // 00970 // Unlock the global data. 00971 // 00972 00973 UdfUnlockUdfData(); 00974 00975 return IrpContext; 00976 }


Generated on Sat May 15 19:43:05 2004 for test by doxygen 1.3.7