diff --git a/drivers/filesystems/fastfat/cleanup.c b/drivers/filesystems/fastfat/cleanup.c
index d19fa94703..fe2c915245 100644
--- a/drivers/filesystems/fastfat/cleanup.c
+++ b/drivers/filesystems/fastfat/cleanup.c
@@ -4,6 +4,7 @@
  * FILE:             drivers/fs/vfat/cleanup.c
  * PURPOSE:          VFAT Filesystem
  * PROGRAMMER:       Jason Filby (jasonfilby@yahoo.com)
+ *                   Pierre Schweitzer (pierre@reactos.org)
  */
 
 /* INCLUDES *****************************************************************/
@@ -127,6 +128,23 @@ VfatCleanupFile(
         {
             IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
         }
+        /* If that's the last open handle we just closed, try to see whether
+         * we can delay close operation
+         */
+        else if (!BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) && !BooleanFlagOn(pFcb->Flags, FCB_IS_PAGE_FILE) &&
+                 !BooleanFlagOn(pFcb->Flags, FCB_IS_FAT) && !BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME))
+        {
+            /* This is only allowed if that's a directory with no open files
+             * OR if there's no section opened
+             */
+            if ((vfatFCBIsDirectory(pFcb) && IsListEmpty(&pFcb->ParentListHead)) ||
+                (FileObject->SectionObjectPointer->DataSectionObject == NULL &&
+                 FileObject->SectionObjectPointer->ImageSectionObject == NULL))
+            {
+                DPRINT("Delaying close of: %wZ\n", &pFcb->PathNameU);
+                SetFlag(pFcb->Flags, FCB_DELAYED_CLOSE);
+            }
+        }
 
         FileObject->Flags |= FO_CLEANUP_COMPLETE;
 #ifdef KDBG
diff --git a/drivers/filesystems/fastfat/close.c b/drivers/filesystems/fastfat/close.c
index bb5cfaae78..95b35d2524 100644
--- a/drivers/filesystems/fastfat/close.c
+++ b/drivers/filesystems/fastfat/close.c
@@ -4,6 +4,7 @@
  * FILE:             drivers/filesystems/fastfat/close.c
  * PURPOSE:          VFAT Filesystem
  * PROGRAMMER:       Jason Filby (jasonfilby@yahoo.com)
+ *                   Pierre Schweitzer (pierre@reactos.org)
  */
 
 /* INCLUDES *****************************************************************/
@@ -15,6 +16,143 @@
 
 /* FUNCTIONS ****************************************************************/
 
