2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ***************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
22 #pragma alloc_text(PAGE, RfsdFlushFile)
23 #pragma alloc_text(PAGE, RfsdFlushFiles)
24 #pragma alloc_text(PAGE, RfsdFlushVolume)
25 #pragma alloc_text(PAGE, RfsdFlush)
29 IO_COMPLETION_ROUTINE RfsdFlushCompletionRoutine
;
33 RfsdFlushCompletionRoutine (
34 IN PDEVICE_OBJECT DeviceObject
,
39 if (Irp
->PendingReturned
)
40 IoMarkIrpPending( Irp
);
43 if (Irp
->IoStatus
.Status
== STATUS_INVALID_DEVICE_REQUEST
)
44 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
46 return STATUS_SUCCESS
;
49 __drv_mustHoldCriticalRegion
51 RfsdFlushFiles (IN PRFSD_VCB Vcb
, BOOLEAN bShutDown
)
53 IO_STATUS_BLOCK IoStatus
;
55 PLIST_ENTRY ListEntry
;
59 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
60 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
61 return STATUS_SUCCESS
;
64 RfsdPrint((DBG_INFO
, "Flushing Files ...\n"));
66 // Flush all Fcbs in Vcb list queue.
68 for (ListEntry
= Vcb
->FcbList
.Flink
;
69 ListEntry
!= &Vcb
->FcbList
;
70 ListEntry
= ListEntry
->Flink
) {
72 Fcb
= CONTAINING_RECORD(ListEntry
, RFSD_FCB
, Next
);
74 if (ExAcquireResourceExclusiveLite(
78 IoStatus
.Status
= RfsdFlushFile(Fcb
);
81 IoStatus.Status = RfsdPurgeFile(Fcb, TRUE);
83 IoStatus.Status = RfsdFlushFile(Fcb);
85 ExReleaseResourceForThreadLite(
87 ExGetCurrentResourceThread());
92 return IoStatus
.Status
;
95 __drv_mustHoldCriticalRegion
97 RfsdFlushVolume (IN PRFSD_VCB Vcb
, BOOLEAN bShutDown
)
99 IO_STATUS_BLOCK IoStatus
;
103 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
104 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
105 return STATUS_SUCCESS
;
108 RfsdPrint((DBG_INFO
, "RfsdFlushVolume: Flushing Vcb ...\n"));
110 ExAcquireSharedStarveExclusive(&Vcb
->PagingIoResource
, TRUE
);
111 ExReleaseResourceLite(&Vcb
->PagingIoResource
);
113 CcFlushCache(&(Vcb
->SectionObject
), NULL
, 0, &IoStatus
);
115 return IoStatus
.Status
;
119 RfsdFlushFile (IN PRFSD_FCB Fcb
)
121 IO_STATUS_BLOCK IoStatus
;
127 ASSERT((Fcb
->Identifier
.Type
== RFSDFCB
) &&
128 (Fcb
->Identifier
.Size
== sizeof(RFSD_FCB
)));
130 if (IsDirectory(Fcb
))
131 return STATUS_SUCCESS
;
133 RfsdPrint((DBG_INFO
, "RfsdFlushFile: Flushing File Key=%x,%xh %S ...\n",
134 Fcb
->RfsdMcb
->Key
.k_dir_id
, Fcb
->RfsdMcb
->Key
.k_objectid
, Fcb
->RfsdMcb
->ShortName
.Buffer
));
137 ULONG ResShCnt, ResExCnt;
138 ResShCnt = ExIsResourceAcquiredSharedLite(&Fcb->PagingIoResource);
139 ResExCnt = ExIsResourceAcquiredExclusiveLite(&Fcb->PagingIoResource);
141 RfsdPrint((DBG_INFO, "RfsdFlushFile: PagingIoRes: %xh:%xh\n", ResShCnt, ResExCnt));
144 CcFlushCache(&(Fcb
->SectionObject
), NULL
, 0, &IoStatus
);
146 ClearFlag(Fcb
->Flags
, FCB_FILE_MODIFIED
);
148 return IoStatus
.Status
;
151 __drv_mustHoldCriticalRegion
153 RfsdFlush (IN PRFSD_IRP_CONTEXT IrpContext
)
158 PIO_STACK_LOCATION IrpSp
;
161 PRFSD_FCBVCB FcbOrVcb
= 0;
162 PFILE_OBJECT FileObject
;
164 PDEVICE_OBJECT DeviceObject
;
166 BOOLEAN MainResourceAcquired
= FALSE
;
174 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
175 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
177 DeviceObject
= IrpContext
->DeviceObject
;
180 // This request is not allowed on the main device object
182 if (DeviceObject
== RfsdGlobal
->DeviceObject
) {
183 Status
= STATUS_INVALID_DEVICE_REQUEST
;
187 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
191 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
192 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
194 ASSERT(IsMounted(Vcb
));
196 if ( IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
197 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
198 Status
= STATUS_SUCCESS
;
202 Irp
= IrpContext
->Irp
;
204 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
206 FileObject
= IrpContext
->FileObject
;
208 FcbOrVcb
= (PRFSD_FCBVCB
) FileObject
->FsContext
;
210 ASSERT(FcbOrVcb
!= NULL
);
213 #pragma prefast( suppress: 28137, "by design" )
215 if (!ExAcquireResourceExclusiveLite(
216 &FcbOrVcb
->MainResource
,
217 IrpContext
->IsSynchronous
)) {
218 Status
= STATUS_PENDING
;
222 MainResourceAcquired
= TRUE
;
224 if (FcbOrVcb
->Identifier
.Type
== RFSDVCB
) {
226 Status
= RfsdFlushFiles((PRFSD_VCB
)(FcbOrVcb
), FALSE
);
228 if (NT_SUCCESS(Status
)) {
232 Status
= RfsdFlushVolume((PRFSD_VCB
)(FcbOrVcb
), FALSE
);
234 if (NT_SUCCESS(Status
) && IsFlagOn(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
)) {
235 ClearFlag(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
);
238 } else if (FcbOrVcb
->Identifier
.Type
== RFSDFCB
) {
240 Status
= RfsdFlushFile((PRFSD_FCB
)(FcbOrVcb
));
242 if (NT_SUCCESS(Status
) && IsFlagOn(FileObject
->Flags
, FO_FILE_MODIFIED
)) {
243 ClearFlag(FileObject
->Flags
, FO_FILE_MODIFIED
);
249 if (MainResourceAcquired
) {
250 ExReleaseResourceForThreadLite(
251 &FcbOrVcb
->MainResource
,
252 ExGetCurrentResourceThread() );
255 if (!IrpContext
->ExceptionInProgress
) {
257 if (!IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
259 // Call the disk driver to flush the physial media.
260 NTSTATUS DriverStatus
;
261 PIO_STACK_LOCATION IrpSp
;
262 PIO_STACK_LOCATION NextIrpSp
;
264 IrpSp
= IoGetCurrentIrpStackLocation(IrpContext
->Irp
);
265 NextIrpSp
= IoGetNextIrpStackLocation(IrpContext
->Irp
);
269 IoSetCompletionRoutine( IrpContext
->Irp
,
270 RfsdFlushCompletionRoutine
,
276 DriverStatus
= IoCallDriver(Vcb
->TargetDeviceObject
, IrpContext
->Irp
);
278 Status
= (DriverStatus
== STATUS_INVALID_DEVICE_REQUEST
) ?
279 Status
: DriverStatus
;
281 IrpContext
->Irp
= Irp
= NULL
;
284 RfsdCompleteIrpContext(IrpContext
, Status
);