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