2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/flush.c
5 * PURPOSE: VFAT Filesystem
9 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ****************************************************************/
21 PDEVICE_EXTENSION DeviceExt
,
24 IO_STATUS_BLOCK IoStatus
;
27 DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt
, Fcb
, &Fcb
->PathNameU
);
29 CcFlushCache(&Fcb
->SectionObjectPointers
, NULL
, 0, &IoStatus
);
30 if (IoStatus
.Status
== STATUS_INVALID_PARAMETER
)
32 /* FIXME: Caching was possible not initialized */
33 IoStatus
.Status
= STATUS_SUCCESS
;
36 if (BooleanFlagOn(Fcb
->Flags
, FCB_IS_DIRTY
))
38 Status
= VfatUpdateEntry(Fcb
, vfatVolumeIsFatX(DeviceExt
));
39 if (!NT_SUCCESS(Status
))
41 IoStatus
.Status
= Status
;
44 return IoStatus
.Status
;
49 PDEVICE_EXTENSION DeviceExt
,
52 PLIST_ENTRY ListEntry
;
54 NTSTATUS Status
, ReturnStatus
= STATUS_SUCCESS
;
57 IO_STATUS_BLOCK IoStatusBlock
;
59 DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt
, VolumeFcb
);
61 ListEntry
= DeviceExt
->FcbListHead
.Flink
;
62 while (ListEntry
!= &DeviceExt
->FcbListHead
)
64 Fcb
= CONTAINING_RECORD(ListEntry
, VFATFCB
, FcbListEntry
);
65 ListEntry
= ListEntry
->Flink
;
66 if (!vfatFCBIsDirectory(Fcb
))
68 ExAcquireResourceExclusiveLite(&Fcb
->MainResource
, TRUE
);
69 Status
= VfatFlushFile(DeviceExt
, Fcb
);
70 ExReleaseResourceLite (&Fcb
->MainResource
);
71 if (!NT_SUCCESS(Status
))
73 DPRINT1("VfatFlushFile failed, status = %x\n", Status
);
74 ReturnStatus
= Status
;
77 /* FIXME: Stop flushing if this is a removable media and the media was removed */
80 ListEntry
= DeviceExt
->FcbListHead
.Flink
;
81 while (ListEntry
!= &DeviceExt
->FcbListHead
)
83 Fcb
= CONTAINING_RECORD(ListEntry
, VFATFCB
, FcbListEntry
);
84 ListEntry
= ListEntry
->Flink
;
85 if (vfatFCBIsDirectory(Fcb
))
87 ExAcquireResourceExclusiveLite(&Fcb
->MainResource
, TRUE
);
88 Status
= VfatFlushFile(DeviceExt
, Fcb
);
89 ExReleaseResourceLite (&Fcb
->MainResource
);
90 if (!NT_SUCCESS(Status
))
92 DPRINT1("VfatFlushFile failed, status = %x\n", Status
);
93 ReturnStatus
= Status
;
96 /* FIXME: Stop flushing if this is a removable media and the media was removed */
99 Fcb
= (PVFATFCB
) DeviceExt
->FATFileObject
->FsContext
;
101 ExAcquireResourceExclusiveLite(&DeviceExt
->FatResource
, TRUE
);
102 Status
= VfatFlushFile(DeviceExt
, Fcb
);
103 ExReleaseResourceLite(&DeviceExt
->FatResource
);
105 /* Prepare an IRP to flush device buffers */
106 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS
,
107 DeviceExt
->StorageDevice
,
108 NULL
, 0, NULL
, &Event
,
112 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
114 Status
= IoCallDriver(DeviceExt
->StorageDevice
, Irp
);
115 if (Status
== STATUS_PENDING
)
117 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
118 Status
= IoStatusBlock
.Status
;
121 /* Ignore device not supporting flush operation */
122 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
124 DPRINT1("Flush not supported, ignored\n");
125 Status
= STATUS_SUCCESS
;
131 Status
= STATUS_INSUFFICIENT_RESOURCES
;
134 if (!NT_SUCCESS(Status
))
136 DPRINT1("VfatFlushFile failed, status = %x\n", Status
);
137 ReturnStatus
= Status
;
145 PVFAT_IRP_CONTEXT IrpContext
)
150 /* This request is not allowed on the main device object. */
151 if (IrpContext
->DeviceObject
== VfatGlobalData
->DeviceObject
)
153 IrpContext
->Irp
->IoStatus
.Information
= 0;
154 return STATUS_INVALID_DEVICE_REQUEST
;
157 Fcb
= (PVFATFCB
)IrpContext
->FileObject
->FsContext
;
160 if (BooleanFlagOn(Fcb
->Flags
, FCB_IS_VOLUME
))
162 ExAcquireResourceExclusiveLite(&IrpContext
->DeviceExt
->DirResource
, TRUE
);
163 Status
= VfatFlushVolume(IrpContext
->DeviceExt
, Fcb
);
164 ExReleaseResourceLite(&IrpContext
->DeviceExt
->DirResource
);
168 ExAcquireResourceExclusiveLite(&Fcb
->MainResource
, TRUE
);
169 Status
= VfatFlushFile(IrpContext
->DeviceExt
, Fcb
);
170 ExReleaseResourceLite (&Fcb
->MainResource
);
173 IrpContext
->Irp
->IoStatus
.Information
= 0;