* Sync up to trunk head (r65147).
[reactos.git] / drivers / filesystems / fastfat / cleanup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/cleanup.c
5 * PURPOSE: VFAT Filesystem
6 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "vfat.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ****************************************************************/
17
18 /*
19 * FUNCTION: Cleans up after a file has been closed.
20 */
21 static
22 NTSTATUS
23 VfatCleanupFile(
24 PVFAT_IRP_CONTEXT IrpContext)
25 {
26 PVFATFCB pFcb;
27 PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
28 PFILE_OBJECT FileObject = IrpContext->FileObject;
29
30 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
31 IrpContext->DeviceExt, FileObject);
32
33 /* FIXME: handle file/directory deletion here */
34 pFcb = (PVFATFCB)FileObject->FsContext;
35 if (!pFcb)
36 return STATUS_SUCCESS;
37
38 if (pFcb->Flags & FCB_IS_VOLUME)
39 {
40 pFcb->OpenHandleCount--;
41 DeviceExt->OpenHandleCount--;
42
43 if (pFcb->OpenHandleCount != 0)
44 {
45 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
46 }
47 }
48 else
49 {
50 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
51 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
52 {
53 return STATUS_PENDING;
54 }
55 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
56 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
57 {
58 ExReleaseResourceLite(&pFcb->MainResource);
59 return STATUS_PENDING;
60 }
61
62 /* Notify about the cleanup */
63 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync,
64 &(IrpContext->DeviceExt->NotifyList),
65 FileObject->FsContext2);
66
67 pFcb->OpenHandleCount--;
68 DeviceExt->OpenHandleCount--;
69
70 if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
71 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
72 {
73 /* remove all locks this process have on this file */
74 FsRtlFastUnlockAll(&pFcb->FileLock,
75 FileObject,
76 IoGetRequestorProcess(IrpContext->Irp),
77 NULL);
78 }
79
80 if (pFcb->Flags & FCB_IS_DIRTY)
81 {
82 VfatUpdateEntry (pFcb);
83 }
84
85 if (pFcb->Flags & FCB_DELETE_PENDING &&
86 pFcb->OpenHandleCount == 0)
87 {
88 PFILE_OBJECT tmpFileObject;
89 tmpFileObject = pFcb->FileObject;
90 if (tmpFileObject != NULL)
91 {
92 pFcb->FileObject = NULL;
93 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
94 ObDereferenceObject(tmpFileObject);
95 vfatReleaseFCB(IrpContext->DeviceExt, pFcb);
96 }
97
98 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
99 }
100
101 /* Uninitialize the cache (should be done even if caching was never initialized) */
102 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
103
104 if (pFcb->OpenHandleCount != 0)
105 {
106 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
107 }
108
109 FileObject->Flags |= FO_CLEANUP_COMPLETE;
110
111 ExReleaseResourceLite(&pFcb->PagingIoResource);
112 ExReleaseResourceLite(&pFcb->MainResource);
113 }
114
115 return STATUS_SUCCESS;
116 }
117
118 /*
119 * FUNCTION: Cleans up after a file has been closed.
120 */
121 NTSTATUS
122 VfatCleanup(
123 PVFAT_IRP_CONTEXT IrpContext)
124 {
125 NTSTATUS Status;
126
127 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
128
129 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
130 {
131 Status = STATUS_SUCCESS;
132 goto ByeBye;
133 }
134
135 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
136 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
137 {
138 return VfatQueueRequest(IrpContext);
139 }
140
141 Status = VfatCleanupFile(IrpContext);
142
143 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
144
145 if (Status == STATUS_PENDING)
146 {
147 return VfatQueueRequest(IrpContext);
148 }
149
150 ByeBye:
151 IrpContext->Irp->IoStatus.Status = Status;
152 IrpContext->Irp->IoStatus.Information = 0;
153
154 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
155 VfatFreeIrpContext(IrpContext);
156 return Status;
157 }
158
159 /* EOF */