test: udfs/cleanup.c File Reference

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

# cleanup.c File Reference

`#include "UdfProcs.h"`

Go to the source code of this file.

## Defines

#define | BugCheckFileId (UDFS_BUG_CHECK_CLEANUP)
#define | Dbg (UDFS_DEBUG_LEVEL_CLEANUP)

## Functions

NTSTATUS | UdfCommonCleanup (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)

## Define Documentation

#define BugCheckFileId (UDFS_BUG_CHECK_CLEANUP)

| Definition at line 28 of file udfs/cleanup.c.

#define Dbg (UDFS_DEBUG_LEVEL_CLEANUP)

| Definition at line 34 of file udfs/cleanup.c.

## Function Documentation

NTSTATUS UdfCommonCleanup | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PIRP | Irp
| ) |

Definition at line 42 of file udfs/cleanup.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, CcUninitializeCacheMap(), ClearFlag, Dbg, DebugTrace, _VCB::DirNotifyList, FALSE, _FILE_OBJECT::Flags, FO_CLEANUP_COMPLETE, FSRTL_VOLUME_UNLOCK, FsRtlCheckOplock(), FsRtlFastUnlockAll(), FsRtlNotifyCleanup(), FsRtlNotifyVolumeEvent(), IoGetCurrentIrpStackLocation, IoGetRequestorProcess(), IoRemoveShareAccess(), Irp, _VCB::NotifySync, NULL, PAGED_CODE, PCCB, SetFlag, _FCB::ShareAccess, StreamFileOpen, TRUE, TYPE_OF_OPEN, UdfAcquireFcbExclusive, UdfAcquireVcbExclusive, UdfBugCheck, UdfCompleteRequest(), UdfDecodeFileObject(), UdfDecrementCleanupCounts, UdfIsFastIoPossible, UdfLockFcb, UdfLockVcb, UdfPurgeVolume(), UdfReleaseFcb, UdfReleaseVcb, UdfUnlockFcb, UdfUnlockVcb, UserDirectoryOpen, UserFileOpen, UserVolumeOpen, _FCB::Vcb, VCB_STATE_LOCKED, _VCB::VcbCleanup, _VCB::VcbCondition, VcbNotMounted, _VCB::VcbState, and _VCB::VolumeLockFileObject.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

    00049                    :
    00050
    00051     This is the common routine for cleanup of a file/directory called by both
    00052     the fsd and fsp threads.
    00053
    00054     Cleanup is invoked whenever the last handle to a file object is closed.
    00055     This is different than the Close operation which is invoked when the last
    00056     reference to a file object is deleted.
    00057
    00058     The function of cleanup is to essentially "cleanup" the file/directory
    00059     after a user is done with it.  The Fcb/Dcb remains around (because MM
    00060     still has the file object referenced) but is now available for another
    00061     user to open (i.e., as far as the user is concerned the is now closed).
    00062
    00063     See close for a more complete description of what close does.
    00064
    00065     We do no synchronization in this routine until we get to the point
    00066     where we modify the counts, share access and volume lock field.
    00067
    00068     We need to update the Fcb and Vcb to show that a user handle has been closed.
    00069     The following structures and fields are affected.
    00070
    00071     Vcb:
    00072
    00073         VolumeLockFileObject - Did the user lock the volume with this file object.
    00074         VcbState - Check if we are unlocking the volume here.
    00075         VcbCleanup - Count of outstanding handles on the volume.
    00076         DirNotifyQueue - If this file object has pending DirNotify Irps.
    00077
    00078     Fcb:
    00079
    00080         ShareAccess - If this is a user handle.
    00081         FcbCleanup - Count of outstanding handles on this Fcb.
    00082         Oplock - Any outstanding oplocks on this file object.
    00083         FileLock - Any outstanding filelocks on this file object.
    00084
    00085 Arguments:
    00086
    00087     Irp - Supplies the Irp to process
    00088
    00089 Return Value:
    00090
    00091     NTSTATUS - The return status for the operation.
    00092
    00093 --*/
    00094
    00095 {
    00096     PFILE_OBJECT FileObject;
    00097     TYPE_OF_OPEN TypeOfOpen;
    00098
    00099     BOOLEAN SendUnlockNotification = FALSE;
    00100     BOOLEAN AttemptTeardown;
    00101
    00102     PVCB Vcb;
    00103     PFCB Fcb;
    00104     PCCB Ccb;
    00105
    00106     PAGED_CODE();
    00107
    00108     ASSERT_IRP_CONTEXT( IrpContext );
    00109     ASSERT_IRP( Irp );
    00110
    00111     //
    00112     //  If we were called with our file system device object instead of a
    00113     //  volume device object, just complete this request with STATUS_SUCCESS.
    00114     //
    00115
    00116     if (IrpContext->Vcb == NULL) {
    00117
    00118         UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
    00119         return STATUS_SUCCESS;
    00120     }
    00121
    00122     //
    00123     //  Get the file object out of the Irp and decode the type of open.
    00124     //
    00125
    00126     FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject;
    00127
    00128     TypeOfOpen = UdfDecodeFileObject( FileObject,
    00129                                       &Fcb,
    00130                                       &Ccb );
    00131
    00132     //
    00133     //  No work here for either an UnopenedFile object or a StreamFileObject.
    00134     //
    00135
    00136     if (TypeOfOpen <= StreamFileOpen) {
    00137
    00138         UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
    00139
    00140         return STATUS_SUCCESS;
    00141     }
    00142
    00143     //
    00144     //  Keep a local pointer to the Vcb.
    00145     //
    00146
    00147     Vcb = Fcb->Vcb;
    00148
    00149     //
    00150     //  Acquire the current file.
    00151     //
    00152
    00153     UdfAcquireFcbExclusive( IrpContext, Fcb, FALSE );
    00154
    00155     //
    00156     //  Use a try-finally to facilitate cleanup.
    00157     //
    00158
    00159     try {
    00160
    00161         //
    00162         //  Set the flag in the FileObject to indicate that cleanup is complete.
    00163         //
    00164
    00165         SetFlag( FileObject->Flags, FO_CLEANUP_COMPLETE );
    00166
    00167         //
    00168         //  Case on the type of open that we are trying to cleanup.
    00169         //
    00170
    00171         switch (TypeOfOpen) {
    00172
    00173         case UserDirectoryOpen:
    00174
    00175             DebugTrace(( +1, Dbg,
    00176                          "UdfCommonCleanup, Fcb %08x FO %08x DIR\n",
    00177                          Fcb,
    00178                          FileObject ));
    00179
    00180             //
    00181             //  Check if we need to complete any dir notify Irps on this file object.
    00182             //
    00183
    00184             FsRtlNotifyCleanup( Vcb->NotifySync,
    00185                                 &Vcb->DirNotifyList,
    00186                                 Ccb );
    00187
    00188             break;
    00189
    00190         case UserFileOpen:
    00191
    00192             DebugTrace(( +1, Dbg,
    00193                          "UdfCommonCleanup, Fcb %08x FO %08x FILE\n",
    00194                          Fcb,
    00195                          FileObject ));
    00196
    00197             //
    00198             //  Coordinate the cleanup operation with the oplock state.
    00199             //  Oplock cleanup operations can always cleanup immediately so no
    00200             //  need to check for STATUS_PENDING.
    00201             //
    00202
    00203             FsRtlCheckOplock( &Fcb->Oplock,
    00204                               Irp,
    00205                               IrpContext,
    00206                               NULL,
    00207                               NULL );
    00208
    00209             //
    00210             //  Unlock all outstanding file locks.
    00211             //
    00212
    00213             if (Fcb->FileLock != NULL) {
    00214
    00215                 FsRtlFastUnlockAll( Fcb->FileLock,
    00216                                     FileObject,
    00217                                     IoGetRequestorProcess( Irp ),
    00218                                     NULL );
    00219             }
    00220
    00221             //
    00222             //  Cleanup the cache map.
    00223             //
    00224
    00225             CcUninitializeCacheMap( FileObject, NULL, NULL );
    00226
    00227             //
    00228             //  Check the fast io state.
    00229             //
    00230
    00231             UdfLockFcb( IrpContext, Fcb );
    00232             Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb );
    00233             UdfUnlockFcb( IrpContext, Fcb );
    00234
    00235             break;
    00236
    00237         case UserVolumeOpen :
    00238
    00239             DebugTrace(( +1, Dbg,
    00240                          "UdfCommonCleanup, Fcb %08x FO %08x VOL\n",
    00241                          Fcb,
    00242                          FileObject ));
    00243
    00244             break;
    00245
    00246         default :
    00247
    00248             UdfBugCheck( TypeOfOpen, 0, 0 );
    00249         }
    00250
    00251         //
    00252         //  Now lock the Vcb in order to modify the fields in the in-memory
    00253         //  structures.
    00254         //
    00255
    00256         UdfLockVcb( IrpContext, Vcb );
    00257
    00258         //
    00259         //  Decrement the cleanup counts in the Vcb and Fcb.
    00260         //
    00261
    00262         UdfDecrementCleanupCounts( IrpContext, Fcb );
    00263
    00264         //
    00265         //  If the cleanup count hit zero and the volume is not mounted, we
    00266         //  will want to try to spark teardown.
    00267         //
    00268
    00269         AttemptTeardown = (Vcb->VcbCleanup == 0 && Vcb->VcbCondition == VcbNotMounted);
    00270
    00271         //
    00272         //  If this file object has locked the volume then perform the unlock operation.
    00273         //
    00274
    00275         if (FileObject == Vcb->VolumeLockFileObject) {
    00276
    00277             ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED );
    00278             Vcb->VolumeLockFileObject = NULL;
    00279             SendUnlockNotification = TRUE;
    00280         }
    00281
    00282         UdfUnlockVcb( IrpContext, Vcb );
    00283
    00284         //
    00285         //  We must clean up the share access at this time, since we may not
    00286         //  get a Close call for awhile if the file was mapped through this
    00287         //  File Object.
    00288         //
    00289
    00290         IoRemoveShareAccess( FileObject, &Fcb->ShareAccess );
    00291
    00292     } finally {
    00293
    00294         UdfReleaseFcb( IrpContext, Fcb );
    00295
    00296         if (SendUnlockNotification) {
    00297
    00298             FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK );
    00299         }
    00300     }
    00301
    00302     DebugTrace(( -1, Dbg,
    00303                  "UdfCommonCleanup, Fcb %08x FO %08x -> SUCCESS\n",
    00304                  Fcb,
    00305                  FileObject ));
    00306
    00307     //
    00308     //  If appropriate, try to spark teardown by purging the volume.  Should
    00309     //  this very fileobject we were cleaning up be the last reason for the
    00310     //  volume to remain, teardown will commence on completion of this Irp.
    00311     //
    00312
    00313     if (AttemptTeardown) {
    00314
    00315         UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE );
    00316
    00317         try {
    00318
    00319             UdfPurgeVolume( IrpContext, Vcb, FALSE );
    00320
    00321         } finally {
    00322
    00323             UdfReleaseVcb( IrpContext, Vcb );
    00324         }
    00325     }
    00326
    00327     //
    00328     //  If this is a normal termination then complete the request
    00329     //
    00330
    00331     UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
    00332
    00333     return STATUS_SUCCESS;
    00334 }