mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00: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:
parent
6b3f309a08
commit
320abafdc3
3 changed files with 34 additions and 28 deletions
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue