Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencleanup.c
Go to the documentation of this file.
00001 /************************************************************************* 00002 * 00003 * File: cleanup.c 00004 * 00005 * Module: Ext2 File System Driver (Kernel mode execution only) 00006 * 00007 * Description: 00008 * Should contain code to handle the "Cleanup" 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_CLEANUP 00021 #define DEBUG_LEVEL (DEBUG_TRACE_CLEANUP) 00022 00023 00024 /************************************************************************* 00025 * 00026 * Function: Ext2Cleanup() 00027 * 00028 * Description: 00029 * The I/O Manager will invoke this routine to handle a cleanup 00030 * request 00031 * 00032 * Expected Interrupt Level (for execution) : 00033 * 00034 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution 00035 * to be deferred to a worker thread context) 00036 * 00037 * Return Value: Does not matter! 00038 * 00039 *************************************************************************/ 00040 NTSTATUS NTAPI Ext2Cleanup( 00041 PDEVICE_OBJECT DeviceObject, // the logical volume device object 00042 PIRP Irp) // I/O Request Packet 00043 { 00044 NTSTATUS RC = STATUS_SUCCESS; 00045 PtrExt2IrpContext PtrIrpContext = NULL; 00046 BOOLEAN AreWeTopLevel = FALSE; 00047 00048 DebugTrace( DEBUG_TRACE_IRP_ENTRY, "Cleanup IRP Received...", 0); 00049 00050 FsRtlEnterFileSystem(); 00051 ASSERT(DeviceObject); 00052 ASSERT(Irp); 00053 00054 // set the top level context 00055 AreWeTopLevel = Ext2IsIrpTopLevel(Irp); 00056 00057 try 00058 { 00059 00060 // get an IRP context structure and issue the request 00061 PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject); 00062 ASSERT(PtrIrpContext); 00063 00064 RC = Ext2CommonCleanup(PtrIrpContext, Irp, TRUE); 00065 00066 } 00067 except( Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation() ) ) 00068 { 00069 00070 RC = Ext2ExceptionHandler(PtrIrpContext, Irp); 00071 00072 Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC); 00073 } 00074 00075 if (AreWeTopLevel) 00076 { 00077 IoSetTopLevelIrp(NULL); 00078 } 00079 00080 FsRtlExitFileSystem(); 00081 00082 return(RC); 00083 } 00084 00085 /************************************************************************* 00086 * 00087 * Function: Ext2CommonCleanup() 00088 * 00089 * Description: 00090 * The actual work is performed here. This routine may be invoked in one' 00091 * of the two possible contexts: 00092 * (a) in the context of a system worker thread 00093 * (b) in the context of the original caller 00094 * 00095 * Expected Interrupt Level (for execution) : 00096 * 00097 * IRQL_PASSIVE_LEVEL 00098 * 00099 * Return Value: Does not matter! 00100 * 00101 *************************************************************************/ 00102 NTSTATUS NTAPI Ext2CommonCleanup( 00103 PtrExt2IrpContext PtrIrpContext, 00104 PIRP PtrIrp, 00105 BOOLEAN FirstAttempt ) 00106 { 00107 00108 NTSTATUS RC = STATUS_SUCCESS; 00109 PIO_STACK_LOCATION PtrIoStackLocation = NULL; 00110 PFILE_OBJECT PtrFileObject = NULL; 00111 PtrExt2FCB PtrFCB = NULL; 00112 PtrExt2CCB PtrCCB = NULL; 00113 PtrExt2VCB PtrVCB = NULL; 00114 PtrExt2NTRequiredFCB PtrReqdFCB = NULL; 00115 PERESOURCE PtrResourceAcquired = NULL; 00116 00117 BOOLEAN CompleteIrp = TRUE; 00118 BOOLEAN PostRequest = FALSE; 00119 BOOLEAN AcquiredVCB = FALSE; 00120 BOOLEAN BlockForResource; 00121 int i = 1; 00122 00123 try 00124 { 00125 // First, get a pointer to the current I/O stack location 00126 PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp); 00127 ASSERT(PtrIoStackLocation); 00128 00129 PtrFileObject = PtrIoStackLocation->FileObject; 00130 ASSERT(PtrFileObject); 00131 00132 if( !PtrFileObject->FsContext2 ) 00133 { 00134 // This must be a Cleanup request received 00135 // as a result of IoCreateStreamFileObject 00136 // Only such a File object would have a NULL CCB 00137 00138 DebugTrace( DEBUG_TRACE_MISC, " === Cleanup with NULL CCB", 0); 00139 if( PtrFileObject ) 00140 { 00141 DebugTrace( DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject); 00142 } 00143 try_return(); 00144 } 00145 00146 00147 Ext2GetFCB_CCB_VCB_FromFileObject ( 00148 PtrFileObject, &PtrFCB, &PtrCCB, &PtrVCB ); 00149 00150 if( PtrFCB && PtrFCB->FCBName && PtrFCB->FCBName->ObjectName.Length && PtrFCB->FCBName->ObjectName.Buffer ) 00151 //if( PtrFileObject->FileName.Length && PtrFileObject->FileName.Buffer ) 00152 { 00153 DebugTrace( DEBUG_TRACE_FILE_NAME, " === Cleanup File Name : -%S-", PtrFCB->FCBName->ObjectName.Buffer ); 00154 } 00155 else 00156 { 00157 DebugTrace( DEBUG_TRACE_FILE_NAME, " === Cleanup Volume", 0); 00158 } 00159 00160 00161 PtrVCB = (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension); 00162 ASSERT(PtrVCB); 00163 ASSERT(PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB); 00164 00165 // (a) Acquiring the VCBResource Exclusively... 00166 // This is done to synchronise with the close and cleanup routines... 00167 BlockForResource = !FirstAttempt; 00168 if( !FirstAttempt ) 00169 { 00170 00171 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Going into a block to acquire VCB Exclusively [Cleanup]", 0); 00172 } 00173 else 00174 { 00175 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Attempting to acquire VCB Exclusively [Cleanup]", 0); 00176 } 00177 00178 if( PtrFileObject ) 00179 { 00180 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject); 00181 } 00182 00183 i = 1; 00184 while( !AcquiredVCB ) 00185 { 00186 DebugTraceState("VCB AC:0x%LX SW:0x%LX EX:0x%LX [Cleanup]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters ); 00187 if( ! ExAcquireResourceExclusiveLite( &(PtrVCB->VCBResource), FALSE ) ) 00188 { 00189 DebugTrace( DEBUG_TRACE_RESOURCE_ACQUIRE, "*** VCB Acquisition FAILED [Cleanup]", 0); 00190 if( BlockForResource && i != 1000 ) 00191 { 00192 LARGE_INTEGER Delay; 00193 Delay.QuadPart = -500 * i; 00194 KeDelayExecutionThread( KernelMode, FALSE, &Delay ); 00195 DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Retrying... after 50 * %ld ms [Cleanup]", i); 00196 } 00197 else 00198 { 00199 if( i == 1000 ) 00200 DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Reposting... [Cleanup]", 0 ); 00201 PostRequest = TRUE; 00202 try_return( RC = STATUS_PENDING ); 00203 } 00204 } 00205 else 00206 { 00207 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** VCB Acquired in [Cleanup]", 0); 00208 AcquiredVCB = TRUE; 00209 } 00210 i *= 10; 00211 } 00212 00213 00214 // (b) Acquire the file (FCB) exclusively 00215 if( PtrFCB && PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB ) 00216 { 00217 // This FCB is an FCB indeed. ;) 00218 // So acquiring it exclusively... 00219 // This is done to synchronise with read/write routines... 00220 if( !FirstAttempt ) 00221 { 00222 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Going into a block to acquire FCB Exclusively [Cleanup]", 0); 00223 } 00224 else 00225 { 00226 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Attempting to acquire FCB Exclusively [Cleanup]", 0); 00227 } 00228 if( PtrFileObject ) 00229 { 00230 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject); 00231 } 00232 00233 i = 1; 00234 while( !PtrResourceAcquired ) 00235 { 00236 PtrReqdFCB = &(PtrFCB->NTRequiredFCB); 00237 DebugTraceState( "FCBMain AC:0x%LX SW:0x%LX EX:0x%LX [Cleanup]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters ); 00238 if(! ExAcquireResourceExclusiveLite( &(PtrFCB->NTRequiredFCB.MainResource ), FALSE ) ) 00239 { 00240 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** FCB Acquisition FAILED [Cleanup]", 0); 00241 if( BlockForResource && i != 1000 ) 00242 { 00243 LARGE_INTEGER Delay; 00244 Delay.QuadPart = -500 * i; 00245 KeDelayExecutionThread( KernelMode, FALSE, &Delay ); 00246 DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Retrying... after 50 * %ld ms [Cleanup]", i); 00247 } 00248 else 00249 { 00250 if( i == 1000 ) 00251 DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Reposting... [Cleanup]", 0 ); 00252 PostRequest = TRUE; 00253 try_return( RC = STATUS_PENDING ); 00254 } 00255 } 00256 else 00257 { 00258 DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** FCB acquired [Cleanup]", 0); 00259 PtrResourceAcquired = & ( PtrFCB->NTRequiredFCB.MainResource ); 00260 } 00261 i *= 10; 00262 } 00263 00264 // (c) Flush file data to disk 00265 if ( PtrFileObject->PrivateCacheMap != NULL) 00266 { 00267 IO_STATUS_BLOCK Status; 00268 CcFlushCache( PtrFileObject->SectionObjectPointer, NULL, 0, &Status ); 00269 } 00270 00271 // (d) Talk to the FSRTL package (if you use it) about pending oplocks. 00272 // (e) Notify the FSRTL package (if you use it) for use with pending 00273 // notification IRPs 00274 // (f) Unlock byte-range locks (if any were acquired by process) 00275 00276 // (g) Attempting to update time stamp values 00277 // Errors are ignored... 00278 // Not considered as critical errors... 00279 00280 /* 00281 if( PtrFCB->OpenHandleCount == 1 ) 00282 { 00283 ULONG CreationTime, AccessTime, ModificationTime; 00284 EXT2_INODE Inode; 00285 00286 CreationTime = (ULONG) ( (PtrFCB->CreationTime.QuadPart 00287 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00288 AccessTime = (ULONG) ( (PtrFCB->LastAccessTime.QuadPart 00289 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00290 ModificationTime = (ULONG) ( (PtrFCB->LastWriteTime.QuadPart 00291 - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 ); 00292 if( NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) ) 00293 { 00294 // Update time stamps in the inode... 00295 Inode.i_ctime = CreationTime; 00296 Inode.i_atime = AccessTime; 00297 Inode.i_mtime = ModificationTime; 00298 00299 // Updating the inode... 00300 Ext2WriteInode( PtrIrpContext, PtrVCB, PtrFCB->INodeNo, &Inode ); 00301 } 00302 } 00303 */ 00304 00305 // (h) Inform the Cache Manager to uninitialize Cache Maps ... 00306 CcUninitializeCacheMap( PtrFileObject, NULL, NULL ); 00307 00308 // (i) Decrementing the Open Handle count... 00309 if( PtrFCB->OpenHandleCount ) 00310 { 00311 InterlockedDecrement( &PtrFCB->OpenHandleCount ); 00312 } 00313 else 00314 { 00315 Ext2BreakPoint(); 00316 } 00317 00318 PtrFCB->FCBFlags |= FO_CLEANUP_COMPLETE; 00319 00320 DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^ReferenceCount = 0x%lX [Cleanup]", PtrFCB->ReferenceCount ); 00321 DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^OpenHandleCount = 0x%lX [Cleanup]", PtrFCB->OpenHandleCount ); 00322 00323 // (j) Remove share access... 00324 // Will do that later ;) 00325 00326 // (k) Is this a close on delete file? 00327 // If so, delete the file... 00328 if( Ext2IsFlagOn( PtrFCB->FCBFlags, EXT2_FCB_DELETE_ON_CLOSE) && 00329 !PtrFCB->OpenHandleCount ) 00330 { 00331 // 00332 // Have to delete this file... 00333 // 00334 Ext2DeleteFile( PtrFCB, PtrIrpContext ); 00335 PtrFCB->NTRequiredFCB.CommonFCBHeader.FileSize.QuadPart = 0; 00336 PtrFCB->INodeNo = 0; 00337 } 00338 } 00339 else 00340 { 00341 // This must be a volume close... 00342 // Just go ahead and complete this IRP... 00343 PtrVCB->VCBOpenCount--; 00344 DebugTrace(DEBUG_TRACE_MISC, "VCB Cleanup Requested !!!", 0); 00345 CompleteIrp = TRUE; 00346 } 00347 00348 try_return(); 00349 00350 try_exit: NOTHING; 00351 00352 } 00353 finally 00354 { 00355 if(PtrResourceAcquired) 00356 { 00357 Ext2ReleaseResource(PtrResourceAcquired); 00358 DebugTrace(DEBUG_TRACE_RESOURCE_RELEASE, "*** Resource Released [Cleanup]", 0); 00359 DebugTraceState( "Resource AC:0x%LX SW:0x%LX EX:0x%LX [Cleanup]", 00360 PtrResourceAcquired->ActiveCount, 00361 PtrResourceAcquired->NumberOfExclusiveWaiters, 00362 PtrResourceAcquired->NumberOfSharedWaiters ); 00363 00364 if( PtrFileObject ) 00365 { 00366 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject); 00367 } 00368 00369 } 00370 00371 if( AcquiredVCB ) 00372 { 00373 ASSERT(PtrVCB); 00374 Ext2ReleaseResource(&(PtrVCB->VCBResource)); 00375 DebugTrace(DEBUG_TRACE_RESOURCE_RELEASE, "*** VCB Released [Cleanup]", 0); 00376 DebugTraceState( "VCB AC:0x%LX SW:0x%LX EX:0x%LX [Cleanup]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters ); 00377 AcquiredVCB = FALSE; 00378 if( PtrFileObject ) 00379 { 00380 DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject); 00381 } 00382 00383 } 00384 00385 if( PostRequest ) 00386 { 00387 RC = Ext2PostRequest(PtrIrpContext, PtrIrp); 00388 } 00389 if( RC != STATUS_PENDING ) 00390 { 00391 Ext2ReleaseIrpContext( PtrIrpContext ); 00392 // complete the IRP 00393 IoCompleteRequest( PtrIrp, IO_DISK_INCREMENT ); 00394 } 00395 } // end of "finally" processing 00396 00397 return(RC); 00398 } Generated on Sun May 27 2012 04:21:23 for ReactOS by
1.7.6.1
|