ReactOS 0.4.15-dev-7953-g1f49173
close.c
Go to the documentation of this file.
1/*
2 * PROJECT: VFAT Filesystem
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: File close routines
5 * COPYRIGHT: Copyright 1998 Jason Filby <jasonfilby@yahoo.com>
6 * Copyright 2014-2018 Pierre Schweitzer <pierre@reactos.org>
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include "vfat.h"
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS ****************************************************************/
17
18VOID
20 PDEVICE_EXTENSION DeviceExt,
21 PVFATFCB pFcb)
22{
23 /* Nothing to do for volumes or for the FAT file object */
25 {
26 return;
27 }
28
29 /* If cache is still initialized, release it
30 * This only affects directories
31 */
33 {
34 PFILE_OBJECT tmpFileObject;
35 tmpFileObject = pFcb->FileObject;
36 if (tmpFileObject != NULL)
37 {
38 pFcb->FileObject = NULL;
39 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
41 ObDereferenceObject(tmpFileObject);
42 }
43 }
44
45#ifdef KDBG
46 pFcb->Flags |= FCB_CLOSED;
47#endif
48
49 /* Release the FCB, we likely cause its deletion */
50 vfatReleaseFCB(DeviceExt, pFcb);
51}
52
53VOID
58{
60 PVFATFCB pFcb;
62 PVFAT_CLOSE_CONTEXT CloseContext;
63 BOOLEAN ConcurrentDeletion;
64
65 /* Start removing work items */
68 {
70 CloseContext = CONTAINING_RECORD(Entry, VFAT_CLOSE_CONTEXT, CloseListEntry);
71
72 /* One less */
74 /* Reset its entry to detect concurrent deletions */
75 InitializeListHead(&CloseContext->CloseListEntry);
77
78 /* Get the elements */
79 Vcb = CloseContext->Vcb;
80 pFcb = CloseContext->Fcb;
82 /* If it didn't got deleted in between */
84 {
85 /* Close it! */
86 DPRINT("Late closing: %wZ\n", &pFcb->PathNameU);
88 pFcb->CloseContext = NULL;
90 ConcurrentDeletion = FALSE;
91 }
92 else
93 {
94 /* Otherwise, mark not to delete it */
95 ConcurrentDeletion = TRUE;
96 }
97 ExReleaseResourceLite(&Vcb->DirResource);
98
99 /* If we were the fastest, delete the context */
100 if (!ConcurrentDeletion)
101 {
102 ExFreeToPagedLookasideList(&VfatGlobalData->CloseContextLookasideList, CloseContext);
103 }
104
105 /* Lock again the list */
107 }
108
109 /* We're done, bye! */
112}
113
116 PDEVICE_EXTENSION DeviceExt,
118{
119 PVFAT_CLOSE_CONTEXT CloseContext;
120
121 /* Allocate a work item */
122 CloseContext = ExAllocateFromPagedLookasideList(&VfatGlobalData->CloseContextLookasideList);
123 if (CloseContext == NULL)
124 {
126 }
127
128 /* Set relevant fields */
129 CloseContext->Vcb = DeviceExt;
130 CloseContext->Fcb = FileObject->FsContext;
131 CloseContext->Fcb->CloseContext = CloseContext;
132
133 /* Acquire the lock to insert in list */
135
136 /* One more element */
139
140 /* If we have more than 16 items in list, and no worker thread
141 * start a new one
142 */
144 {
147 }
148
149 /* We're done */
151
152 return STATUS_SUCCESS;
153}
154
155/*
156 * FUNCTION: Closes a file
157 */
160 PDEVICE_EXTENSION DeviceExt,
162{
163 PVFATFCB pFcb;
164 PVFATCCB pCcb;
165 BOOLEAN IsVolume;
167
168 DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
169 DeviceExt, FileObject);
170
171 /* FIXME : update entry in directory? */
172 pCcb = (PVFATCCB) (FileObject->FsContext2);
173 pFcb = (PVFATFCB) (FileObject->FsContext);
174
175 if (pFcb == NULL)
176 {
177 return STATUS_SUCCESS;
178 }
179
180 IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME);
181
182 if (pCcb)
183 {
184 vfatDestroyCCB(pCcb);
185 }
186
187 /* If we have to close immediately, or if delaying failed, close */
190 {
191 VfatCommonCloseFile(DeviceExt, pFcb);
192 }
193
194 FileObject->FsContext2 = NULL;
195 FileObject->FsContext = NULL;
196 FileObject->SectionObjectPointer = NULL;
197
198#ifdef ENABLE_SWAPOUT
199 if (IsVolume && DeviceExt->OpenHandleCount == 0)
200 {
201 VfatCheckForDismount(DeviceExt, FALSE);
202 }
203#endif
204
205 return Status;
206}
207
208/*
209 * FUNCTION: Closes a file
210 */
213 PVFAT_IRP_CONTEXT IrpContext)
214{
216
217 DPRINT("VfatClose(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
218
219 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
220 {
221 DPRINT("Closing file system\n");
222 IrpContext->Irp->IoStatus.Information = 0;
223 return STATUS_SUCCESS;
224 }
226 {
227 return VfatMarkIrpContextForQueue(IrpContext);
228 }
229
230 Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
232
233 IrpContext->Irp->IoStatus.Information = 0;
234
235 return Status;
236}
237
238/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#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:32
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:474
#define FCB_IS_VOLUME
Definition: ntfs.h:510
#define FCB_CACHE_INITIALIZED
Definition: ntfs.h:508
NTSTATUS VfatPostCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:115
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:159
VOID VfatCommonCloseFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
Definition: close.c:19
VOID NTAPI VfatCloseWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: close.c:55
NTSTATUS VfatClose(PVFAT_IRP_CONTEXT IrpContext)
Definition: close.c:212
BOOLEAN VfatCheckForDismount(IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Force)
Definition: misc.c:495
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define Vcb
Definition: cdprocs.h:1415
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
ERESOURCE DirResource
Definition: ntfs.h:103
base of all file and directory entries
Definition: entries.h:83
BOOLEAN CloseWorkerRunning
Definition: vfat.h:426
PIO_WORKITEM CloseWorkItem
Definition: vfat.h:427
PAGED_LOOKASIDE_LIST CloseContextLookasideList
Definition: vfat.h:420
FAST_MUTEX CloseMutex
Definition: vfat.h:423
LIST_ENTRY CloseListHead
Definition: vfat.h:425
ULONG CloseCount
Definition: vfat.h:424
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
BOOLEAN ShutdownStarted
Definition: vfat.h:428
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
ULONG Flags
Definition: vfat.h:586
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
PFILE_OBJECT FileObject
Definition: vfat.h:591
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
Definition: vfat.h:537
Definition: vfat.h:448
PFILE_OBJECT FileObject
Definition: vfat.h:499
ULONG Flags
Definition: vfat.h:496
UNICODE_STRING PathNameU
Definition: vfat.h:472
ULONG OpenHandleCount
Definition: vfat.h:511
struct _VFAT_CLOSE_CONTEXT * CloseContext
Definition: vfat.h:531
PVFATFCB Fcb
Definition: vfat.h:619
LIST_ENTRY CloseListEntry
Definition: vfat.h:620
PDEVICE_EXTENSION Vcb
Definition: vfat.h:618
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _VFATFCB * PVFATFCB
#define FCB_DELAYED_CLOSE
Definition: vfat.h:439
struct _VFATCCB * PVFATCCB
#define FCB_IS_FAT
Definition: vfat.h:435
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:625
VOID vfatDestroyCCB(PVFATCCB pCcb)
Definition: fcb.c:257
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
@ CriticalWorkQueue
Definition: extypes.h:189
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203