- Make the initial NpfsRead wait uninterruptible since it's really being used like a mutex (avoid the kernel stack being paged out during the wait causing memory corruption)
- Handle interrupted waits that were missed in certain cases
- Fix a potential deadlock that would happen if more I/O was done on a file object after the previous operation was interrupted by an APC or alert

svn path=/trunk/; revision=54325
This commit is contained in:
Cameron Gutman 2011-11-06 23:40:06 +00:00
parent 1f8bcd7af2
commit 35a7096ebc
2 changed files with 16 additions and 22 deletions

View file

@ -183,11 +183,13 @@ NpfsConnectPipe(PIRP Irp,
if (Flags & FO_SYNCHRONOUS_IO) if (Flags & FO_SYNCHRONOUS_IO)
{ {
KeWaitForSingleObject(&Ccb->ConnectEvent, Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest, UserRequest,
Irp->RequestorMode, Irp->RequestorMode,
(Flags & FO_ALERTABLE_IO), (Flags & FO_ALERTABLE_IO),
NULL); NULL);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
Status = STATUS_CANCELLED;
} }
DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status); DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
@ -403,11 +405,13 @@ NpfsWaitPipe(PIRP Irp,
TimeOut = NULL; TimeOut = NULL;
} }
Status = KeWaitForSingleObject(&Ccb->ConnectEvent, Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest, UserRequest,
Irp->RequestorMode, Irp->RequestorMode,
(Ccb->FileObject->Flags & FO_ALERTABLE_IO), (Ccb->FileObject->Flags & FO_ALERTABLE_IO),
TimeOut); TimeOut);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
Status = STATUS_CANCELLED;
DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status); DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
@ -526,6 +530,8 @@ NpfsWaitPipe2(PIRP Irp,
Irp->RequestorMode, Irp->RequestorMode,
(Ccb->FileObject->Flags & FO_ALERTABLE_IO), (Ccb->FileObject->Flags & FO_ALERTABLE_IO),
&TimeOut); &TimeOut);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
Status = STATUS_CANCELLED;
DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status); DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);

View file

@ -373,20 +373,11 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
KeInitializeEvent(&Event, SynchronizationEvent, FALSE); KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
Context->WaitEvent = &Event; Context->WaitEvent = &Event;
ExReleaseFastMutex(&Ccb->DataListLock); ExReleaseFastMutex(&Ccb->DataListLock);
Status = KeWaitForSingleObject(&Event, KeWaitForSingleObject(&Event,
UserRequest, Executive,
Irp->RequestorMode, KernelMode,
(FileObject->Flags & FO_ALERTABLE_IO), FALSE,
NULL); NULL);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
{
Status = STATUS_CANCELLED;
goto done;
}
if (!NT_SUCCESS(Status))
{
ASSERT(FALSE);
}
ExAcquireFastMutex(&Ccb->DataListLock); ExAcquireFastMutex(&Ccb->DataListLock);
} }
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -662,9 +653,6 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL); ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
if (Status == STATUS_CANCELLED)
goto done;
if (IoIsOperationSynchronous(Irp)) if (IoIsOperationSynchronous(Irp))
{ {
RemoveEntryList(&Context->ListEntry); RemoveEntryList(&Context->ListEntry);