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 }


Generated on Sat May 15 19:43:04 2004 for test by doxygen 1.3.7