ReactOS  0.4.13-dev-479-gec9c8fd
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 
24  IN PIRP Irp,
25  IN PVOID Context )
26 
27 {
28  if (Irp->PendingReturned)
30 
31 
32  if (Irp->IoStatus.Status == STATUS_INVALID_DEVICE_REQUEST)
33  Irp->IoStatus.Status = STATUS_SUCCESS;
34 
35  return STATUS_SUCCESS;
36 }
37 
40  IN PEXT2_IRP_CONTEXT IrpContext,
43 )
44 {
45  DEBUG(DL_INF, ( "Ext2FlushVolume: Flushing Vcb ...\n"));
46 
47  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
48  ExReleaseResourceLite(&Vcb->PagingIoResource);
49 
50  return Ext2FlushVcb(Vcb);
51 }
52 
55  IN PEXT2_IRP_CONTEXT IrpContext,
58 )
59 {
61 
62  ASSERT(Fcb != NULL);
64  (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
65 
66  _SEH2_TRY {
67 
68  /* do nothing if target fie was deleted */
72  }
73 
74  /* update timestamp and achieve attribute */
75  if (Ccb != NULL) {
76 
78 
79  LARGE_INTEGER SysTime;
80  KeQuerySystemTime(&SysTime);
81 
82  Fcb->Inode->i_mtime = Ext2LinuxTime(SysTime);
83  Fcb->Mcb->LastWriteTime = Ext2NtTime(Fcb->Inode->i_mtime);
84  Ext2SaveInode(IrpContext, Fcb->Vcb, Fcb->Inode);
85  }
86  }
87 
88  if (IsDirectory(Fcb)) {
89  IoStatus.Status = STATUS_SUCCESS;
91  }
92 
93  DEBUG(DL_INF, ( "Ext2FlushFile: Flushing File Inode=%xh %S ...\n",
94  Fcb->Inode->i_ino, Fcb->Mcb->ShortName.Buffer));
95 
96  CcFlushCache(&(Fcb->SectionObject), NULL, 0, &IoStatus);
98 
99  } _SEH2_FINALLY {
100 
101  /* do cleanup here */
102  } _SEH2_END;
103 
104  return IoStatus.Status;
105 }
106 
107 NTSTATUS
109  IN PEXT2_IRP_CONTEXT IrpContext,
110  IN PEXT2_VCB Vcb,
112 )
113 {
115 
116  PEXT2_FCB Fcb;
117  PLIST_ENTRY ListEntry;
118 
119  if (IsVcbReadOnly(Vcb)) {
120  return STATUS_SUCCESS;
121  }
122 
123  IoStatus.Status = STATUS_SUCCESS;
124 
125  DEBUG(DL_INF, ( "Flushing Files ...\n"));
126 
127  // Flush all Fcbs in Vcb list queue.
128  for (ListEntry = Vcb->FcbList.Flink;
129  ListEntry != &Vcb->FcbList;
130  ListEntry = ListEntry->Flink ) {
131 
132  Fcb = CONTAINING_RECORD(ListEntry, EXT2_FCB, Next);
134  &Fcb->MainResource, TRUE);
135  Ext2FlushFile(IrpContext, Fcb, NULL);
137  }
138 
139  return IoStatus.Status;
140 }
141 
142 
143 NTSTATUS
145 {
147 
148  PIRP Irp = NULL;
150 
151  PEXT2_VCB Vcb = NULL;
152  PEXT2_FCB Fcb = NULL;
153  PEXT2_FCBVCB FcbOrVcb = NULL;
154  PEXT2_CCB Ccb = NULL;
156 
158 
159  BOOLEAN MainResourceAcquired = FALSE;
160 
161  _SEH2_TRY {
162 
163  ASSERT(IrpContext);
164 
165  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
166  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
167 
168  DeviceObject = IrpContext->DeviceObject;
169 
170  //
171  // This request is not allowed on the main device object
172  //
175  _SEH2_LEAVE;
176  }
177 
179  ASSERT(Vcb != NULL);
180  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
181  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
182 
183  ASSERT(IsMounted(Vcb));
184  if (IsVcbReadOnly(Vcb)) {
186  _SEH2_LEAVE;
187  }
188 
189  Irp = IrpContext->Irp;
191 
192  FileObject = IrpContext->FileObject;
193  FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
194  ASSERT(FcbOrVcb != NULL);
195 
196  Ccb = (PEXT2_CCB) FileObject->FsContext2;
197  if (Ccb == NULL) {
199  _SEH2_LEAVE;
200  }
201 
202  MainResourceAcquired =
204  ASSERT(MainResourceAcquired);
205  DEBUG(DL_INF, ("Ext2Flush-pre: total mcb records=%u\n",
206  FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));
207 
208  if (FcbOrVcb->Identifier.Type == EXT2VCB) {
209 
210  Ext2VerifyVcb(IrpContext, Vcb);
211  Status = Ext2FlushFiles(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);
212  if (NT_SUCCESS(Status)) {
213  _SEH2_LEAVE;
214  }
215 
216  Status = Ext2FlushVolume(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);
217 
218  if (NT_SUCCESS(Status) && IsFlagOn(Vcb->Volume->Flags, FO_FILE_MODIFIED)) {
219  ClearFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
220  }
221 
222  } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
223 
224  Fcb = (PEXT2_FCB)(FcbOrVcb);
225 
226  Status = Ext2FlushFile(IrpContext, Fcb, Ccb);
227  if (NT_SUCCESS(Status)) {
228  if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {
229  Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE;
231  }
232  }
233  }
234 
235  DEBUG(DL_INF, ("Ext2Flush-post: total mcb records=%u\n",
236  FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));
237 
238 
239  } _SEH2_FINALLY {
240 
241  if (MainResourceAcquired) {
243  }
244 
245  if (!IrpContext->ExceptionInProgress) {
246 
247  if (Vcb && Irp && IrpSp && !IsVcbReadOnly(Vcb)) {
248 
249  // Call the disk driver to flush the physial media.
250  NTSTATUS DriverStatus;
251  PIO_STACK_LOCATION NextIrpSp;
252 
253  NextIrpSp = IoGetNextIrpStackLocation(Irp);
254 
255  *NextIrpSp = *IrpSp;
256 
259  NULL,
260  TRUE,
261  TRUE,
262  TRUE );
263 
264  DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, Irp);
265 
266  Status = (DriverStatus == STATUS_INVALID_DEVICE_REQUEST) ?
267  Status : DriverStatus;
268 
269  IrpContext->Irp = Irp = NULL;
270  }
271 
272  Ext2CompleteIrpContext(IrpContext, Status);
273  }
274  } _SEH2_END;
275 
276  return Status;
277 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _EXT2_FCB * PEXT2_FCB
#define IN
Definition: typedefs.h:38
#define IsMounted(Vcb)
Definition: ext2fs.h:803
#define TRUE
Definition: types.h:120
NTSTATUS Ext2FlushFiles(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:108
NTSTATUS Ext2FlushFile(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_FCB Fcb, IN PEXT2_CCB Ccb)
Definition: flush.c:54
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 PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
NTSTATUS Ext2FlushVolume(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:39
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
volatile BOOL bShutDown
Definition: ServiceMain.c:12
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS Ext2FlushVcb(IN PEXT2_VCB Vcb)
Definition: generic.c:319
ULONG NTAPI FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:769
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:472
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define FO_FILE_MODIFIED
Definition: iotypes.h:1744
NTFSIDENTIFIER Identifier
Definition: ntfs.h:499
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:624
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI Ext2FlushCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: flush.c:22
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSTATUS Ext2Flush(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: flush.c:144
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DL_INF
Definition: ext2fs.h:1399
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:805
#define CCB_LAST_WRITE_UPDATED
Definition: ext2fs.h:1024
#define Vcb
Definition: cdprocs.h:1425
struct _EXT2_FCBVCB * PEXT2_FCBVCB
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1954
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG Flags
Definition: ntfs.h:520
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
CD_MCB Mcb
Definition: cdstruc.h:1022
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
ULONG Type
Definition: ntfs.h:95
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:873
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ERESOURCE MainResource
Definition: ntfs.h:512
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1063
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_SEH2_END
Definition: create.c:4424
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
ERESOURCE MainResource
Definition: ext2fs.h:628
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:607
PVCB Vcb
Definition: cdstruc.h:939
struct _EXT2_VCB * PEXT2_VCB
#define DEBUG(args)
Definition: rdesktop.h:129
#define _SEH2_LEAVE
Definition: filesup.c:20
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2777
struct _EXT2_CCB * PEXT2_CCB
IoMarkIrpPending(Irp)
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:548
ULONG Size
Definition: ntfs.h:96
VOID Ext2VerifyVcb(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: fsctl.c:2277
ULONG Ext2LinuxTime(IN LARGE_INTEGER SysTime)
Definition: misc.c:51