ReactOS  0.4.14-dev-50-g13bb5e2
close.c File Reference
#include "ext2fs.h"
Include dependency graph for close.c:

Go to the source code of this file.

Functions

NTSTATUS Ext2Close (IN PEXT2_IRP_CONTEXT IrpContext)
 
VOID Ext2QueueCloseRequest (IN PEXT2_IRP_CONTEXT IrpContext)
 
VOID NTAPI Ext2DeQueueCloseRequest (IN PVOID Context)
 

Variables

PEXT2_GLOBAL Ext2Global
 

Function Documentation

◆ Ext2Close()

NTSTATUS Ext2Close ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 26 of file close.c.

27 {
30  PEXT2_VCB Vcb = NULL;
32  PEXT2_FCB Fcb = NULL;
33  PEXT2_CCB Ccb = NULL;
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 
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 
59  FileObject = NULL;
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);
102  Ext2FreeCcb(Vcb, Ccb);
103 
104  if (FileObject) {
105  FileObject->FsContext2 = Ccb = NULL;
106  }
107  }
108 
110  _SEH2_LEAVE;
111  }
112 
113  if ( Fcb->Identifier.Type != EXT2FCB ||
114  Fcb->Identifier.Size != sizeof(EXT2_FCB)) {
115  _SEH2_LEAVE;
116  }
117 
119  &Fcb->MainResource,
120  TRUE )) {
122  _SEH2_LEAVE;
123  }
124  FcbResourceAcquired = TRUE;
125 
126  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
127 
128  if (Ccb == NULL ||
129  Ccb->Identifier.Type != EXT2CCB ||
130  Ccb->Identifier.Size != sizeof(EXT2_CCB)) {
132  _SEH2_LEAVE;
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 
138  Ext2FreeCcb(Vcb, Ccb);
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 ||
147  IsFileDeleted(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 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _EXT2_FCB * PEXT2_FCB
#define TRUE
Definition: types.h:120
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
LONG NTSTATUS
Definition: precomp.h:26
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
_SEH2_TRY
Definition: create.c:4250
#define IRP_CONTEXT_FLAG_DELAY_CLOSE
Definition: ext2fs.h:1087
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
ULONG OpenHandleCount
Definition: ntfs.h:533
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DL_INF
Definition: ext2fs.h:1399
#define Vcb
Definition: cdprocs.h:1425
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG Flags
Definition: ntfs.h:532
CD_MCB Mcb
Definition: cdstruc.h:1022
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
ULONG Type
Definition: ntfs.h:95
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
ERESOURCE MainResource
Definition: ntfs.h:524
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_SEH2_END
Definition: create.c:4424
struct _FCB::@693::@696 Fcb
VOID Ext2QueueCloseRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: close.c:190
_SEH2_FINALLY
Definition: create.c:4395
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:607
struct _EXT2_VCB * PEXT2_VCB
#define DEBUG(args)
Definition: rdesktop.h:129
VOID Ext2FreeCcb(IN PEXT2_VCB Vcb, IN PEXT2_CCB Ccb)
Definition: memory.c:356
#define _SEH2_LEAVE
Definition: filesup.c:20
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _EXT2_CCB * PEXT2_CCB
ULONG Size
Definition: ntfs.h:96
#define Ext2DerefXcb(_C)
Definition: ext2fs.h:968

Referenced by Ext2DeQueueCloseRequest().

◆ Ext2DeQueueCloseRequest()

VOID NTAPI Ext2DeQueueCloseRequest ( IN PVOID  Context)

Definition at line 222 of file close.c.

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 }
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
NTSTATUS Ext2Close(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: close.c:26
_SEH2_TRY
Definition: create.c:4250
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:472
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:1038
NTSTATUS Ext2ExceptionHandler(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: except.c:112
NTSTATUS Ext2ExceptionFilter(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: except.c:21
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_SEH2_END
Definition: create.c:4424
struct ext2_icb * PEXT2_IRP_CONTEXT
_SEH2_FINALLY
Definition: create.c:4395
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6

Referenced by Ext2QueueCloseRequest().

◆ Ext2QueueCloseRequest()

VOID Ext2QueueCloseRequest ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 190 of file close.c.

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 }
struct _EXT2_FCB * PEXT2_FCB
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define IRP_CONTEXT_FLAG_DELAY_CLOSE
Definition: ext2fs.h:1087
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
VOID NTAPI Ext2DeQueueCloseRequest(IN PVOID Context)
Definition: close.c:222
VOID Ext2Sleep(ULONG ms)
Definition: misc.c:297
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IRP_CONTEXT_FLAG_FILE_BUSY
Definition: ext2fs.h:1088
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187

Referenced by Ext2Close().

Variable Documentation

◆ Ext2Global

PEXT2_GLOBAL Ext2Global

Definition at line 16 of file init.c.