* Sync up to trunk HEAD (r62285). Branch guys deserve the significant speedups too ;)
[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 PFILE_OBJECT FileObject = IrpContext->FileObject;
28
29 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
30 IrpContext->DeviceExt, FileObject);
31
32 /* FIXME: handle file/directory deletion here */
33 pFcb = (PVFATFCB)FileObject->FsContext;
34 if (!pFcb)
35 return STATUS_SUCCESS;
36
37 if (pFcb->Flags & FCB_IS_VOLUME)
38 {
39 pFcb->OpenHandleCount--;
40
41 if (pFcb->OpenHandleCount != 0)
42 {
43 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
44 }
45 }
46 else
47 {
48 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
49 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
50 {
51 return STATUS_PENDING;
52 }
53 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
54 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
55 {
56 ExReleaseResourceLite(&pFcb->MainResource);
57 return STATUS_PENDING;
58 }
59
60 pFcb->OpenHandleCount--;
61
62 if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
63 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
64 {
65 /* remove all locks this process have on this file */
66 FsRtlFastUnlockAll(&pFcb->FileLock,
67 FileObject,
68 IoGetRequestorProcess(IrpContext->Irp),
69 NULL);
70 }
71
72 if (pFcb->Flags & FCB_IS_DIRTY)
73 {
74 VfatUpdateEntry (pFcb);
75 }
76
77 if (pFcb->Flags & FCB_DELETE_PENDING &&
78 pFcb->OpenHandleCount == 0)
79 {
80 PFILE_OBJECT tmpFileObject;
81 tmpFileObject = pFcb->FileObject;
82 if (tmpFileObject != NULL)
83 {
84 pFcb->FileObject = NULL;
85 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
86 ObDereferenceObject(tmpFileObject);
87 }
88
89 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
90 }
91
92 /* Uninitialize the cache (should be done even if caching was never initialized) */
93 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
94
95 if (pFcb->OpenHandleCount != 0)
96 {
97 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
98 }
99
100 FileObject->Flags |= FO_CLEANUP_COMPLETE;
101
102 ExReleaseResourceLite(&pFcb->PagingIoResource);
103 ExReleaseResourceLite(&pFcb->MainResource);
104 }
105
106 return STATUS_SUCCESS;
107 }
108
109 /*
110 * FUNCTION: Cleans up after a file has been closed.
111 */
112 NTSTATUS
113 VfatCleanup(
114 PVFAT_IRP_CONTEXT IrpContext)
115 {
116 NTSTATUS Status;
117
118 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
119
120 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
121 {
122 Status = STATUS_SUCCESS;
123 goto ByeBye;
124 }
125
126 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
127 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
128 {
129 return VfatQueueRequest(IrpContext);
130 }
131
132 Status = VfatCleanupFile(IrpContext);
133
134 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
135
136 if (Status == STATUS_PENDING)
137 {
138 return VfatQueueRequest(IrpContext);
139 }
140
141 ByeBye:
142 IrpContext->Irp->IoStatus.Status = Status;
143 IrpContext->Irp->IoStatus.Information = 0;
144
145 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
146 VfatFreeIrpContext(IrpContext);
147 return Status;
148 }
149
150 /* EOF */