ReactOS  0.4.14-dev-606-g14ebc0b
close.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: drivers/filesystems/fastfat/close.c
5  * PURPOSE: VFAT Filesystem
6  * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
7  * Pierre Schweitzer (pierre@reactos.org)
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "vfat.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* FUNCTIONS ****************************************************************/
18 
19 VOID
21  PDEVICE_EXTENSION DeviceExt,
22  PVFATFCB pFcb)
23 {
24  /* Nothing to do for volumes or for the FAT file object */
26  {
27  return;
28  }
29 
30  /* If cache is still initialized, release it
31  * This only affects directories
32  */
33  if (pFcb->OpenHandleCount == 0 && BooleanFlagOn(pFcb->Flags, FCB_CACHE_INITIALIZED))
34  {
35  PFILE_OBJECT tmpFileObject;
36  tmpFileObject = pFcb->FileObject;
37  if (tmpFileObject != NULL)
38  {
39  pFcb->FileObject = NULL;
40  CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
42  ObDereferenceObject(tmpFileObject);
43  }
44  }
45 
46 #ifdef KDBG
47  pFcb->Flags |= FCB_CLOSED;
48 #endif
49 
50  /* Release the FCB, we likely cause its deletion */
51  vfatReleaseFCB(DeviceExt, pFcb);
52 }
53 
54 VOID
55 NTAPI
59 {
61  PVFATFCB pFcb;
63  PVFAT_CLOSE_CONTEXT CloseContext;
64  BOOLEAN ConcurrentDeletion;
65 
66  /* Start removing work items */
69  {
71  CloseContext = CONTAINING_RECORD(Entry, VFAT_CLOSE_CONTEXT, CloseListEntry);
72 
73  /* One less */
75  /* Reset its entry to detect concurrent deletions */
76  InitializeListHead(&CloseContext->CloseListEntry);
78 
79  /* Get the elements */
80  Vcb = CloseContext->Vcb;
81  pFcb = CloseContext->Fcb;
82  ExAcquireResourceExclusiveLite(&Vcb->DirResource, TRUE);
83  /* If it didn't got deleted in between */
85  {
86  /* Close it! */
87  DPRINT("Late closing: %wZ\n", &pFcb->PathNameU);
89  pFcb->CloseContext = NULL;
90  VfatCommonCloseFile(Vcb, pFcb);
91  ConcurrentDeletion = FALSE;
92  }
93  else
94  {
95  /* Otherwise, mark not to delete it */
96  ConcurrentDeletion = TRUE;
97  }
98  ExReleaseResourceLite(&Vcb->DirResource);
99 
100  /* If we were the fastest, delete the context */
101  if (!ConcurrentDeletion)
102  {
103  ExFreeToPagedLookasideList(&VfatGlobalData->CloseContextLookasideList, CloseContext);
104  }
105 
106  /* Lock again the list */
108  }
109 
110  /* We're done, bye! */
113 }
114 
115 NTSTATUS
117  PDEVICE_EXTENSION DeviceExt,
119 {
120  PVFAT_CLOSE_CONTEXT CloseContext;
121 
122  /* Allocate a work item */
123  CloseContext = ExAllocateFromPagedLookasideList(&VfatGlobalData->CloseContextLookasideList);
124  if (CloseContext == NULL)
125  {
127  }
128 
129  /* Set relevant fields */
130  CloseContext->Vcb = DeviceExt;
131  CloseContext->Fcb = FileObject->FsContext;
132  CloseContext->Fcb->CloseContext = CloseContext;
133 
134  /* Acquire the lock to insert in list */
136 
137  /* One more element */
140 
141  /* If we have more than 16 items in list, and no worker thread
142  * start a new one
143  */
145  {
148  }
149 
150  /* We're done */
152 
153  return STATUS_SUCCESS;
154 }
155 
156 /*
157  * FUNCTION: Closes a file
158  */
159 NTSTATUS
161  PDEVICE_EXTENSION DeviceExt,
163 {
164  PVFATFCB pFcb;
165  PVFATCCB pCcb;
166  BOOLEAN IsVolume;
168 
169  DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
170  DeviceExt, FileObject);
171 
172  /* FIXME : update entry in directory? */
173  pCcb = (PVFATCCB) (FileObject->FsContext2);
174  pFcb = (PVFATFCB) (FileObject->FsContext);
175 
176  if (pFcb == NULL)
177  {
178  return STATUS_SUCCESS;
179  }
180 
181  IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME);
182 
183  if (pCcb)
184  {
185  vfatDestroyCCB(pCcb);
186  }
187 
188  /* If we have to close immediately, or if delaying failed, close */
191  {
192  VfatCommonCloseFile(DeviceExt, pFcb);
193  }
194 
195  FileObject->FsContext2 = NULL;
196  FileObject->FsContext = NULL;
197  FileObject->SectionObjectPointer = NULL;
198 
199 #ifdef ENABLE_SWAPOUT
200  if (IsVolume && DeviceExt->OpenHandleCount == 0)
201  {
202  VfatCheckForDismount(DeviceExt, FALSE);
203  }
204 #endif
205 
206  return Status;
207 }
208 
209 /*
210  * FUNCTION: Closes a file
211  */
212 NTSTATUS
214  PVFAT_IRP_CONTEXT IrpContext)
215 {
217 
218  DPRINT("VfatClose(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
219 
220  if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
221  {
222  DPRINT("Closing file system\n");
223  IrpContext->Irp->IoStatus.Information = 0;
224  return STATUS_SUCCESS;
225  }
226  if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
227  {
228  return VfatMarkIrpContextForQueue(IrpContext);
229  }
230 
231  Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
232  ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
233 
234  IrpContext->Irp->IoStatus.Information = 0;
235 
236  return Status;
237 }
238 
239 /* EOF */
LIST_ENTRY CloseListEntry
Definition: vfat.h:614
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:160
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS VfatPostCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:116
FAST_MUTEX CloseMutex
Definition: vfat.h:417
struct _Entry Entry
Definition: kefuncs.h:640
Definition: vfat.h:441
Definition: vfat.h:530
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:579
struct _VFATCCB * PVFATCCB
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PIO_WORKITEM CloseWorkItem
Definition: vfat.h:421
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define InsertTailList(ListHead, Entry)
PFILE_OBJECT FileObject
Definition: vfat.h:585
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PDEVICE_EXTENSION Vcb
Definition: vfat.h:612
PFILE_OBJECT FileObject
Definition: vfat.h:493
ULONG Flags
Definition: vfat.h:490
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:569
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:406
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
NTSTATUS VfatClose(PVFAT_IRP_CONTEXT IrpContext)
Definition: close.c:213
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:619
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FCB_IS_FAT
Definition: vfat.h:429
VOID vfatDestroyCCB(PVFATCCB pCcb)
Definition: fcb.c:258
Definition: typedefs.h:117
BOOLEAN VfatCheckForDismount(IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Force)
Definition: misc.c:417
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
struct _VFATFCB * PVFATFCB
Status
Definition: gdiplustypes.h:24
struct _VFAT_CLOSE_CONTEXT * CloseContext
Definition: vfat.h:525
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define FCB_DELAYED_CLOSE
Definition: vfat.h:433
#define FCB_CACHE_INITIALIZED
Definition: vfat.h:427
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:40
#define FCB_IS_VOLUME
Definition: vfat.h:431
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
BOOLEAN ShutdownStarted
Definition: vfat.h:422
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:578
LIST_ENTRY CloseListHead
Definition: vfat.h:419
BOOLEAN CloseWorkerRunning
Definition: vfat.h:420
UNICODE_STRING PathNameU
Definition: vfat.h:466
VOID NTAPI VfatCloseWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: close.c:56
ULONG CloseCount
Definition: vfat.h:418
ULONG Flags
Definition: vfat.h:580
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
ULONG OpenHandleCount
Definition: vfat.h:505
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID VfatCommonCloseFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
Definition: close.c:20
PAGED_LOOKASIDE_LIST CloseContextLookasideList
Definition: vfat.h:414
base of all file and directory entries
Definition: entries.h:82
PVFATFCB Fcb
Definition: vfat.h:613