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

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

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