[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
This commit is contained in:
Pierre Schweitzer 2018-04-29 20:42:24 +02:00
parent f2c44aa483
commit 2a7d16727a
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
3 changed files with 33 additions and 0 deletions

View file

@ -213,6 +213,15 @@ VfatDispatchRequest(
return Status;
}
VOID
NTAPI
VfatHandleDeferredWrite(
IN PVOID IrpContext,
IN PVOID Unused)
{
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
}
NTSTATUS
NTAPI
VfatBuildRequest(

View file

@ -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;

View file

@ -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