https://git.reactos.org/?p=reactos.git;a=commitdiff;h=320abafdc3ce9c89d561b…
commit 320abafdc3ce9c89d561bb41e4d5bd6a34f1442e
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sun Oct 11 15:02:26 2020 +0200
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Fri Oct 16 16:18:56 2020 +0200
[FASTFAT] Ensure that deferred write IRP contexts are not touched. CORE-17328
Cc may decide to process deferred writes any time, so the context might
already be freed by the time we return from CcDeferWrite.
Also mark the IRP as pending, since we're going to return STATUS_PENDING.
---
drivers/filesystems/fastfat/misc.c | 47 ++++++++++++++++++++------------------
drivers/filesystems/fastfat/rw.c | 11 +++++----
drivers/filesystems/fastfat/vfat.h | 2 +-
3 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/drivers/filesystems/fastfat/misc.c b/drivers/filesystems/fastfat/misc.c
index 4f7bf5b7d4b..443ad290817 100644
--- a/drivers/filesystems/fastfat/misc.c
+++ b/drivers/filesystems/fastfat/misc.c
@@ -130,7 +130,7 @@ VfatDispatchRequest(
break;
case IRP_MJ_WRITE:
- Status = VfatWrite(IrpContext);
+ Status = VfatWrite(&IrpContext);
break;
case IRP_MJ_FILE_SYSTEM_CONTROL:
@@ -182,30 +182,33 @@ VfatDispatchRequest(
Status = STATUS_DRIVER_INTERNAL_ERROR;
}
- QueueIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_QUEUE);
- CompleteIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE);
+ if (IrpContext != NULL)
+ {
+ QueueIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_QUEUE);
+ CompleteIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE);
- ASSERT((!CompleteIrp && !QueueIrp) ||
- (CompleteIrp && !QueueIrp) ||
- (!CompleteIrp && QueueIrp));
+ ASSERT((!CompleteIrp && !QueueIrp) ||
+ (CompleteIrp && !QueueIrp) ||
+ (!CompleteIrp && QueueIrp));
- if (CompleteIrp)
- {
- IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
- }
+ if (CompleteIrp)
+ {
+ IrpContext->Irp->IoStatus.Status = Status;
+ IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
+ }
- if (QueueIrp)
- {
- /* Reset our status flags before queueing the IRP */
- IrpContext->Flags |= IRPCONTEXT_COMPLETE;
- IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
- Status = VfatQueueRequest(IrpContext);
- }
- else
- {
- /* Unless the IRP was queued, always free the IRP context */
- VfatFreeIrpContext(IrpContext);
+ if (QueueIrp)
+ {
+ /* Reset our status flags before queueing the IRP */
+ IrpContext->Flags |= IRPCONTEXT_COMPLETE;
+ IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
+ Status = VfatQueueRequest(IrpContext);
+ }
+ else
+ {
+ /* Unless the IRP was queued, always free the IRP context */
+ VfatFreeIrpContext(IrpContext);
+ }
}
FsRtlExitFileSystem();
diff --git a/drivers/filesystems/fastfat/rw.c b/drivers/filesystems/fastfat/rw.c
index 60713e104c4..0afebafe893 100644
--- a/drivers/filesystems/fastfat/rw.c
+++ b/drivers/filesystems/fastfat/rw.c
@@ -873,8 +873,9 @@ ByeBye:
NTSTATUS
VfatWrite(
- PVFAT_IRP_CONTEXT IrpContext)
+ PVFAT_IRP_CONTEXT *pIrpContext)
{
+ PVFAT_IRP_CONTEXT IrpContext = *pIrpContext;
PVFATFCB Fcb;
PERESOURCE Resource = NULL;
LARGE_INTEGER ByteOffset;
@@ -999,13 +1000,15 @@ VfatWrite(
Retrying = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE);
SetFlag(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE);
+ IoMarkIrpPending(IrpContext->Irp);
Status = STATUS_PENDING;
+
+ DPRINT1("Deferring write for Irp %p, context %p!\n",
IrpContext->Irp, IrpContext);
CcDeferWrite(IrpContext->FileObject, VfatHandleDeferredWrite,
IrpContext, NULL, Length, Retrying);
+ *pIrpContext = NULL;
- DPRINT1("Dererring write!\n");
-
- goto ByeBye;
+ return Status;
}
if (IsVolume)
diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h
index 593ceb7c2da..fcb3a25cca7 100644
--- a/drivers/filesystems/fastfat/vfat.h
+++ b/drivers/filesystems/fastfat/vfat.h
@@ -1189,7 +1189,7 @@ VfatRead(
NTSTATUS
VfatWrite(
- PVFAT_IRP_CONTEXT IrpContext);
+ PVFAT_IRP_CONTEXT *pIrpContext);
NTSTATUS
NextCluster(