Why TopLevelIrp is FSRTL_FAST_IO_TOP_LEVEL_IRP but resources are not held?

I encounter TopLevelIrp == FSRTL_FAST_IO_TOP_LEVEL_IRP during a Paging I/O
read to a memory-mapped file on my volume, and I do not understand the
resource acquisition rules under these circumstances. I am developing an
FSD, not a filter.

I have presumed that when my FSD is not top-level (like in this case when
TopLevelIrp == FSRTL_FAST_IO_TOP_LEVEL_IRP), I need not acquire resources
because the top-level component has pre-acquired them directly or via
callbacks to my FSD. But in this case, neither MainResource or
PagingIoResource has been pre-acquired.

Scenario:

I use XCOPY to copy a file from my FSD to drive C (FastFat). In some
cases, XCOPY seems to open the source file on my driver as a memory-mapped
file. Also, in this particular case, it does Fast I/O writing to the
target file on the C drive. The thread that does Fast I/O write to the C
drive, a page fault occurs because the source data comes from a
memory-mapped file on my FSD’s drive. My FSD receives IRP_MJ_READ because
of this Paging I/O read request. NOW: In this case, IoGetTopLevelIrp()
returns FSRTL_FAST_IO_TOP_LEVEL_IRP, but no one has yet acquired any
resources of the source file (the memory-mapped file on my drive).

How should I interpret this situation? If I don’t reserve resources
because my FSD is not top level, I will end up reading from the source
file without holding PagingIoResource shared. On the other hand, I do not
see why I should take care of acquiring the resources in this case since
my FSD is not top-level and I have understood that the top-level component
is responsible for acquiring the resources (although I know that
recursively acquiring the resources in the same thread would succeed).

Anyway, I am concerned because obviously I have somehow misunderstood the
TopLevelIrp concept at least in this case. Can someone explain how I
should interpret the situation (and why I am responsible for acquiring the
resources in this case although my FSD is not top-level).

The stack trace is below.

myfsd!MYFSDReadCommon+0xc0
myfsd!MYFSDRead+0x19 <= This is Paging I/O read from the source file
on my FSD drive
nt!IovSpecialIrpCallDriver+0xcd
+0xf6fc3c71
+0xf6fc40cf
nt!IovSpecialIrpCallDriver+0xcd
nt!IoPageRead+0xb1
nt!MiDispatchFault+0x24c
nt!MmAccessFault+0xd1a
nt!KiTrap0E+0xc7
nt!MmCopyToCachedPage+0x5c
nt!CcMapAndCopy+0x197
nt!CcFastCopyWrite+0x432
nt!FsRtlCopyWrite+0x270
+0xf6fc5f33
nt!NtWriteFile+0x36b <= This is writing to the target file on C drive
(FastFat)
nt!KiSystemService+0xc9
+0x77f823b2
+0x7c58b87a
+0x7c589608
+0x7c589d8f
+0x7552665b
+0x1004446
+0x10037ad
+0x1003301
+0x1002dad
+0x1005a2f
+0x7c5987e7

My FSD does not currently support Fast I/O at all. Fast I/O is occurring
on the C drive.

Best regards,
Antti Nivala
###########################################

This message has been scanned by F-Secure Anti-Virus for Microsoft
Exchange.
For more information, connect to http://www.F-Secure.com/