mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 14:34:57 +08:00
[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.
This commit is contained in:
@@ -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);
|
||||
|
||||
ASSERT((!CompleteIrp && !QueueIrp) ||
|
||||
(CompleteIrp && !QueueIrp) ||
|
||||
(!CompleteIrp && QueueIrp));
|
||||
|
||||
if (CompleteIrp)
|
||||
if (IrpContext != NULL)
|
||||
{
|
||||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
|
||||
}
|
||||
QueueIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_QUEUE);
|
||||
CompleteIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE);
|
||||
|
||||
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);
|
||||
ASSERT((!CompleteIrp && !QueueIrp) ||
|
||||
(CompleteIrp && !QueueIrp) ||
|
||||
(!CompleteIrp && QueueIrp));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1189,7 +1189,7 @@ VfatRead(
|
||||
|
||||
NTSTATUS
|
||||
VfatWrite(
|
||||
PVFAT_IRP_CONTEXT IrpContext);
|
||||
PVFAT_IRP_CONTEXT *pIrpContext);
|
||||
|
||||
NTSTATUS
|
||||
NextCluster(
|
||||
|
||||
Reference in New Issue
Block a user