ReactOS  0.4.13-dev-551-gf37fb1f
cleanup.c File Reference
#include "cdprocs.h"
Include dependency graph for cleanup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_CLEANUP)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_CLEANUP)

Definition at line 23 of file cleanup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 25 of file cleanup.c.

80 {
83 
84  BOOLEAN SendUnlockNotification = FALSE;
85  BOOLEAN AttemptTeardown = FALSE;
86  BOOLEAN VcbAcquired = FALSE;
87 
88  PVCB Vcb;
89  PFCB Fcb;
90  PCCB Ccb;
91 
92  KIRQL SavedIrql;
93 
94  ASSERT_IRP_CONTEXT( IrpContext );
95  ASSERT_IRP( Irp );
96 
97  //
98  // If we were called with our file system device object instead of a
99  // volume device object, just complete this request with STATUS_SUCCESS.
100  //
101 
102  if (IrpContext->Vcb == NULL) {
103 
104  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
105  return STATUS_SUCCESS;
106  }
107 
108  //
109  // Get the file object out of the Irp and decode the type of open.
110  //
111 
113 
114  TypeOfOpen = CdDecodeFileObject( IrpContext,
115  FileObject,
116  &Fcb,
117  &Ccb );
118 
119  //
120  // No work here for either an UnopenedFile object or a StreamFileObject.
121  //
122 
123  if (TypeOfOpen <= StreamFileOpen) {
124 
125  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
126 
127  return STATUS_SUCCESS;
128  }
129 
130  //
131  // Keep a local pointer to the Vcb.
132  //
133 
134  Vcb = Fcb->Vcb;
135 
136  //
137  // Synchronise with reads while we set the cleanup complete
138  // flag on this fileobject. Once this flag is set, any further
139  // reads will be rejected (CdVerifyFcbOperation)
140  //
141 
142  CdAcquireFileExclusive( IrpContext, Fcb);
143 
144  //
145  // Set the flag in the FileObject to indicate that cleanup is complete.
146  //
147 
149 
150  CdReleaseFile( IrpContext, Fcb);
151 
152  if (TypeOfOpen == UserVolumeOpen) {
153 
154  //
155  // For a force dismount, physically disconnect this Vcb from the device so
156  // a new mount can occur. Vcb deletion cannot happen at this time since
157  // there is a reference on it associated with this very request, but we'll
158  // call check for dismount again later after we process this close.
159  //
160 
162 
163  CdAcquireCdData( IrpContext );
164 
165  CdCheckForDismount( IrpContext, Vcb, TRUE );
166 
167  CdReleaseCdData( IrpContext );
168 
169  //
170  // If this handle actually wrote something, flush the device buffers,
171  // and then set the verify bit now just to be safe (in case there is no
172  // dismount).
173  //
174 
175  } else if (FlagOn( FileObject->Flags, FO_FILE_MODIFIED )) {
176 
177  CdHijackIrpAndFlushDevice( IrpContext, Irp, Vcb->TargetDeviceObject );
178 
180  }
181  }
182 
183  //
184  // Acquire the current file.
185  //
186 
187  CdAcquireFcbExclusive( IrpContext, Fcb, FALSE );
188 
189  //
190  // Use a try-finally to facilitate cleanup.
191  //
192 
193  _SEH2_TRY {
194 
195  //
196  // Case on the type of open that we are trying to cleanup.
197  //
198 
199  switch (TypeOfOpen) {
200 
201  case UserDirectoryOpen:
202 
203  //
204  // Check if we need to complete any dir notify Irps on this file object.
205  //
206 
207  FsRtlNotifyCleanup( Vcb->NotifySync,
208  &Vcb->DirNotifyList,
209  Ccb );
210 
211  break;
212 
213  case UserFileOpen:
214 
215  //
216  // Coordinate the cleanup operation with the oplock state.
217  // Oplock cleanup operations can always cleanup immediately so no
218  // need to check for STATUS_PENDING.
219  //
220 
222  Irp,
223  IrpContext,
224  NULL,
225  NULL );
226 
227  //
228  // Unlock all outstanding file locks.
229  //
230 
231  if (Fcb->FileLock != NULL) {
232 
234  FileObject,
236  NULL );
237  }
238 
239  //
240  // Cleanup the cache map.
241  //
242 
244 
245  //
246  // Check the fast io state.
247  //
248 
249  CdLockFcb( IrpContext, Fcb );
250  Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
251  CdUnlockFcb( IrpContext, Fcb );
252 
253  break;
254 
255  case UserVolumeOpen:
256 
257  break;
258 
259  default :
260 
261 #ifdef _MSC_VER
262 #pragma prefast( suppress:__WARNING_USE_OTHER_FUNCTION, "argument bogus" )
263 #endif
264  CdBugCheck( TypeOfOpen, 0, 0 );
265  }
266 
267  //
268  // Now lock the Vcb in order to modify the fields in the in-memory
269  // structures.
270  //
271 
272  CdLockVcb( IrpContext, Vcb );
273 
274  //
275  // Decrement the cleanup counts in the Vcb and Fcb.
276  //
277 
278  CdDecrementCleanupCounts( IrpContext, Fcb );
279 
280  //
281  // If the cleanup count hit zero and the volume is not mounted, we
282  // will want to try to spark teardown.
283  //
284 
285  AttemptTeardown = (Vcb->VcbCleanup == 0 && Vcb->VcbCondition == VcbNotMounted);
286 
287  //
288  // If this file object has locked the volume then perform the unlock operation.
289  // We do this regardless of explicit or implicit (no share DASD open) lock.
290  //
291 
292  if (FileObject == Vcb->VolumeLockFileObject) {
293 
294  NT_ASSERT( FlagOn( Vcb->VcbState, VCB_STATE_LOCKED));
295 
296  IoAcquireVpbSpinLock( &SavedIrql );
297 
298  ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED);
299  ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED );
300  Vcb->VolumeLockFileObject = NULL;
301  SendUnlockNotification = TRUE;
302 
303  IoReleaseVpbSpinLock( SavedIrql );
304  }
305 
306  CdUnlockVcb( IrpContext, Vcb );
307 
308  //
309  // We must clean up the share access at this time, since we may not
310  // get a Close call for awhile if the file was mapped through this
311  // File Object.
312  //
313 
315 
316  } _SEH2_FINALLY {
317 
318  CdReleaseFcb( IrpContext, Fcb );
319 
320  if (SendUnlockNotification) {
321 
323  }
324  } _SEH2_END;
325 
326  //
327  // If appropriate, try to spark teardown by purging the volume. Should
328  // this very fileobject we were cleaning up be the last reason for the
329  // volume to remain, teardown will commence on completion of this Irp.
330  //
331 
332  if (AttemptTeardown) {
333 
334  //
335  // Preacquire CdData here, since the purges will generate closes which
336  // may acquire CdData if there is a possibility of tearing the volume
337  // down.
338  //
339 
340  CdAcquireCdData( IrpContext);
341 
342  _SEH2_TRY {
343 
344  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
345  VcbAcquired = TRUE;
346 
347  CdPurgeVolume( IrpContext, Vcb, FALSE );
348 
349  } _SEH2_FINALLY {
350 
351  if (VcbAcquired) { CdReleaseVcb( IrpContext, Vcb ); }
352 
353  CdReleaseCdData( IrpContext);
354  } _SEH2_END;
355  }
356 
357  //
358  // If this is a normal termination then complete the request
359  //
360 
361  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
362 
363  return STATUS_SUCCESS;
364 }
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1782
FILE_LOCK FileLock
Definition: fatstruc.h:1067
#define TRUE
Definition: types.h:120
#define CCB_FLAG_DISMOUNT_ON_CLOSE
Definition: cdstruc.h:1113
#define CdReleaseFile(IC, F)
Definition: cdprocs.h:1008
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
Definition: cdstruc.h:1073
#define CdReleaseFcb(IC, F)
Definition: cdprocs.h:1017
#define FSRTL_VOLUME_UNLOCK
Definition: ntifs_ex.h:443
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
Definition: cdstruc.h:504
#define CdAcquireFcbExclusive(IC, F, I)
Definition: cdprocs.h:1011
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3477
#define CdBugCheck(A, B, C)
Definition: nodetype.h:103
#define CdUnlockFcb(IC, F)
Definition: cdprocs.h:1065
_SEH2_TRY
Definition: create.c:4250
VOID NTAPI FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext)
Definition: notify.c:635
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FO_FILE_MODIFIED
Definition: iotypes.h:1744
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
#define CdGetFcbOplock(F)
Definition: cdprocs.h:1086
#define ASSERT_IRP_CONTEXT(IC)
Definition: cddata.h:249
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define VPB_LOCKED
Definition: iotypes.h:1764
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define VCB_STATE_LOCKED
Definition: cdstruc.h:715
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define CdAcquireVcbExclusive(IC, V, I)
Definition: cdprocs.h:984
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1015
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
Definition: pnp.c:38
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:990
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1033
#define Vcb
Definition: cdprocs.h:1425
* PFILE_OBJECT
Definition: iotypes.h:1954
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1028
ULONG Flags
Definition: ntfs.h:520
#define CdIsFastIoPossible(F)
Definition: cdprocs.h:2025
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1026
#define CdAcquireCdData(IC)
Definition: cdprocs.h:978
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define ASSERT_IRP(I)
Definition: cddata.h:251
#define CdLockFcb(IC, F)
Definition: cdprocs.h:1049
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1746
_SEH2_FINALLY
Definition: create.c:4395
#define CdReleaseCdData(IC)
Definition: cdprocs.h:981
NTSTATUS CdHijackIrpAndFlushDevice(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp, _In_ PDEVICE_OBJECT TargetDeviceObject)
Definition: deviosup.c:4105
#define CdAcquireFileExclusive(IC, F)
Definition: cdprocs.h:999
PVCB Vcb
Definition: cdstruc.h:939
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1172
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2777
BOOLEAN CdMarkDevForVerifyIfVcbMounted(_Inout_ PVCB Vcb)
Definition: verfysup.c:359
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
#define CdDecrementCleanupCounts(IC, F)
Definition: cdprocs.h:1316
#define NT_ASSERT
Definition: rtlfuncs.h:3312