Hi all,
Why does a call to CcCopyRead(), where the Wait argument is specified as
FALSE, cause a recursive *sync* paging io READ? I would have thought an
async paging io READ would have been triggered. Its not causing me any
problems (at least I don’t think so), I’m curious if I may be mishandling
IRP completion. But it does seem to imply that CcCopyRead() will wait even
when what the wait argument is false, if the underlying FSD truly implements
sync paging io in a synchronous way.
Below is an excerpt from the traces of my FSD. The first READ IRP
(8437cee8) is an async, cached, non-MDL READ from a user mode app (apache).
This calls CcCopyRead(), which causes the second READ IRP (86a1ef48) to be
called recursively. This is a sync paging io READ.
In my FSD, the paging io READ is sent to an user-mode service, so it gets
queued up in the driver while waiting for it to be processed. I am using
CSQs, so inserting the IRP into the queue implicitly calls
IoMarkIrpPending(). Because this READ IRP is sync, I do a
KeWaitForSingleObject() to wait for the IRP to complete before returning
from my READ dispatch routine. However, I still return STATUS_PENDING,
because the rules of IRP handling say that if I call IoMarkIrpPending(), I
must return STATUS_PENDING, even if the IRP has been completed in the
meantime.
Because I return STATUS_PENDING from the paging io READ to CcCopyRead(), and
because the Wait argument is FALSE, I suspect this causes CcCopyRead() to
return FALSE, although it seems unnecessary. Because CcCopyRead() returns
FALSE to the original READ from apache, my FSD interprets this as meaning
“CcCopyRead() could not do the read because it would need to block”, and so
it posts the READ IRP to a worker thread.
The worker thread then executes the original read again, but this time it is
satisfied immediately since Cc has the data. The worker thread completes
the original READ IRP.
I am doing anything incorrectly in the handling of the paging io read?
Thanks.
PIFSK:READ 8437cee8 DO=84482d70 “\hi.bmp” FO=84e2d2c8 [Apache.exe]
Thread=84380020
PIFSK:8437cee8 Flags=00000000
PIFSK:8437cee8 Minor=00(IRP_MN_NORMAL) Offset=0 Length=3031
PIFSK:8437cee8 StackFlags=00000000
PIFSK:8437cee8 FO=84e2d2c8 Flags=00040020 Bits= ReadAccess SharedRead
SharedWrite SharedDelete
PIFSK:8437cee8 FCB=8572baf0 Flags=00000050 Flags2=00000002
ACQUIRE_MAIN_RSRC_SH ADVANCED_HEADERSUPPORTS_FILTER_CONTEXTS
PIFSK:8437cee8 Alloc=360448 File=360054 VDL=360054
PIFSK:READ 86a1ef48 DO=84482d70 “\hi.bmp” FO=84e2d2c8 [Apache.exe]
Thread=84380020
PIFSK:86a1ef48 Flags=40000043 NOCACHE PAGING_IO SYNCHRONOUS_PAGING_IO
PIFSK:86a1ef48 Minor=00(IRP_MN_NORMAL) PAGING SYNC Offset=0 Length=4096
PIFSK:86a1ef48 StackFlags=00000000
PIFSK:86a1ef48 FO=84e2d2c8 Flags=00040060 CACHE_SUPPORTED Bits=
ReadAccess SharedRead SharedWrite SharedDelete
PIFSK:86a1ef48 FCB=8572baf0 Flags=00000050 Flags2=00000002
ACQUIRE_MAIN_RSRC_SH ADVANCED_HEADERSUPPORTS_FILTER_CONTEXTS
PIFSK:86a1ef48 Alloc=360448 File=360054 VDL=360054
PIFSK:READ 86a1ef48 COMPLETED Status=00000000(STATUS_SUCCESS)
Info=00001000(4096) Thread=84482900
PIFSK:8437cee8 Queuing work item 85b467d8
PIFSK:Work item 85b467d8 started
PIFSK:READ 8437cee8 DO=84482d70 “\hi.bmp” FO=84e2d2c8 [System]
Thread=85e483c8
PIFSK:8437cee8 Flags=00000004 SYNCHRONOUS_API
PIFSK:8437cee8 Minor=00(IRP_MN_NORMAL) SYNC Offset=0 Length=3031
PIFSK:8437cee8 StackFlags=00000000
PIFSK:8437cee8 FO=84e2d2c8 Flags=000c0060 CACHE_SUPPORTED Bits=
ReadAccess SharedRead SharedWrite SharedDelete
PIFSK:8437cee8 FCB=8572baf0 Flags=00000050 Flags2=00000002
ACQUIRE_MAIN_RSRC_SH ADVANCED_HEADERSUPPORTS_FILTER_CONTEXTS
PIFSK:8437cee8 Alloc=360448 File=360054 VDL=360054
PIFSK:READ 8437cee8 COMPLETED Status=00000000(STATUS_SUCCESS)
Info=00000bd7(3031) Thread=85e483c8
PIFSK:Work item 85b467d8 ended
=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]