+VOID
+VfatCommonCloseFile(
+    PDEVICE_EXTENSION DeviceExt,
+    PVFATFCB pFcb)
+{
+    /* Nothing to do for volumes */
+    if (BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME))
+    {
+        return;
+    }
+
+    /* If cache is still initialized, release it
+     * This only affects directories
+     */
+    if (pFcb->OpenHandleCount == 0 && BooleanFlagOn(pFcb->Flags, FCB_CACHE_INITIALIZED))
+    {
+        PFILE_OBJECT tmpFileObject;
+        tmpFileObject = pFcb->FileObject;
+        if (tmpFileObject != NULL)
+        {
+            pFcb->FileObject = NULL;
+            CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
+            ClearFlag(pFcb->Flags, FCB_CACHE_INITIALIZED);
+            ObDereferenceObject(tmpFileObject);
+        }
+    }
+
+#ifdef KDBG
+    pFcb->Flags |= FCB_CLOSED;
+#endif
+
+    /* Release the FCB, we likely cause its deletion */
+    vfatReleaseFCB(DeviceExt, pFcb);
+}
+
+VOID
+NTAPI
+VfatCloseWorker(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID Context)
+{
+    PLIST_ENTRY Entry;
+    PVFATFCB pFcb;
+    PDEVICE_EXTENSION Vcb;
+    PVFAT_CLOSE_CONTEXT CloseContext;
+    BOOLEAN ConcurrentDeletion;
+
+    /* Start removing work items */
+    ExAcquireFastMutex(&VfatGlobalData->CloseMutex);
+    while (!IsListEmpty(&VfatGlobalData->CloseListHead))
+    {
+        Entry = RemoveHeadList(&VfatGlobalData->CloseListHead);
+        CloseContext = CONTAINING_RECORD(Entry, VFAT_CLOSE_CONTEXT, CloseListEntry);
+
+        /* One less */
+        --VfatGlobalData->CloseCount;
+        /* Reset its entry to detect concurrent deletions */
+        InitializeListHead(&CloseContext->CloseListEntry);
+        ExReleaseFastMutex(&VfatGlobalData->CloseMutex);
+
+        /* Get the elements */
+        Vcb = CloseContext->Vcb;
+        pFcb = CloseContext->Fcb;
+        ExAcquireResourceExclusiveLite(&Vcb->DirResource, TRUE);
+        /* If it didn't got deleted in between */
+        if (BooleanFlagOn(pFcb->Flags, FCB_DELAYED_CLOSE))
+        {
+            /* Close it! */
+            DPRINT("Late closing: %wZ\n", &pFcb->PathNameU);
+            ClearFlag(pFcb->Flags, FCB_DELAYED_CLOSE);
+            pFcb->CloseContext = NULL;
+            VfatCommonCloseFile(Vcb, pFcb);
+            ConcurrentDeletion = FALSE;
+        }
+        else
+        {
+            /* Otherwise, mark not to delete it */
+            ConcurrentDeletion = TRUE;
+        }
+        ExReleaseResourceLite(&Vcb->DirResource);
+
+        /* If we were the fastest, delete the context */
+        if (!ConcurrentDeletion)
+        {
+            ExFreePoolWithTag(CloseContext, TAG_VFAT);
+        }
+
+        /* Lock again the list */
+        ExAcquireFastMutex(&VfatGlobalData->CloseMutex);
+    }
+
+    /* We're done, bye! */
+    VfatGlobalData->CloseWorkerRunning = FALSE;
+    ExReleaseFastMutex(&VfatGlobalData->CloseMutex);
+}
+
+NTSTATUS
+VfatPostCloseFile(
+    PDEVICE_EXTENSION DeviceExt,
+    PFILE_OBJECT FileObject)
+{
+    PVFAT_CLOSE_CONTEXT CloseContext;
+
+    /* Allocate a work item */
+    CloseContext = ExAllocatePoolWithTag(PagedPool, sizeof(VFAT_CLOSE_CONTEXT), TAG_VFAT);
+    if (CloseContext == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Set relevant fields */
+    CloseContext->Vcb = DeviceExt;
+    CloseContext->Fcb = FileObject->FsContext;
+    CloseContext->Fcb->CloseContext = CloseContext;
+
+    /* Acquire the lock to insert in list */
+    ExAcquireFastMutex(&VfatGlobalData->CloseMutex);
+
+    /* One more element */
+    InsertTailList(&VfatGlobalData->CloseListHead, &CloseContext->CloseListEntry);
+    ++VfatGlobalData->CloseCount;
+
+    /* If we have more than 16 items in list, and no worker thread
+     * start a new one
+     */
+    if (VfatGlobalData->CloseCount > 16 && !VfatGlobalData->CloseWorkerRunning)
+    {
+        VfatGlobalData->CloseWorkerRunning = TRUE;
+        IoQueueWorkItem(VfatGlobalData->CloseWorkItem, VfatCloseWorker, CriticalWorkQueue, NULL);
+    }
+
+    /* We're done */
+    ExReleaseFastMutex(&VfatGlobalData->CloseMutex);
+
+    return STATUS_SUCCESS;
+}
+
 /*
  * FUNCTION: Closes a file
  */
@@ -25,7 +163,6 @@ VfatCloseFile(
 {
     PVFATFCB pFcb;
     PVFATCCB pCcb;
-    BOOLEAN IsVolume;
     NTSTATUS Status = STATUS_SUCCESS;
 
     DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
@@ -40,31 +177,10 @@ VfatCloseFile(
         return STATUS_SUCCESS;
     }
 
-    IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME);
-    if (IsVolume)
+    /* If we have to close immediately, or if delaying failed, close */
+    if (!BooleanFlagOn(pFcb->Flags, FCB_DELAYED_CLOSE) || !NT_SUCCESS(VfatPostCloseFile(DeviceExt, FileObject)))
     {
-        DPRINT("Volume\n");
-        FileObject->FsContext2 = NULL;
-    }
-    else
-    {
-        if (pFcb->OpenHandleCount == 0 && BooleanFlagOn(pFcb->Flags, FCB_CACHE_INITIALIZED))
-        {
-            PFILE_OBJECT tmpFileObject;
-            tmpFileObject = pFcb->FileObject;
-            if (tmpFileObject != NULL)
-            {
-                pFcb->FileObject = NULL;
-                CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
-                ClearFlag(pFcb->Flags, FCB_CACHE_INITIALIZED);
-                ObDereferenceObject(tmpFileObject);
-            }
-        }
-
-#ifdef KDBG
-        pFcb->Flags |= FCB_CLOSED;
-#endif
-        vfatReleaseFCB(DeviceExt, pFcb);
+        VfatCommonCloseFile(DeviceExt, pFcb);
     }
 
     FileObject->FsContext2 = NULL;
@@ -77,7 +193,7 @@ VfatCloseFile(
     }
 
 #ifdef ENABLE_SWAPOUT
-    if (IsVolume && DeviceExt->OpenHandleCount == 0)
+    if (BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME) && DeviceExt->OpenHandleCount == 0)
     {
         VfatCheckForDismount(DeviceExt, FALSE);
     }
diff --git a/drivers/filesystems/fastfat/create.c b/drivers/filesystems/fastfat/create.c
index e2fbccaf9c..2206dad627 100644
--- a/drivers/filesystems/fastfat/create.c
+++ b/drivers/filesystems/fastfat/create.c
@@ -370,6 +370,40 @@ VfatOpenFile(
         return STATUS_CANNOT_DELETE;
     }
 
+    /* If that one was marked for closing, remove it */
+    if (BooleanFlagOn(Fcb->Flags, FCB_DELAYED_CLOSE))
+    {
+        BOOLEAN ConcurrentDeletion;
+        PVFAT_CLOSE_CONTEXT CloseContext;
+
+        /* Get the context */
+        CloseContext = Fcb->CloseContext;
+        ConcurrentDeletion = FALSE;
+        /* Lock list */
+        ExAcquireFastMutex(&VfatGlobalData->CloseMutex);
+        /* Check whether it was already removed, if not, do it */
+        if (!IsListEmpty(&CloseContext->CloseListEntry))
+        {
+            RemoveEntryList(&CloseContext->CloseListEntry);
+            --VfatGlobalData->CloseCount;
+            ConcurrentDeletion = TRUE;
+        }
+        ExReleaseFastMutex(&VfatGlobalData->CloseMutex);
+
+        /* It's not delayed anymore! */
+        ClearFlag(Fcb->Flags, FCB_DELAYED_CLOSE);
+        /* Release the extra reference (would have been removed by IRP_MJ_CLOSE) */
+        vfatReleaseFCB(DeviceExt, Fcb);
+        Fcb->CloseContext = NULL;
+        /* If no concurrent deletion, free work item */
+        if (!ConcurrentDeletion)
+        {
+            ExFreePoolWithTag(CloseContext, TAG_VFAT);
+        }
+
+        DPRINT("Reusing delayed close FCB for %wZ\n", &Fcb->PathNameU);
+    }
+
     DPRINT("Attaching FCB to fileObject\n");
     Status = vfatAttachFCBToFileObject(DeviceExt, Fcb, FileObject);
     if (!NT_SUCCESS(Status))
diff --git a/drivers/filesystems/fastfat/iface.c b/drivers/filesystems/fastfat/iface.c
index 41653a2549..152dfcf287 100644
--- a/drivers/filesystems/fastfat/iface.c
+++ b/drivers/filesystems/fastfat/iface.c
@@ -21,6 +21,7 @@
  * FILE:             drivers/fs/vfat/iface.c
  * PURPOSE:          VFAT Filesystem
  * PROGRAMMER:       Jason Filby (jasonfilby@yahoo.com)
+ *                   Pierre Schweitzer (pierre@reactos.org)
  */
 
 /* INCLUDES *****************************************************************/
@@ -95,6 +96,18 @@ DriverEntry(
      * has been detected:
     VfatGlobalData->Flags = VFAT_BREAK_ON_CORRUPTION; */
 
+    /* Delayed close support */
+    ExInitializeFastMutex(&VfatGlobalData->CloseMutex);
+    InitializeListHead(&VfatGlobalData->CloseListHead);
+    VfatGlobalData->CloseCount = 0;
+    VfatGlobalData->CloseWorkerRunning = FALSE;
+    VfatGlobalData->CloseWorkItem = IoAllocateWorkItem(DeviceObject);
+    if (VfatGlobalData->CloseWorkItem == NULL)
+    {
+        IoDeleteDevice(DeviceObject);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
     DeviceObject->Flags |= DO_DIRECT_IO;
     DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
     DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h
index bec3dc8394..30860409ab 100644
--- a/drivers/filesystems/fastfat/vfat.h
+++ b/drivers/filesystems/fastfat/vfat.h
@@ -269,6 +269,7 @@ typedef struct
 struct _VFATFCB;
 struct _VFAT_DIRENTRY_CONTEXT;
 struct _VFAT_MOVE_CONTEXT;
+struct _VFAT_CLOSE_CONTEXT;
 
 typedef struct _HASHENTRY
 {
@@ -410,6 +411,11 @@ typedef struct
     NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
     FAST_IO_DISPATCH FastIoDispatch;
     CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
+    FAST_MUTEX CloseMutex;
+    ULONG CloseCount;
+    LIST_ENTRY CloseListHead;
+    BOOLEAN CloseWorkerRunning;
+    PIO_WORKITEM CloseWorkItem;
 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
 
 extern PVFAT_GLOBAL_DATA VfatGlobalData;
@@ -420,9 +426,10 @@ extern PVFAT_GLOBAL_DATA VfatGlobalData;
 #define FCB_IS_PAGE_FILE        0x0008
 #define FCB_IS_VOLUME           0x0010
 #define FCB_IS_DIRTY            0x0020
+#define FCB_DELAYED_CLOSE       0x0040
 #ifdef KDBG
-#define FCB_CLEANED_UP          0x0040
-#define FCB_CLOSED              0x0080
+#define FCB_CLEANED_UP          0x0080
+#define FCB_CLOSED              0x0100
 #endif
 
 #define NODE_TYPE_FCB ((CSHORT)0x0502)
@@ -510,6 +517,8 @@ typedef struct _VFATFCB
     FAST_MUTEX LastMutex;
     ULONG LastCluster;
     ULONG LastOffset;
+
+    struct _VFAT_CLOSE_CONTEXT * CloseContext;
 } VFATFCB, *PVFATFCB;
 
 #define CCB_DELETE_ON_CLOSE     0x0001
@@ -588,6 +597,13 @@ typedef struct _VFAT_MOVE_CONTEXT
     BOOLEAN InPlace;
 } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
 
+typedef struct _VFAT_CLOSE_CONTEXT
+{
+    PDEVICE_EXTENSION Vcb;
+    PVFATFCB Fcb;
+    LIST_ENTRY CloseListEntry;
+} VFAT_CLOSE_CONTEXT, *PVFAT_CLOSE_CONTEXT;
+
 FORCEINLINE
 NTSTATUS
 VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
