MDL_PAGES_LOCKED assert

Hi all,

I am getting the following assert:

*** Assertion failed: (MemoryDescriptorList->MdlFlags & MDL_PAGES_LOCKED) !=
0
*** Source File: d:\xpsprtm\base\ntos\mm\iosup.c, line 2346

when I start up an Apache web server, and configures it to expose my file
system as a WebDAV folder. The machine running Apache is running a checked
version of xp sp2. The assert occurs when a remote client tries to read
from a file. The remote client is using the xp built-in WebDAV
mini-redirector.

The last IRP that goes through my FSD before the assert is an
IRP_MJ_READ/IRP_MN_MDL. I call CcMdlRead(), specifying the IRP’s MdlAddress
field as the 4th argument. I then complete the IRP. (I basically copied
the code from FASTFAT.) However, I’m not sure how the MDL causing the
assert and the MDL returned by my FSD are connected, since they do not
appear to be same.

I believe they are not the same because, while processing the
IRP_MJ_READ/IRP_MN_MDL, I see this (this is the state of the READ IRP
*after* I call CcMdlRead()):

kd> !irp poi(pirp) 2
Irp is active with 2 stacks 2 is current (= 0x86954fdc)
Mdl = 857f93c8 Thread 850323c8: Irp stack trace.
Flags = 40000004
UserBuffer = 00000000

cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000

[3, 2] 0 e0 855556d0 85aaae68 f53ee8ce-865fcf00 Success Error Cancel
\FileSystem\Pifsk afd!AfdRestartTPacketsMdlRead
Args: 00000ea0 00000000 00000bd7 00000000

kd> dt 857f93c8 MDL
+0x000 Next : (null)
+0x004 Size : 36
+0x006 MdlFlags : 10 <– is: MDL_PARTIAL
+0x008 Process : (null)
+0x00c MappedSystemVa : 0x855f9b68
+0x010 StartVa : 0xdae00000
+0x014 ByteCount : 0xea0
+0x018 ByteOffset : 0xbd7

However, when I get the assert, the call stack is this, and the MDL being
unlocked (853fafc4, between the >> and << below in the stack) is not the one
I returned from my FSD:

f235474c 80abbf3e 853fafc4 00000000 f2354b18 nt!DbgBreakPoint (FPO: [0,0,0])
f2354a3c 80abbf80 80a4f40e 80a4f3ee 0000092a nt!RtlAssert2+0x104 (FPO:
[Non-Fpo])
f2354a58 80a4ff3f 80a4f40e 80a4f3ee 0000092a nt!RtlAssert+0x18 (FPO:
[Non-Fpo])
f2354a90 80b0dd38 >>853fafc4<< 85aaae68 855556d0 nt!MmUnlockPages+0x2b (FPO:
[Non-Fpo])
f2354aa4 80a18a68 85aaae68 853fafc4 f2354ad0 nt!CcMdlReadComplete2+0x16
(FPO: [Non-Fpo])
f2354ab4 80a1944a 85aaae68 853fafc4 855556d0 nt!FsRtlMdlReadCompleteDev+0x10
(FPO: [Non-Fpo])
f2354ad0 f53a0bbe 85aaae68 853fafc4 853fafc4 nt!FsRtlMdlReadComplete+0x5e
(FPO: [Non-Fpo])
f2354ae4 f53edb02 85aaae68 853fafc4 853faea8 afd!AfdMdlReadComplete+0x32
(FPO: [Non-Fpo])
853fafc4 00040020 00000000 853fa000 853fa000 afd!AfdCleanupPacketChain+0x14c
(FPO: [Non-Fpo])
WARNING: Frame IP not in any known module. Following frames may be wrong.

Has anyone experienced something like this? Any clues on where I should
look to try and get more info about what is going on? Thanks.

=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]

Are you unlocking the partial MDL? You should not.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Roger Tawa”
To: “Windows File Systems Devs Interest List”
Sent: Monday, July 31, 2006 6:57 AM
Subject: [ntfsd] MDL_PAGES_LOCKED assert

