Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenclose.c
Go to the documentation of this file.
00001 /************************************************************************* 00002 * 00003 * File: close.c 00004 * 00005 * Module: Ext2 File System Driver (Kernel mode execution only) 00006 * 00007 * Description: 00008 * Should contain code to handle the "Close" dispatch entry point. 00009 * This file serves as a placeholder. Please update this file as part 00010 * of designing and implementing your FSD. 00011 * 00012 * Author: Manoj Paul Joseph 00013 * 00014 * 00015 *************************************************************************/ 00016 00017 #include "ext2fsd.h" 00018 00019 // define the file specific bug-check id 00020 #define EXT2_BUG_CHECK_ID EXT2_FILE_CLOSE 00021 00022 #define DEBUG_LEVEL (DEBUG_TRACE_CLOSE) 00023 00024 00025 /************************************************************************* 00026 * 00027 * Function: Ext2Close() 00028 * 00029 * Description: 00030 * The I/O Manager will invoke this routine to handle a close 00031 * request 00032 * 00033 * Expected Interrupt Level (for execution) : 00034 * 00035 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution 00036 * to be deferred to a worker thread context) 00037 * 00038 * Return Value: Does not matter! 00039 * 00040 *************************************************************************/ 00041 NTSTATUS NTAPI Ext2Close( 00042 PDEVICE_OBJECT DeviceObject, // the logical volume device object 00043 PIRP Irp) // I/O Request Packet 00044 { 00045 NTSTATUS RC = STATUS_SUCCESS; 00046 PtrExt2IrpContext PtrIrpContext = NULL; 00047 BOOLEAN AreWeTopLevel = FALSE; 00048 00049 DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Close IRP Received...", 0); 00050 00051 00052 FsRtlEnterFileSystem(); 00053 00054 ASSERT(DeviceObject); 00055 ASSERT(Irp); 00056 00057 // set the top level context 00058 AreWeTopLevel = Ext2IsIrpTopLevel(Irp); 00059 00060 try 00061 { 00062 00063 // get an IRP context structure and issue the request 00064 PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject); 00065 ASSERT(PtrIrpContext); 00066 00067 RC = Ext2CommonClose(PtrIrpContext, Irp, TRUE); 00068 00069 } 00070 except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 00071 { 00072 00073 RC = Ext2ExceptionHandler(PtrIrpContext, Irp); 00074 Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC); 00075 } 00076 00077 if (AreWeTopLevel) 00078 { 00079 IoSetTopLevelIrp(NULL); 00080 } 00081 00082 FsRtlExitFileSystem(); 00083 00084 return(RC); 00085 } 00086 00087 00088 /************************************************************************* 00089 * 00090 * Function: Ext2CommonClose() 00091 * 00092 * Description: 00093 * The actual work is performed here. This routine may be invoked in one' 00094 * of the two possible contexts: 00095 * (a) in the context of a system worker thread 00096 * (b) in the context of the original caller 00097 * 00098 * Expected Interrupt Level (for execution) : 00099 * 00100 * IRQL_PASSIVE_LEVEL 00101 * 00102 * Return Value: Does not matter! 00103 * 00104 *************************************************************************/ 00105 NTSTATUS NTAPI Ext2CommonClose( 00106 PtrExt2IrpContext PtrIrpContext, 00107 PIRP PtrIrp, 00108 BOOLEAN FirstAttempt ) 00109 { 00110 NTSTATUS RC = STATUS_SUCCESS; 00111 PIO_STACK_LOCATION PtrIoStackLocation = NULL; 00112 PFILE_OBJECT PtrFileObject = NULL; 00113 PtrExt2FCB PtrFCB = NULL; 00114 PtrExt2CCB PtrCCB = NULL; 00115 PtrExt2VCB PtrVCB = NULL; 00116 PtrExt2NTRequiredFCB PtrReqdFCB = NULL; 00117 PERESOURCE PtrResourceAcquired = NULL; 00118 PERESOURCE PtrPagingIoResourceAcquired = NULL; 00119 00120 BOOLEAN CompleteIrp = TRUE; 00121 BOOLEAN PostRequest = FALSE; 00122 BOOLEAN AcquiredVCB = FALSE; 00123 BOOLEAN BlockForResource; 00124 int i = 1; 00125 00126 try 00127 { 00128 // First, get a pointer to the current I/O stack location 00129 PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp); 00130 ASSERT(PtrIoStackLocation); 00131 00132 PtrFileObject = PtrIoStackLocation->FileObject; 00133 ASSERT(PtrFileObject); 00134 00135 if( !PtrFileObject->FsContext2 ) 00136 { 00137 // This must be a Cleanup request received 00138 // as a result of IoCreateStreamFileObject 00139 // Only such a File object would have a NULL CCB 00140 00141 DebugTrace( DEBUG_TRACE_SPECIAL, " === Close with NULL CCB", 0); 00142 if( PtrFileObject ) 00143 { 00144 DebugTrace( DEBUG_TRACE_SPECIAL, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00145 } 00146 try_return(); 00147 } 00148 00149 // Get the FCB and CCB pointers 00150 00151 Ext2GetFCB_CCB_VCB_FromFileObject ( 00152 PtrFileObject, &PtrFCB, &PtrCCB, &PtrVCB ); 00153 00154 PtrVCB = (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension); 00155 ASSERT( PtrVCB ); 00156 00157 if( PtrFCB && PtrFCB->FCBName && PtrFCB->FCBName->ObjectName.Length && PtrFCB->FCBName->ObjectName.Buffer ) 00158 //if( PtrFileObject->FileName.Length && PtrFileObject->FileName.Buffer ) 00159 { 00160 DebugTrace(DEBUG_TRACE_FILE_NAME, " === Close File Name : -%S-", PtrFCB->FCBName->ObjectName.Buffer ); 00161 } 00162 else 00163 { 00164 DebugTrace(DEBUG_TRACE_FILE_NAME, " === Close File Name : -null-", 0); 00165 } 00166 00167 // (a) Acquiring the VCBResource Exclusively... 00168 // This is done to synchronise with the close and cleanup routines... 00169 // if( ExTryToAcquireResourceExclusiveLite(&(PtrVCB->VCBResource) ) ) 00170 00171 BlockForResource = !FirstAttempt; 00172 if( !FirstAttempt ) 00173 { 00174 DebugTrace(DEBUG_TRACE_MISC, "*** Going into a block to acquire VCB Exclusively [Close]", 0); 00175 } 00176 else 00177 { 00178 DebugTrace(DEBUG_TRACE_MISC, "*** Attempting to acquire VCB Exclusively [Close]", 0); 00179 } 00180 if( PtrFileObject ) 00181 { 00182 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00183 } 00184 00185 i = 1; 00186 while( !AcquiredVCB ) 00187 { 00188 DebugTraceState( "VCB AC:0x%LX EX:0x%LX SW:0x%LX [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters ); 00189 if(! ExAcquireResourceExclusiveLite( &(PtrVCB->VCBResource), FALSE ) ) 00190 { 00191 DebugTrace(DEBUG_TRACE_MISC, "*** VCB Acquisition FAILED [Close]", 0); 00192 if( BlockForResource && i != 1000 ) 00193 { 00194 LARGE_INTEGER Delay; 00195 00196 //KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY ); 00197 00198 Delay.QuadPart = -500 * i; 00199 KeDelayExecutionThread( KernelMode, FALSE, &Delay ); 00200 DebugTrace(DEBUG_TRACE_MISC, "*** Retrying... after 50 * %ld ms [Close]", i); 00201 } 00202 else 00203 { 00204 if( i == 1000 ) 00205 DebugTrace(DEBUG_TRACE_MISC, "*** Reposting... [Close]", 0 ); 00206 PostRequest = TRUE; 00207 try_return( RC = STATUS_PENDING ); 00208 } 00209 } 00210 else 00211 { 00212 DebugTrace(DEBUG_TRACE_MISC, "*** VCB Acquired in [Close]", 0); 00213 AcquiredVCB = TRUE; 00214 } 00215 i *= 10; 00216 } 00217 00218 // (b) Acquire the file (FCB) exclusively 00219 if( PtrFCB && PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB ) 00220 { 00221 // This FCB is an FCB indeed. ;) 00222 // So acquiring it exclusively... 00223 // This is done to synchronise with read/write routines... 00224 if( !FirstAttempt ) 00225 { 00226 DebugTrace(DEBUG_TRACE_MISC, "*** Going into a block to acquire FCB Exclusively [Close]", 0); 00227 } 00228 else 00229 { 00230 DebugTrace(DEBUG_TRACE_MISC, "*** Attempting to acquire FCB Exclusively [Close]", 0); 00231 } 00232 if( PtrFileObject ) 00233 { 00234 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00235 } 00236 00237 PtrReqdFCB = &PtrFCB->NTRequiredFCB; 00238 00239 i = 1; 00240 while( !PtrResourceAcquired ) 00241 { 00242 DebugTraceState( "FCBMain AC:0x%LX EX:0x%LX SW:0x%LX [Close]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters ); 00243 if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->MainResource), FALSE ) ) 00244 { 00245 DebugTrace(DEBUG_TRACE_MISC, "*** FCB Acquisition FAILED [Close]", 0); 00246 if( BlockForResource && i != 1000 ) 00247 { 00248 LARGE_INTEGER Delay; 00249 00250 //KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY ); 00251 00252 Delay.QuadPart = -500 * i; 00253 KeDelayExecutionThread( KernelMode, FALSE, &Delay ); 00254 DebugTrace(DEBUG_TRACE_MISC, "*** Retrying... after 50 * %ld ms [Close]", i); 00255 } 00256 else 00257 { 00258 if( i == 1000 ) 00259 DebugTrace(DEBUG_TRACE_MISC, "*** Reposting... [Close]", 0 ); 00260 PostRequest = TRUE; 00261 try_return( RC = STATUS_PENDING ); 00262 } 00263 } 00264 else 00265 { 00266 DebugTrace(DEBUG_TRACE_MISC, "*** FCB acquired [Close]", 0); 00267 PtrResourceAcquired = & ( PtrReqdFCB->MainResource ); 00268 } 00269 i *= 10; 00270 } 00271 00272 i = 1; 00273 while( !PtrPagingIoResourceAcquired ) 00274 { 00275 DebugTraceState( "FCBPaging AC:0x%LX EX:0x%LX SW:0x%LX [Close]", PtrReqdFCB->PagingIoResource.ActiveCount, PtrReqdFCB->PagingIoResource.NumberOfExclusiveWaiters, PtrReqdFCB->PagingIoResource.NumberOfSharedWaiters ); 00276 if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->PagingIoResource), FALSE ) ) 00277 { 00278 DebugTrace(DEBUG_TRACE_MISC, "*** FCB Acquisition FAILED [Close]", 0); 00279 if( BlockForResource && i != 1000 ) 00280 { 00281 LARGE_INTEGER Delay; 00282 00283 // KeSetPriorityThread( PsGetCurrentThread(), LOW_REALTIME_PRIORITY ); 00284 00285 Delay.QuadPart = -500 * i; 00286 KeDelayExecutionThread( KernelMode, FALSE, &Delay ); 00287 DebugTrace(DEBUG_TRACE_MISC, "*** Retrying... after 50 * %ld ms [Close]", i); 00288 } 00289 else 00290 { 00291 if( i == 1000 ) 00292 DebugTrace(DEBUG_TRACE_MISC, "*** Reposting... [Close]", 0 ); 00293 PostRequest = TRUE; 00294 try_return( RC = STATUS_PENDING ); 00295 } 00296 } 00297 else 00298 { 00299 DebugTrace(DEBUG_TRACE_MISC, "*** FCB acquired [Close]", 0); 00300 PtrPagingIoResourceAcquired = & ( PtrReqdFCB->PagingIoResource ); 00301 } 00302 i *= 10; 00303 } 00304 00305 // (c) Delete the CCB structure (free memory) 00306 RemoveEntryList( &PtrCCB->NextCCB ); 00307 Ext2ReleaseCCB( PtrCCB ); 00308 PtrFileObject->FsContext2 = NULL; 00309 00310 // (d) Decrementing the Reference Count... 00311 if( PtrFCB->ReferenceCount ) 00312 { 00313 InterlockedDecrement( &PtrFCB->ReferenceCount ); 00314 } 00315 else 00316 { 00317 Ext2BreakPoint(); 00318 } 00319 DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^ReferenceCount = 0x%lX [Close]", PtrFCB->ReferenceCount ); 00320 DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^OpenHandleCount = 0x%lX [Close]", PtrFCB->OpenHandleCount ); 00321 if( PtrFCB->ReferenceCount == 0 ) 00322 { 00323 00324 // Attempting to update time stamp values 00325 // Errors are ignored... 00326 // Not considered as critical errors... 00327 00328 { 00329 ULONG CreationTime, AccessTime, ModificationTime; 00330 EXT2_INODE Inode; 00331 00332 CreationTime = (ULONG) ( (PtrFCB->CreationTime.QuadPart 00333 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00334 AccessTime = (ULONG) ( (PtrFCB->LastAccessTime.QuadPart 00335 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00336 ModificationTime = (ULONG) ( (PtrFCB->LastWriteTime.QuadPart 00337 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00338 if( NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) ) 00339 { 00340 // Update time stamps in the inode... 00341 Inode.i_ctime = CreationTime; 00342 Inode.i_atime = AccessTime; 00343 Inode.i_mtime = ModificationTime; 00344 00345 // Updating the inode... 00346 Ext2WriteInode( NULL, PtrVCB, PtrFCB->INodeNo, &Inode ); 00347 } 00348 } 00349 00350 00351 if( PtrFCB->INodeNo == EXT2_ROOT_INO ) 00352 { 00353 // 00354 // Root Directory FCB 00355 // Preserve this 00356 // FSD has a File Object for this FCB... 00357 // 00358 DebugTrace(DEBUG_TRACE_MISC, "^^^^^Root Directory FCB ; leaveing it alone[Close]", 0); 00359 // Do nothing... 00360 00361 } 00362 else if( PtrFCB->DcbFcb.Dcb.PtrDirFileObject ) 00363 { 00364 // 00365 // If this is a FCB created on the FSD's initiative 00366 // Leave it alone 00367 // 00368 DebugTrace(DEBUG_TRACE_MISC, "^^^^^FCB Created on the FSD's initiative; leaveing it alone[Close]", 0); 00369 if( !PtrFCB->ClosableFCBs.OnClosableFCBList ) 00370 { 00371 InsertTailList( &PtrVCB->ClosableFCBs.ClosableFCBListHead, 00372 &PtrFCB->ClosableFCBs.ClosableFCBList ); 00373 PtrVCB->ClosableFCBs.Count++; 00374 00375 PtrFCB->ClosableFCBs.OnClosableFCBList = TRUE; 00376 } 00377 00378 if( PtrVCB->ClosableFCBs.Count > EXT2_MAXCLOSABLE_FCBS_UL ) 00379 { 00380 PtrExt2FCB PtrTempFCB = NULL; 00381 // Checking if Closable FCBs are too many in number... 00382 // Shouldn't block the 00383 // Should do this asynchronously... 00384 // Maybe later... 00385 PLIST_ENTRY PtrEntry = NULL; 00386 00387 PtrEntry = RemoveHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead ); 00388 00389 PtrTempFCB = CONTAINING_RECORD( PtrEntry, Ext2FCB, ClosableFCBs.ClosableFCBList ); 00390 if( Ext2CloseClosableFCB( PtrTempFCB ) ) 00391 { 00392 DebugTrace( DEBUG_TRACE_FREE, "Freeing = %lX [Close]", PtrTempFCB ); 00393 ExFreePool( PtrTempFCB ); 00394 PtrVCB->ClosableFCBs.Count--; 00395 } 00396 else 00397 { 00398 // Put the FCB back in the list... 00399 InsertHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead, 00400 &PtrTempFCB->ClosableFCBs.ClosableFCBList ); 00401 } 00402 DebugTrace( DEBUG_TRACE_SPECIAL, "ClosableFCBs Count = %ld [Close]", PtrVCB->ClosableFCBs.Count ); 00403 } 00404 } 00405 else 00406 { 00407 // Remove this FCB as well... 00408 DebugTrace(DEBUG_TRACE_MISC, "^^^^^Deleting FCB [Close]", 0); 00409 RemoveEntryList( &PtrFCB->NextFCB ); 00410 00411 if ( PtrPagingIoResourceAcquired ) 00412 { 00413 Ext2ReleaseResource(PtrPagingIoResourceAcquired); 00414 DebugTraceState( "Resource AC:0x%LX EX:0x%LX SW:0x%LX [Close]", 00415 PtrPagingIoResourceAcquired->ActiveCount, 00416 PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters, 00417 PtrPagingIoResourceAcquired->NumberOfSharedWaiters ); 00418 00419 PtrPagingIoResourceAcquired = NULL; 00420 } 00421 00422 if ( PtrResourceAcquired ) 00423 { 00424 Ext2ReleaseResource(PtrResourceAcquired); 00425 DebugTrace(DEBUG_TRACE_MISC, "*** FCB Released [Close]", 0); 00426 DebugTraceState( "Resource AC:0x%LX EX:0x%LX SW:0x%LX [Close]", 00427 PtrResourceAcquired->ActiveCount, 00428 PtrResourceAcquired->NumberOfExclusiveWaiters, 00429 PtrResourceAcquired->NumberOfSharedWaiters ); 00430 00431 if( PtrFileObject ) 00432 { 00433 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00434 } 00435 PtrResourceAcquired = NULL; 00436 } 00437 00438 Ext2ReleaseFCB( PtrFCB ); 00439 } 00440 00441 } 00442 CompleteIrp = TRUE; 00443 } 00444 else 00445 { 00446 // This must be a volume close... 00447 // What do I do now? ;) 00448 DebugTrace(DEBUG_TRACE_MISC, "VCB Close Requested !!!", 0); 00449 CompleteIrp = TRUE; 00450 } 00451 try_return(); 00452 00453 try_exit: NOTHING; 00454 00455 } 00456 finally 00457 { 00458 if ( PtrPagingIoResourceAcquired ) 00459 { 00460 Ext2ReleaseResource(PtrPagingIoResourceAcquired); 00461 DebugTraceState( "Resource AC:0x%LX EX:0x%LX SW:0x%LX [Close]", 00462 PtrPagingIoResourceAcquired->ActiveCount, 00463 PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters, 00464 PtrPagingIoResourceAcquired->NumberOfSharedWaiters ); 00465 00466 PtrPagingIoResourceAcquired = NULL; 00467 } 00468 00469 if ( PtrResourceAcquired ) 00470 { 00471 Ext2ReleaseResource(PtrResourceAcquired); 00472 DebugTrace(DEBUG_TRACE_MISC, "*** FCB Released [Close]", 0); 00473 DebugTraceState( "Resource AC:0x%LX EX:0x%LX SW:0x%LX [Close]", 00474 PtrResourceAcquired->ActiveCount, 00475 PtrResourceAcquired->NumberOfExclusiveWaiters, 00476 PtrResourceAcquired->NumberOfSharedWaiters ); 00477 00478 if( PtrFileObject ) 00479 { 00480 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00481 } 00482 PtrResourceAcquired = NULL; 00483 } 00484 00485 if (AcquiredVCB) 00486 { 00487 ASSERT(PtrVCB); 00488 Ext2ReleaseResource(&(PtrVCB->VCBResource)); 00489 DebugTraceState( "VCB AC:0x%LX EX:0x%LX SW:0x%LX [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters ); 00490 DebugTrace(DEBUG_TRACE_MISC, "*** VCB Released [Close]", 0); 00491 00492 AcquiredVCB = FALSE; 00493 if( PtrFileObject ) 00494 { 00495 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject); 00496 } 00497 00498 } 00499 00500 if( PostRequest ) 00501 { 00502 RC = Ext2PostRequest(PtrIrpContext, PtrIrp); 00503 } 00504 else if( CompleteIrp && RC != STATUS_PENDING ) 00505 { 00506 // complete the IRP 00507 IoCompleteRequest( PtrIrp, IO_DISK_INCREMENT ); 00508 00509 Ext2ReleaseIrpContext( PtrIrpContext ); 00510 } 00511 00512 } // end of "finally" processing 00513 00514 return(RC); 00515 } Generated on Sat May 26 2012 04:26:04 for ReactOS by
1.7.6.1
|