Re: Why TopLevelIrp is FSRTL_FAST_IO_TOP_LEVEL_IRP but resources are not held?

If the top level field is NULL, you have a guarantee that there are no
FSD resources pre-acquired, but the converse is apparently not always
true. In this case (a simple page fault on a memory-mapped range) it
looks like the VMM has decided not to acquire any locks of its own, so
therefore it had no need to pre-acquire the FSD’s locks. In any case, in
your read/write dispatch routines your FSD should acquire whatever
resources needed to ensure the integrity of the individual request. And
since ERESOURCEs can be acquire recursively, there should be no issues
if the necessary resources have already been pre-acquired by one of the
FSD pre-acquire routines (I suggest you take a look at the FASTFAT
source for details).

Antti Nivala wrote:

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/


Nick Ryan (MVP for DDK)