ReactOS 0.4.16-dev-319-g6cf4263
cleanup.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: cleanup.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "ext2fs.h"
13
14/* GLOBALS ***************************************************************/
15
17
18/* DEFINITIONS *************************************************************/
19
22{
29 PIRP Irp = NULL;
31
32
33 BOOLEAN VcbResourceAcquired = FALSE;
34 BOOLEAN FcbResourceAcquired = FALSE;
35 BOOLEAN FcbPagingIoResourceAcquired = FALSE;
36 BOOLEAN SymLinkDelete = FALSE;
37
38 _SEH2_TRY {
39
40 ASSERT(IrpContext != NULL);
41 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
42 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
43
44 DeviceObject = IrpContext->DeviceObject;
48 }
49
50 Irp = IrpContext->Irp;
51 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
52 ASSERT(Vcb != NULL);
53 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
54 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
55
56 if (!IsVcbInited(Vcb)) {
59 }
60
61 FileObject = IrpContext->FileObject;
62 Fcb = (PEXT2_FCB) FileObject->FsContext;
63 if (!Fcb || (Fcb->Identifier.Type != EXT2VCB &&
67 }
68 Mcb = Fcb->Mcb;
69 Ccb = (PEXT2_CCB) FileObject->FsContext2;
70
74 }
75
76 if (Fcb->Identifier.Type == EXT2VCB) {
77
79 &Vcb->MainResource, TRUE);
80 VcbResourceAcquired = TRUE;
81
82 if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
83 Vcb->LockFile == FileObject ){
84
86 Vcb->LockFile = NULL;
88 }
89
90 if (Ccb) {
91 Ext2DerefXcb(&Vcb->OpenHandleCount);
92 Ext2DerefXcb(&Vcb->OpenVolumeCount);
93 }
94
95 IoRemoveShareAccess(FileObject, &Vcb->ShareAccess);
96
99 }
100
102 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
103
104 FcbResourceAcquired =
107 TRUE
108 );
109
111 if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
112 IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK) &&
113 !IsVcbReadOnly(Vcb) ) {
114 Status = Ext2FlushFile(IrpContext, Fcb, Ccb);
115 }
117 }
118
119 if (Ccb == NULL) {
122 }
123
124 if (IsDirectory(Fcb)) {
127
129 Vcb->NotifySync,
130 &Vcb->NotifyList,
131 Ccb,
132 NULL,
133 FALSE,
134 FALSE,
135 0,
136 NULL,
137 NULL,
138 NULL );
139 }
140
141 FsRtlNotifyCleanup(Vcb->NotifySync, &Vcb->NotifyList, Ccb);
142 }
143
145 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
146
147 Ext2DerefXcb(&Vcb->OpenHandleCount);
149
150 if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {
151 Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE;
152 }
153
154 if (IsDirectory(Fcb)) {
155
156 ext3_release_dir(Fcb->Inode, &Ccb->filp);
157
158 } else {
159
160 if ( IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
162
163 LARGE_INTEGER SysTime;
164 KeQuerySystemTime(&SysTime);
165
166 Fcb->Inode->i_atime =
167 Fcb->Inode->i_mtime = Ext2LinuxTime(SysTime);
168 Fcb->Mcb->LastAccessTime =
169 Fcb->Mcb->LastWriteTime = Ext2NtTime(Fcb->Inode->i_atime);
170
171 Ext2SaveInode(IrpContext, Vcb, Fcb->Inode);
172
174 IrpContext,
175 Vcb,
176 Fcb->Mcb,
181 }
182
183 FsRtlCheckOplock( &Fcb->Oplock,
184 Irp,
185 IrpContext,
186 NULL,
187 NULL );
188
189 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
190
191 if (!IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) {
192 Fcb->NonCachedOpenCount--;
193 }
194
196 if (Ccb->SymLink || IsInodeSymLink(&Mcb->Inode)) {
197 SymLinkDelete = TRUE;
198 } else {
200 }
201 }
202
203 //
204 // Drop any byte range locks this process may have on the file.
205 //
206
208 &Fcb->FileLockAnchor,
211 NULL );
212
213 //
214 // If there are no byte range locks owned by other processes on the
215 // file the fast I/O read/write functions doesn't have to check for
216 // locks so we set IsFastIoPossible to FastIoIsPossible again.
217 //
218 if (!FsRtlGetNextFileLock(&Fcb->FileLockAnchor, TRUE)) {
219 if (Fcb->Header.IsFastIoPossible != FastIoIsPossible) {
220#if EXT2_DEBUG
221 DEBUG(DL_INF, (": %-16.16s %-31s %wZ\n",
223 "FastIoIsPossible",
224 &Fcb->Mcb->FullName
225 ));
226#endif
227
228 Fcb->Header.IsFastIoPossible = FastIoIsPossible;
229 }
230 }
231
234
236 if (Fcb->Header.ValidDataLength.QuadPart < Fcb->Header.FileSize.QuadPart) {
237 if (!INODE_HAS_EXTENT(Fcb->Inode)) {
238 #if EXT2_PRE_ALLOCATION_SUPPORT
239 _SEH2_TRY {
241 &Fcb->Header.ValidDataLength,
242 &Fcb->Header.AllocationSize,
243 TRUE);
245 DbgBreak();
246 } _SEH2_END;
247 #endif
248 }
249 }
250 }
251
253
255
257 FcbPagingIoResourceAcquired = TRUE;
258
259 Size.QuadPart = CEILING_ALIGNED(ULONGLONG,
260 (ULONGLONG)Fcb->Mcb->Inode.i_size,
263
264 Ext2TruncateFile(IrpContext, Vcb, Fcb->Mcb, &Size);
265 Fcb->Header.AllocationSize = Size;
266 Fcb->Header.FileSize.QuadPart = Mcb->Inode.i_size;
267 if (Fcb->Header.ValidDataLength.QuadPart > Fcb->Header.FileSize.QuadPart)
268 Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
271 (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
272 }
273 }
276 FcbPagingIoResourceAcquired = FALSE;
277 }
278 }
279 }
280
282
283 if (!IsDirectory(Fcb)) {
284
285 if ( IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
286 (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount) &&
287 (Fcb->SectionObject.DataSectionObject != NULL)) {
288
289 if (!IsVcbReadOnly(Vcb)) {
290 CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
292 }
293
294 /* purge cache if all remaining openings are non-cached */
295 if (Fcb->NonCachedOpenCount > 0 ||
299 }
300
301 /* CcPurge could generate recursive IRP_MJ_CLOSE request */
302 CcPurgeCacheSection( &Fcb->SectionObject,
303 NULL,
304 0,
305 FALSE );
306 }
307 }
308
310 }
311
312 if (SymLinkDelete ||
314 Fcb->OpenHandleCount == 0) ) {
315
316 //
317 // Ext2DeleteFile will acquire these lock inside
318 //
319
320 if (FcbResourceAcquired) {
322 FcbResourceAcquired = FALSE;
323 }
324
325 //
326 // this file is to be deleted ...
327 //
328 if (Ccb->SymLink) {
329 Mcb = Ccb->SymLink;
330 FileObject->DeletePending = FALSE;
331 }
332
333 Status = Ext2DeleteFile(IrpContext, Vcb, Fcb, Mcb);
334
335 if (NT_SUCCESS(Status)) {
336 if (IsMcbDirectory(Mcb)) {
337 Ext2NotifyReportChange( IrpContext, Vcb, Mcb,
340 } else {
341 Ext2NotifyReportChange( IrpContext, Vcb, Mcb,
344 }
345 }
346
347 //
348 // re-acquire the main resource lock
349 //
350
351 FcbResourceAcquired =
354 TRUE
355 );
356 if (!SymLinkDelete) {
360 (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
361 }
362 }
363 }
364
365 DEBUG(DL_INF, ( "Ext2Cleanup: OpenCount=%u ReferCount=%u NonCahcedCount=%xh %wZ\n",
366 Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount, &Fcb->Mcb->FullName));
367
369
370 if (FileObject) {
372 }
373
374 } _SEH2_FINALLY {
375
376 if (FcbPagingIoResourceAcquired) {
378 }
379
380 if (FcbResourceAcquired) {
382 }
383
384 if (VcbResourceAcquired) {
385 ExReleaseResourceLite(&Vcb->MainResource);
386 }
387
388 if (!IrpContext->ExceptionInProgress) {
389 if (Status == STATUS_PENDING) {
390 Ext2QueueRequest(IrpContext);
391 } else {
392 IrpContext->Irp->IoStatus.Status = Status;
393 Ext2CompleteIrpContext(IrpContext, Status);
394 }
395 }
396 } _SEH2_END;
397
398 return Status;
399}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define CcIsFileCached(FO)
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define BLOCK_SIZE
Definition: dlist.c:220
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS Ext2Cleanup(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: cleanup.c:21
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define Ext2GetCurrentProcessName()
Definition: ext2fs.h:1489
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:789
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
@ EXT2FCB
Definition: ext2fs.h:463
@ EXT2ICX
Definition: ext2fs.h:465
@ EXT2VCB
Definition: ext2fs.h:462
@ EXT2CCB
Definition: ext2fs.h:464
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:814
NTSTATUS Ext2TruncateFile(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, PLARGE_INTEGER AllocationSize)
Definition: fileinfo.c:1204
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:552
NTSTATUS Ext2DeleteFile(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_FCB Fcb, PEXT2_MCB Mcb)
Definition: fileinfo.c:1920
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:616
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:158
#define FCB_ALLOC_IN_WRITE
Definition: ext2fs.h:885
#define SetLongFlag(_F, _SF)
Definition: ext2fs.h:258
#define DL_INF
Definition: ext2fs.h:1436
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:882
VOID Ext2ClearVpbFlag(IN PVPB Vpb, IN USHORT Flag)
Definition: fsctl.c:56
#define FCB_ALLOC_IN_SETINFO
Definition: ext2fs.h:886
ULONG Ext2LinuxTime(IN LARGE_INTEGER SysTime)
Definition: misc.c:51
#define ClearLongFlag(_F, _SF)
Definition: ext2fs.h:259
NTSTATUS Ext2FlushFile(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_FCB Fcb, IN PEXT2_CCB Ccb)
Definition: flush.c:58
VOID Ext2NotifyReportChange(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Filter, IN ULONG Action)
Definition: dirctl.c:1209
#define IsMcbDirectory(Mcb)
Definition: ext2fs.h:967
#define IsInodeSymLink(I)
Definition: ext2fs.h:286
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
#define DbgBreak()
Definition: ext2fs.h:46
#define FCB_ALLOC_IN_CREATE
Definition: ext2fs.h:884
struct _EXT2_VCB * PEXT2_VCB
#define CCB_DELETE_ON_CLOSE
Definition: ext2fs.h:1035
struct _EXT2_CCB * PEXT2_CCB
#define CCB_LAST_WRITE_UPDATED
Definition: ext2fs.h:1033
struct _EXT2_FCB * PEXT2_FCB
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:806
#define IsVcbInited(Vcb)
Definition: ext2fs.h:811
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define Ext2DerefXcb(_C)
Definition: ext2fs.h:977
FAST_IO_POSSIBLE Ext2IsFastIoPossible(IN PEXT2_FCB Fcb)
Definition: fastio.c:38
int ext3_release_dir(struct inode *inode, struct file *filp)
Definition: htree.c:1929
#define INODE_HAS_EXTENT(i)
Definition: ext4_ext.h:228
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:349
PFILE_LOCK_INFO NTAPI FsRtlGetNextFileLock(IN PFILE_LOCK FileLock, IN BOOLEAN Restart)
Definition: filelock.c:255
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1025
@ FastIoIsPossible
Definition: fsrtltypes.h:241
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
VOID NTAPI FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext)
Definition: notify.c:659
VOID NTAPI FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
Definition: notify.c:1487
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1782
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:1170
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Type
Definition: ntfs.h:95
ULONG Size
Definition: ntfs.h:96
ULONG Flags
Definition: ntfs.h:536
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1009
CD_MCB Mcb
Definition: cdstruc.h:1016
ERESOURCE PagingIoResource
Definition: ntfs.h:527
NTFSIDENTIFIER Identifier
Definition: ntfs.h:515
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG OpenHandleCount
Definition: ntfs.h:537
ERESOURCE MainResource
Definition: ntfs.h:528
#define IN
Definition: typedefs.h:39
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_ACTION_REMOVED
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998
#define VPB_LOCKED
Definition: iotypes.h:1808
#define FO_CACHE_SUPPORTED
Definition: iotypes.h:1781
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_DIR_NAME