ReactOS 0.4.16-dev-319-g6cf4263
flush.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: flush.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "ext2fs.h"
13
14/* GLOBALS ***************************************************************/
15
17
18/* DEFINITIONS *************************************************************/
19
20
21#ifdef __REACTOS__
23#else
25#endif
28 IN PIRP Irp,
30
31{
32 if (Irp->PendingReturned)
34
35
36 if (Irp->IoStatus.Status == STATUS_INVALID_DEVICE_REQUEST)
37 Irp->IoStatus.Status = STATUS_SUCCESS;
38
39 return STATUS_SUCCESS;
40}
41
44 IN PEXT2_IRP_CONTEXT IrpContext,
47)
48{
49 DEBUG(DL_INF, ( "Ext2FlushVolume: Flushing Vcb ...\n"));
50
51 ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
52 ExReleaseResourceLite(&Vcb->PagingIoResource);
53
54 return Ext2FlushVcb(Vcb);
55}
56
59 IN PEXT2_IRP_CONTEXT IrpContext,
62)
63{
65
66 ASSERT(Fcb != NULL);
68 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
69
70 _SEH2_TRY {
71
72 /* do nothing if target fie was deleted */
76 }
77
78 /* update timestamp and achieve attribute */
79 if (Ccb != NULL) {
80
82
83 LARGE_INTEGER SysTime;
84 KeQuerySystemTime(&SysTime);
85
86 Fcb->Inode->i_mtime = Ext2LinuxTime(SysTime);
87 Fcb->Mcb->LastWriteTime = Ext2NtTime(Fcb->Inode->i_mtime);
88 Ext2SaveInode(IrpContext, Fcb->Vcb, Fcb->Inode);
89 }
90 }
91
92 if (IsDirectory(Fcb)) {
93 IoStatus.Status = STATUS_SUCCESS;
95 }
96
97 DEBUG(DL_INF, ( "Ext2FlushFile: Flushing File Inode=%xh %S ...\n",
98 Fcb->Inode->i_ino, Fcb->Mcb->ShortName.Buffer));
99
100 CcFlushCache(&(Fcb->SectionObject), NULL, 0, &IoStatus);
102
103 } _SEH2_FINALLY {
104
105 /* do cleanup here */
106 } _SEH2_END;
107
108 return IoStatus.Status;
109}
110
113 IN PEXT2_IRP_CONTEXT IrpContext,
116)
117{
119
121 PLIST_ENTRY ListEntry;
122
123 if (IsVcbReadOnly(Vcb)) {
124 return STATUS_SUCCESS;
125 }
126
127 IoStatus.Status = STATUS_SUCCESS;
128
129 DEBUG(DL_INF, ( "Flushing Files ...\n"));
130
131 // Flush all Fcbs in Vcb list queue.
132 for (ListEntry = Vcb->FcbList.Flink;
133 ListEntry != &Vcb->FcbList;
134 ListEntry = ListEntry->Flink ) {
135
136 Fcb = CONTAINING_RECORD(ListEntry, EXT2_FCB, Next);
139 Ext2FlushFile(IrpContext, Fcb, NULL);
141 }
142
143 return IoStatus.Status;
144}
145
146
149{
151
152 PIRP Irp = NULL;
154
157 PEXT2_FCBVCB FcbOrVcb = NULL;
160
162
163 BOOLEAN MainResourceAcquired = FALSE;
164
165 _SEH2_TRY {
166
167 ASSERT(IrpContext);
168
169 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
170 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
171
172 DeviceObject = IrpContext->DeviceObject;
173
174 //
175 // This request is not allowed on the main device object
176 //
180 }
181
182 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
183 ASSERT(Vcb != NULL);
184 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
185 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
186
188 if (IsVcbReadOnly(Vcb)) {
191 }
192
193 Irp = IrpContext->Irp;
195
196 FileObject = IrpContext->FileObject;
197 FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
198 ASSERT(FcbOrVcb != NULL);
199
200 Ccb = (PEXT2_CCB) FileObject->FsContext2;
201 if (Ccb == NULL) {
204 }
205
206 MainResourceAcquired =
208 ASSERT(MainResourceAcquired);
209 DEBUG(DL_INF, ("Ext2Flush-pre: total mcb records=%u\n",
210 FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));
211
212 if (FcbOrVcb->Identifier.Type == EXT2VCB) {
213
214 Ext2VerifyVcb(IrpContext, Vcb);
215 Status = Ext2FlushFiles(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);
216 if (NT_SUCCESS(Status)) {
218 }
219
220 Status = Ext2FlushVolume(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);
221
222 if (NT_SUCCESS(Status) && IsFlagOn(Vcb->Volume->Flags, FO_FILE_MODIFIED)) {
223 ClearFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
224 }
225
226 } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
227
228 Fcb = (PEXT2_FCB)(FcbOrVcb);
229
230 Status = Ext2FlushFile(IrpContext, Fcb, Ccb);
231 if (NT_SUCCESS(Status)) {
232 if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {
233 Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE;
235 }
236 }
237 }
238
239 DEBUG(DL_INF, ("Ext2Flush-post: total mcb records=%u\n",
240 FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));
241
242
243 } _SEH2_FINALLY {
244
245 if (MainResourceAcquired) {
247 }
248
249 if (!IrpContext->ExceptionInProgress) {
250
251 if (Vcb && Irp && IrpSp && !IsVcbReadOnly(Vcb)) {
252
253 // Call the disk driver to flush the physial media.
254 NTSTATUS DriverStatus;
255 PIO_STACK_LOCATION NextIrpSp;
256
257 NextIrpSp = IoGetNextIrpStackLocation(Irp);
258
259 *NextIrpSp = *IrpSp;
260
263 NULL,
264 TRUE,
265 TRUE,
266 TRUE );
267
268 DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, Irp);
269
270 Status = (DriverStatus == STATUS_INVALID_DEVICE_REQUEST) ?
271 Status : DriverStatus;
272
273 IrpContext->Irp = Irp = NULL;
274 }
275
276 Ext2CompleteIrpContext(IrpContext, Status);
277 }
278 } _SEH2_END;
279
280 return Status;
281}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
NTSTATUS Ext2Flush(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: flush.c:148
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2FlushFile(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_FCB Fcb, IN PEXT2_CCB Ccb)
Definition: flush.c:58
NTSTATUS Ext2FlushCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: flush.c:26
NTSTATUS Ext2FlushFiles(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:112
NTSTATUS Ext2FlushVolume(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:43
NTSTATUS Ext2FlushVcb(IN PEXT2_VCB Vcb)
Definition: generic.c:323
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
@ EXT2FCB
Definition: ext2fs.h:463
@ EXT2ICX
Definition: ext2fs.h:465
@ EXT2VCB
Definition: ext2fs.h:462
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:814
#define IsMounted(Vcb)
Definition: ext2fs.h:812
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:552
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:616
#define DL_INF
Definition: ext2fs.h:1436
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:882
ULONG Ext2LinuxTime(IN LARGE_INTEGER SysTime)
Definition: misc.c:51
struct _EXT2_FCBVCB * PEXT2_FCBVCB
VOID Ext2VerifyVcb(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: fsctl.c:2277
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
struct _EXT2_VCB * PEXT2_VCB
struct _EXT2_CCB * PEXT2_CCB
#define CCB_LAST_WRITE_UPDATED
Definition: ext2fs.h:1033
struct _EXT2_FCB * PEXT2_FCB
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
Status
Definition: gdiplustypes.h:25
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
ULONG NTAPI FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:765
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
volatile BOOL bShutDown
Definition: ServiceMain.c:12
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define IoCallDriver
Definition: irp.c:1225
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Type
Definition: ntfs.h:95
ULONG Size
Definition: ntfs.h:96
ERESOURCE MainResource
Definition: ext2fs.h:637
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:633
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:477
ULONG Flags
Definition: ntfs.h:536
PVCB Vcb
Definition: cdstruc.h:933
CD_MCB Mcb
Definition: cdstruc.h:1016
NTFSIDENTIFIER Identifier
Definition: ntfs.h:515
ERESOURCE MainResource
Definition: ntfs.h:528
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
* PFILE_OBJECT
Definition: iotypes.h:1998