* Sync to trunk r63845.
[reactos.git] / drivers / filesystems / fastfat / flush.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/flush.c
5 * PURPOSE: VFAT Filesystem
6 * PROGRAMMER:
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "vfat.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ****************************************************************/
17
18 static
19 NTSTATUS
20 VfatFlushFile(
21 PDEVICE_EXTENSION DeviceExt,
22 PVFATFCB Fcb)
23 {
24 IO_STATUS_BLOCK IoStatus;
25 NTSTATUS Status;
26
27 DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt, Fcb, &Fcb->PathNameU);
28
29 CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
30 if (IoStatus.Status == STATUS_INVALID_PARAMETER)
31 {
32 /* FIXME: Caching was possible not initialized */
33 IoStatus.Status = STATUS_SUCCESS;
34 }
35
36 if (Fcb->Flags & FCB_IS_DIRTY)
37 {
38 Status = VfatUpdateEntry(Fcb);
39 if (!NT_SUCCESS(Status))
40 {
41 IoStatus.Status = Status;
42 }
43 }
44 return IoStatus.Status;
45 }
46
47 NTSTATUS
48 VfatFlushVolume(
49 PDEVICE_EXTENSION DeviceExt,
50 PVFATFCB VolumeFcb)
51 {
52 PLIST_ENTRY ListEntry;
53 PVFATFCB Fcb;
54 NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
55
56 DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
57
58 ListEntry = DeviceExt->FcbListHead.Flink;
59 while (ListEntry != &DeviceExt->FcbListHead)
60 {
61 Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
62 ListEntry = ListEntry->Flink;
63 if (!vfatFCBIsDirectory(Fcb))
64 {
65 ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
66 Status = VfatFlushFile(DeviceExt, Fcb);
67 ExReleaseResourceLite (&Fcb->MainResource);
68 if (!NT_SUCCESS(Status))
69 {
70 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
71 ReturnStatus = Status;
72 }
73 }
74 /* FIXME: Stop flushing if this is a removable media and the media was removed */
75 }
76
77 ListEntry = DeviceExt->FcbListHead.Flink;
78 while (ListEntry != &DeviceExt->FcbListHead)
79 {
80 Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
81 ListEntry = ListEntry->Flink;
82 if (vfatFCBIsDirectory(Fcb))
83 {
84 ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
85 Status = VfatFlushFile(DeviceExt, Fcb);
86 ExReleaseResourceLite (&Fcb->MainResource);
87 if (!NT_SUCCESS(Status))
88 {
89 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
90 ReturnStatus = Status;
91 }
92 }
93 /* FIXME: Stop flushing if this is a removable media and the media was removed */
94 }
95
96 Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
97
98 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
99 Status = VfatFlushFile(DeviceExt, Fcb);
100 ExReleaseResourceLite(&DeviceExt->FatResource);
101
102 /* FIXME: Flush the buffers from storage device */
103
104 if (!NT_SUCCESS(Status))
105 {
106 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
107 ReturnStatus = Status;
108 }
109
110 return ReturnStatus;
111 }
112
113 NTSTATUS
114 VfatFlush(
115 PVFAT_IRP_CONTEXT IrpContext)
116 {
117 NTSTATUS Status;
118 PVFATFCB Fcb;
119
120 /* This request is not allowed on the main device object. */
121 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
122 {
123 Status = STATUS_INVALID_DEVICE_REQUEST;
124 goto ByeBye;
125 }
126
127 Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
128 ASSERT(Fcb);
129
130 if (Fcb->Flags & FCB_IS_VOLUME)
131 {
132 ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
133 Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
134 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
135 }
136 else
137 {
138 ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
139 Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
140 ExReleaseResourceLite (&Fcb->MainResource);
141 }
142
143 ByeBye:
144 IrpContext->Irp->IoStatus.Status = Status;
145 IrpContext->Irp->IoStatus.Information = 0;
146 IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
147 VfatFreeIrpContext(IrpContext);
148
149 return Status;
150 }
151
152 /* EOF */