There are a few general rules and a few exceptions:
- You must return STATUS_PENDING if you mark the IRP pending.
- You must not return STATUS_PENDING if you don’t mark the IRP pending.
- If you register an IO completion routine, your completion routine is
responsible for propagating the SL_PENDING_RETURNED flag to its IO stack
location. This is commonly done by placing the following snippet in your
completion routine:
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
The exception to this rule 3 is when you handle the IRP synchronously as
Joel has done. In that case, don’t return STATUS_PENDING, and don’t mark
the IRP pending either in dispatch or completion. This is consistent with
rule 2.
If your completion routine propagates the SL_PENDING_RETURNED flag, your
dispatch return must return STATUS_PENDING, either because it always returns
STATUS_PENDING, or the underlying driver returned STATUS_PENDING. This is
consistent with rule 1.
If you don’t follow the rules, typically either one of two bad things may
happen. If you return STATUS_PENDING and don’t mark the IRP pending, then
the IO request may hang. If you don’t return STATUS_PENDING, and you do
mark the IRP pending, then IopCompleteRequest may be called twice, once by
IoCompleteRequest queuing an APC object, and again by ZwXxxFile.
There is yet another set of exceptions. These are types of IRP’s for which
you shouldn’t return STATUS_PENDING unless the underlying FSD returns
STATUS_PENDING. For example, if the IRP is of type FSCTL_REQUEST_OPLOCK,
then STATUS_PENDING means an oplock has been granted. There’s an article
about OPLOCK’s at http://www.osr.com/ntinsider/1996/Oplock/Oplock.htm
http:
Hopefully, nobody is telling people filtering is easy. If time to market is
a consideration, then you’re best off purchasing a kit that handles the
majority of the filtering requirements, such as OSR’s FDDK.
-----Original Message-----
From: Smith, Joel [mailto:xxxxx@ntpsoftware.com]
Sent: Wednesday, August 02, 2000 8:08 AM
To: File Systems Developers
Subject: [ntfsd] RE: overlapped io
I don’t know if its the cause, but I don’t think you should be marking the
irp pending in your completion routine, since you’re forcing the io to be
synchronous anyways. With the code as presented, you could be returning a
NON-PENDING status code, while at the same time having marked the irp
pending.
-Joel
-----Original Message-----
From: Neil Weicher [mailto:xxxxx@netlib.com mailto:xxxxx]
Sent: Tuesday, August 01, 2000 8:49 PM
To: File Systems Developers
Subject: [ntfsd] overlapped io
Can anyone tell me what is wrong with this bare-bones IRP_MJ_READ handler?
It
works absolutely fine 99.9% of the time. But the machine hangs if when
running
an application using overlapped I/O. I know it would be more efficient to
use
an asynchronous read, but still, this shouldn’t hang the machine. Any ideas
would be greatly appreciated.
Thanks. - Neil
(PS - I don’t know if this is relevant, but the system appears to hang in
ExInterlockedPopEntrySList)
NTSTATUS IrpMjReadCompletion(PDEVICE_OBJECT DeviceObject,PIRP Irp,PVOID
Context)
{
if (Context != NULL) KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT,
FALSE);
if (Irp->PendingReturned) IoMarkIrpPending(Irp);
return (STATUS_MORE_PROCESSING_REQUIRED);
}
NTSTATUS IrpMjReadHandler(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS ntStatus;
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, IrpMjReadCompletion, &event, TRUE, TRUE,
TRUE);
if ((ntStatus = IoCallDriver(deviceExtension->FileSystemDeviceObject,
Irp)) == STATUS_PENDING)
{
KeWaitForSingleObject(&event, UserRequest, KernelMode, TRUE, NULL);
ntStatus = Irp->IoStatus.Status;
}
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return (ntStatus);
}
—
You are currently subscribed to ntfsd as: xxxxx@ntpsoftware.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</mailto:xxxxx></http:>