From 2a7d16727a840b631076aaaa1cd00d09b9a32a80 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 29 Apr 2018 20:42:24 +0200 Subject: [PATCH] [FASTFAT] Implement write IOs defering. Before any write operation that would involve caching, ask the cache controler whether writing would make it exceed its memory consumption. If so, queue the write operation for later execution. In case the write operation can wait, then, the FSD operation will be halted until the write is allowed. I could test it successfully by copying huge files from a FAT volume to another. The write is halted until some portions of the file is written to the disk. I could also properly install Qt (SDK) on ReactOS with this and less than 1GB RAM: - https://www.heisspiter.net/~Pierre/rostests/Qt_OS.png - https://www.heisspiter.net/~Pierre/rostests/Qt_OS2.png CORE-12081 CORE-14582 CORE-14313 --- drivers/filesystems/fastfat/misc.c | 9 +++++++++ drivers/filesystems/fastfat/rw.c | 17 +++++++++++++++++ drivers/filesystems/fastfat/vfat.h | 7 +++++++ 3 files changed, 33 insertions(+) diff --git a/drivers/filesystems/fastfat/misc.c b/drivers/filesystems/fastfat/misc.c index 7797f37ab21..0d291776b57 100644 --- a/drivers/filesystems/fastfat/misc.c +++ b/drivers/filesystems/fastfat/misc.c @@ -213,6 +213,15 @@ VfatDispatchRequest( return Status; } +VOID +NTAPI +VfatHandleDeferredWrite( + IN PVOID IrpContext, + IN PVOID Unused) +{ + VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext); +} + NTSTATUS NTAPI VfatBuildRequest( diff --git a/drivers/filesystems/fastfat/rw.c b/drivers/filesystems/fastfat/rw.c index 25114f25cf7..4dd59933c44 100644 --- a/drivers/filesystems/fastfat/rw.c +++ b/drivers/filesystems/fastfat/rw.c @@ -895,6 +895,23 @@ VfatWrite( } } + if (!NoCache && !CcCanIWrite(IrpContext->FileObject, Length, CanWait, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE))) + { + BOOLEAN Retrying; + + Retrying = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE); + SetFlag(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE); + + Status = STATUS_PENDING; + CcDeferWrite(IrpContext->FileObject, VfatHandleDeferredWrite, + IrpContext, NULL, Length, Retrying); + + DPRINT1("Dererring write!\n"); + + goto ByeBye; + } + if (IsVolume) { Resource = &IrpContext->DeviceExt->DirResource; diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h index 5bb5289febe..cb38b16699f 100644 --- a/drivers/filesystems/fastfat/vfat.h +++ b/drivers/filesystems/fastfat/vfat.h @@ -544,6 +544,7 @@ DOSDATE, *PDOSDATE; #define IRPCONTEXT_COMPLETE 0x0002 #define IRPCONTEXT_QUEUE 0x0004 #define IRPCONTEXT_PENDINGRETURNED 0x0008 +#define IRPCONTEXT_DEFERRED_WRITE 0x0010 typedef struct { @@ -1085,6 +1086,12 @@ vfatReportChange( IN ULONG FilterMatch, IN ULONG Action); +VOID +NTAPI +VfatHandleDeferredWrite( + IN PVOID IrpContext, + IN PVOID Unused); + /* pnp.c */ NTSTATUS