[FASTFAT] Implement write IOs defering.
authorPierre Schweitzer <pierre@reactos.org>
Sun, 29 Apr 2018 18:42:24 +0000 (20:42 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 29 Apr 2018 18:42:53 +0000 (20:42 +0200)
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
drivers/filesystems/fastfat/rw.c
drivers/filesystems/fastfat/vfat.h

index 7797f37..0d29177 100644 (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(
index 25114f2..4dd5993 100644 (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;
index 5bb5289..cb38b16 100644 (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