> Hi all,
>
> I am getting the following assert:
>
> Assertion failed: (MemoryDescriptorList->MdlFlags & MDL_PAGES_LOCKED) !=
> 0
>
Source File: d:\xpsprtm\base\ntos\mm\iosup.c, line 2346
>
> when I start up an Apache web server, and configures it to expose my file
> system as a WebDAV folder. The machine running Apache is running a checked
> version of xp sp2. The assert occurs when a remote client tries to read
> from a file. The remote client is using the xp built-in WebDAV
> mini-redirector.
>
> The last IRP that goes through my FSD before the assert is an
> IRP_MJ_READ/IRP_MN_MDL. I call CcMdlRead(), specifying the IRP’s MdlAddress
> field as the 4th argument. I then complete the IRP. (I basically copied
> the code from FASTFAT.) However, I’m not sure how the MDL causing the
> assert and the MDL returned by my FSD are connected, since they do not
> appear to be same.
>
> I believe they are not the same because, while processing the
> IRP_MJ_READ/IRP_MN_MDL, I see this (this is the state of the READ IRP
> after I call CcMdlRead()):
>
> kd> !irp poi(pirp) 2
> Irp is active with 2 stacks 2 is current (= 0x86954fdc)
> Mdl = 857f93c8 Thread 850323c8: Irp stack trace.
> Flags = 40000004
> UserBuffer = 00000000
> …
> cmd flg cl Device File Completion-Context
> [0, 0] 0 0 00000000 00000000 00000000-00000000
>
> Args: 00000000 00000000 00000000 00000000
> >[3, 2] 0 e0 855556d0 85aaae68 f53ee8ce-865fcf00 Success Error Cancel
> \FileSystem\Pifsk afd!AfdRestartTPacketsMdlRead
> Args: 00000ea0 00000000 00000bd7 00000000
>
> kd> dt 857f93c8 MDL
> +0x000 Next : (null)
> +0x004 Size : 36
> +0x006 MdlFlags : 10 <– is: MDL_PARTIAL
> +0x008 Process : (null)
> +0x00c MappedSystemVa : 0x855f9b68
> +0x010 StartVa : 0xdae00000
> +0x014 ByteCount : 0xea0
> +0x018 ByteOffset : 0xbd7
>
> However, when I get the assert, the call stack is this, and the MDL being
> unlocked (853fafc4, between the >> and << below in the stack) is not the one
> I returned from my FSD:
>
> f235474c 80abbf3e 853fafc4 00000000 f2354b18 nt!DbgBreakPoint (FPO: [0,0,0])
> f2354a3c 80abbf80 80a4f40e 80a4f3ee 0000092a nt!RtlAssert2+0x104 (FPO:
> [Non-Fpo])
> f2354a58 80a4ff3f 80a4f40e 80a4f3ee 0000092a nt!RtlAssert+0x18 (FPO:
> [Non-Fpo])
> f2354a90 80b0dd38 >>853fafc4<< 85aaae68 855556d0 nt!MmUnlockPages+0x2b (FPO:
> [Non-Fpo])
> f2354aa4 80a18a68 85aaae68 853fafc4 f2354ad0 nt!CcMdlReadComplete2+0x16
> (FPO: [Non-Fpo])
> f2354ab4 80a1944a 85aaae68 853fafc4 855556d0 nt!FsRtlMdlReadCompleteDev+0x10
> (FPO: [Non-Fpo])
> f2354ad0 f53a0bbe 85aaae68 853fafc4 853fafc4 nt!FsRtlMdlReadComplete+0x5e
> (FPO: [Non-Fpo])
> f2354ae4 f53edb02 85aaae68 853fafc4 853faea8 afd!AfdMdlReadComplete+0x32
> (FPO: [Non-Fpo])
> 853fafc4 00040020 00000000 853fa000 853fa000 afd!AfdCleanupPacketChain+0x14c
> (FPO: [Non-Fpo])
> WARNING: Frame IP not in any known module. Following frames may be wrong.
> …
>
> Has anyone experienced something like this? Any clues on where I should
> look to try and get more info about what is going on? Thanks.
>
> =================================================
> Roger Tawa
> http://tawacentral.net/
> [One thing about paradigms: shift happens.]
> [When you stop, you’re done.]
>
>
>
>
> —
> Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks for your response Maxim.

I am not unlocking the MDL, but I can see why you ask because one
thing I said below is incorrect. The value of 10 shown for MdlFlags
is a decimal value, not a hex valued as I thought. So the flags of
the MDL is not MDL_PARTIAL, its
MDL_ALLOCATED_FIXED_SIZE|MDL_PAGES_LOCKED.

What I do is very similar to what FASTFAT does. After calling
CcMdlRead(), and assigning the returned MDL to pirp->MdlAddress, I set
the CurrentByteOffset field of the FO as needed, set the
FO_FILE_FAST_IO_READ flag in the FO, unlock my FCB, and complete the
IRP. I then call IoSetTopLevelIrp(0) and FsRtlExitFileSystem().

BTW, I used to complete the IRP after calling IoSetTopLevelIrp(0) and
FsRtlExitFileSystem(). When I noticed that FASTFAT completes it
before these two calls, I changed my code to do the same, but I still
get the assert. Is there a best practice wrt to completing IRPs and
calling FsRtlExitFileSystem()?

=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]