ReactOS 0.4.15-dev-8119-g4fb2fdb
close.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: close.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
20#ifdef ALLOC_PRAGMA
21#pragma alloc_text(PAGE, Ext2QueueCloseRequest)
22#pragma alloc_text(PAGE, Ext2DeQueueCloseRequest)
23#endif
24
27{
34
35 BOOLEAN VcbResourceAcquired = FALSE;
36 BOOLEAN FcbResourceAcquired = FALSE;
37 BOOLEAN FcbDerefDeferred = FALSE;
38
39 _SEH2_TRY {
40
41 ASSERT(IrpContext != NULL);
42 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
43 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
44
45 DeviceObject = IrpContext->DeviceObject;
48 Vcb = NULL;
50 }
51
52 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
53 ASSERT(Vcb != NULL);
54 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
55 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
56
57 if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) {
58
60 Fcb = IrpContext->Fcb;
61 Ccb = IrpContext->Ccb;
62
63 } else {
64
65 FileObject = IrpContext->FileObject;
66 Fcb = (PEXT2_FCB) FileObject->FsContext;
67 if (!Fcb) {
70 }
71 ASSERT(Fcb != NULL);
72 Ccb = (PEXT2_CCB) FileObject->FsContext2;
73 }
74
75 DEBUG(DL_INF, ( "Ext2Close: (VCB) Vcb = %p ReferCount = %d\n",
76 Vcb, Vcb->ReferenceCount));
77
78 /*
79 * WARNING: don't release Vcb resource lock here.
80 *
81 * CcPurgeCacheSection will lead a recursive irp: IRP_MJ_CLOSE
82 * which would cause revrese order of lock acquirision:
83 * 1) IRP_MJ_CLEANUP: a) Vcb lock -> b) Fcb lock
84 * 2) IRP_MJ_CLOSE: c) Vcb lock -> d) Fcb lock
85 */
86
87 if (Fcb->Identifier.Type == EXT2VCB) {
88
90 &Vcb->MainResource,
91 TRUE )) {
92 DEBUG(DL_INF, ("Ext2Close: PENDING ... Vcb: %xh/%xh\n",
93 Vcb->OpenHandleCount, Vcb->ReferenceCount));
96 }
97 VcbResourceAcquired = TRUE;
98
99 if (Ccb) {
100
101 Ext2DerefXcb(&Vcb->ReferenceCount);
103
104 if (FileObject) {
105 FileObject->FsContext2 = Ccb = NULL;
106 }
107 }
108
111 }
112
113 if ( Fcb->Identifier.Type != EXT2FCB ||
114 Fcb->Identifier.Size != sizeof(EXT2_FCB)) {
116 }
117
120 TRUE )) {
123 }
124 FcbResourceAcquired = TRUE;
125
126 Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
127
128 if (Ccb == NULL ||
130 Ccb->Identifier.Size != sizeof(EXT2_CCB)) {
133 }
134
135 DEBUG(DL_INF, ( "Ext2Close: Fcb = %p OpenHandleCount= %u ReferenceCount=%u NonCachedCount=%u %wZ\n",
136 Fcb, Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount, &Fcb->Mcb->FullName ));
137
139 if (FileObject) {
140 FileObject->FsContext2 = Ccb = NULL;
141 }
142
143 /* only deref fcb, Ext2ReleaseFcb might lead deadlock */
144 FcbDerefDeferred = TRUE;
146 NULL == Fcb->Mcb ||
148 Fcb->TsDrop.QuadPart = 0;
149 } else {
150 KeQuerySystemTime(&Fcb->TsDrop);
151 }
152 Ext2DerefXcb(&Vcb->ReferenceCount);
153
154 if (FileObject) {
155 FileObject->FsContext = NULL;
156 }
157
159
160 } _SEH2_FINALLY {
161
162 if (FcbResourceAcquired) {
164 }
165
166 if (VcbResourceAcquired) {
167 ExReleaseResourceLite(&Vcb->MainResource);
168 }
169
170 if (!IrpContext->ExceptionInProgress) {
171
172 if (Status == STATUS_PENDING) {
173
174 Ext2QueueCloseRequest(IrpContext);
175
176 } else {
177
178 Ext2CompleteIrpContext(IrpContext, Status);
179 }
180 }
181
182 if (FcbDerefDeferred)
183 Ext2DerefXcb(&Fcb->ReferenceCount);
184 } _SEH2_END;
185
186 return Status;
187}
188
189VOID
191{
192 ASSERT(IrpContext);
193 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
194 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
195
196 if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) {
197
198 if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FILE_BUSY)) {
199 Ext2Sleep(500); /* 0.5 sec*/
200 } else {
201 Ext2Sleep(50); /* 0.05 sec*/
202 }
203
204 } else {
205
206 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
207 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE);
208
209 IrpContext->Fcb = (PEXT2_FCB) IrpContext->FileObject->FsContext;
210 IrpContext->Ccb = (PEXT2_CCB) IrpContext->FileObject->FsContext2;
211 }
212
214 &IrpContext->WorkQueueItem,
216 IrpContext);
217
218 ExQueueWorkItem(&IrpContext->WorkQueueItem, DelayedWorkQueue);
219}
220
223{
224 PEXT2_IRP_CONTEXT IrpContext;
225
226 IrpContext = (PEXT2_IRP_CONTEXT) Context;
227 ASSERT(IrpContext);
228 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
229 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
230
231 _SEH2_TRY {
232
233 _SEH2_TRY {
234
236 Ext2Close(IrpContext);
237
239
240 Ext2ExceptionHandler(IrpContext);
241 } _SEH2_END;
242
243 } _SEH2_FINALLY {
244
246 } _SEH2_END;
247}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI Ext2DeQueueCloseRequest(IN PVOID Context)
Definition: close.c:222
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2Close(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: close.c:26
VOID Ext2QueueCloseRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: close.c:190
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
NTSTATUS Ext2ExceptionHandler(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: except.c:112
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
NTSTATUS Ext2ExceptionFilter(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: except.c:21
@ EXT2FCB
Definition: ext2fs.h:463
@ EXT2ICX
Definition: ext2fs.h:465
@ EXT2VCB
Definition: ext2fs.h:462
@ EXT2CCB
Definition: ext2fs.h:464
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:968
VOID Ext2Sleep(ULONG ms)
Definition: misc.c:297
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:616
#define DL_INF
Definition: ext2fs.h:1436
struct ext2_icb * PEXT2_IRP_CONTEXT
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
struct _EXT2_VCB * PEXT2_VCB
#define IRP_CONTEXT_FLAG_DELAY_CLOSE
Definition: ext2fs.h:1096
struct _EXT2_CCB * PEXT2_CCB
VOID Ext2FreeCcb(IN PEXT2_VCB Vcb, IN PEXT2_CCB Ccb)
Definition: memory.c:356
struct _EXT2_FCB * PEXT2_FCB
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define IRP_CONTEXT_FLAG_FILE_BUSY
Definition: ext2fs.h:1097
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define Ext2DerefXcb(_C)
Definition: ext2fs.h:977
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
Status
Definition: gdiplustypes.h:25
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Type
Definition: ntfs.h:95
ULONG Size
Definition: ntfs.h:96
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:477
ULONG Flags
Definition: ntfs.h:536
CD_MCB Mcb
Definition: cdstruc.h:1016
NTFSIDENTIFIER Identifier
Definition: ntfs.h:515
struct _FCB::@724::@727 Fcb
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG OpenHandleCount
Definition: ntfs.h:537
ERESOURCE MainResource
Definition: ntfs.h:528
PFILE_OBJECT FileObject
Definition: ntfs.h:520
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:1047
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
* PFILE_OBJECT
Definition: iotypes.h:1998