ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cleanup.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.