Short MDL in Storport miniport driver

In a virtual Stor miniport, in Windows 2008 RTM, we’re occasionally getting an MDL for Write operation that describes a buffer shorter than Srb->DataTransferLength. For example, MmGetMdlByteCount will return 0xECE0, but DataTransferLength is 0xEE00, which is MDL length rounded up to whole sector.

This can happen during installation. I suspect it’s caused by WriteFile with FILE_FLAG_WRITE_THROUGH, when a request gets written to the disk immediately, but the lengths is not necessarily multiple of sectors.

Is it calid case which the miniport should handle? I don’t see anything in the WDK docs. Should I just zero-pad the transfer up to DataTransferLength?

Why are you looking at the byte count in the MDL? That’s not the correct
place to check for the length of the transfer, you should only be concerned
with the transfer length specified in the SRB (and of course the lengths of
the scatter gather elements).

As for WHY you’re seeing this, I’m not sure. Clearly somebody is rounding up
for some reason or another and I’d hope that they’d ensure enough space in
the buffer to accommodate it (though I have seen bad cases where people just
assume the space is available). If you honor the transfer length it
shouldn’t matter, but if you’re curious I’d track down the original I/O
request and check out the parameters.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
> In a virtual Stor miniport, in Windows 2008 RTM, we’re occasionally
> getting an MDL for Write operation that describes a buffer shorter than
> Srb->DataTransferLength. For example, MmGetMdlByteCount will return
> 0xECE0, but DataTransferLength is 0xEE00, which is MDL length rounded up
> to whole sector.
>
> This can happen during installation. I suspect it’s caused by WriteFile
> with FILE_FLAG_WRITE_THROUGH, when a request gets written to the disk
> immediately, but the lengths is not necessarily multiple of sectors.
>
> Is it calid case which the miniport should handle? I don’t see anything in
> the WDK docs. Should I just zero-pad the transfer up to
> DataTransferLength?
>
>

To continue where SNoone (who is entirely correct, of course) left off:

Where’s the data buffer? I bet its in pool (not in the user application).

Peter
OSR

[ScottN]

Why are you looking at the byte count in the MDL? That’s not the correct
place to check for the length of the transfer, you should only be concerned
with the transfer length specified in the SRB (and of course the lengths of
the scatter gather elements).

To get data froom the buffer, we need to build SGL. If we request to build SGL longer than the MDL describes, what will happen?

[PeterV]

Where’s the data buffer? I bet its in pool (not in the user application).

The request comes from the modified page writer. Since it’s not a multiple of pages, I suspect it’s file cache commit, rather than pageout.

Related question: If I pass Length greater than the MDL describes, to StorPortBuildScatterGatherList, is it allowed?

> To get data froom the buffer, we need to build SGL. If we request to build

SGL longer than the MDL describes, what will >happen?

You pass the SRB to StorPorGetScatterGatherList, not the MDL. Thus, it’s
StorPort’s problem (if it’s even a problem at all). It’s still not clear why
you’re even messing with the MDL. Did this come from StorPortGetOriginalMdl
(Vista and later) or did you poof up your own mechanism?

While I’m admittedly not the biggest fan of the port driver architectures,
I’d say that in this particular case you might be poking under the covers
too much. There’s not much you can do if the wrapper is screwing things this
badly. If you’re finding corruptions, failures, or other issues and you’re
thinking that this is the cause, I’d again recommend that you isolate the
original I/O request and find out where the rounding up is occurring. But,
my guess is that you’re missing part of the puzzle and this is a red
herring.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
> [ScottN]
>>Why are you looking at the byte count in the MDL? That’s not the correct
>>place to check for the length of the transfer, you should only be
>>concerned
>>with the transfer length specified in the SRB (and of course the lengths
>>of
>>the scatter gather elements).
>
> To get data froom the buffer, we need to build SGL. If we request to build
> SGL longer than the MDL describes, what will happen?
>
> [PeterV]
>>Where’s the data buffer? I bet its in pool (not in the user application).
>
> The request comes from the modified page writer. Since it’s not a multiple
> of pages, I suspect it’s file cache commit, rather than pageout.
>
> Related question: If I pass Length greater than the MDL describes, to
> StorPortBuildScatterGatherList, is it allowed?
>
>

[ScottN]

You pass the SRB to StorPorGetScatterGatherList, not the MDL. Thus, it’s
StorPort’s problem (if it’s even a problem at all). It’s still not clear why
you’re even messing with the MDL. Did this come from >StorPortGetOriginalMdl
(Vista and later) or did you poof up your own mechanism?

This is virtual miniport. For such, storport doesn’t build SGL just in case, and StorPorGetScatterGatherList returns NULL. Thus, we need to call StorPortBuildSGL.

Ahh, OK, that makes sense.

This has to be a thin wrapper around the underlying DMA APIs and, having
been through this before long ago for reasons long forgotten, I do know that
they handle this case for some reason or another.

There’s definitely code in the FSDs to round up I/Os to sector boundaris
(non-cached I/O comes to mind) and that might cause you to see something
like this.

But, again, this is all out of your control and is likely to be normal. You
didn’t initiate the transfer, you didn’t build the MDL, you’re just a lowly
block device at the mercy of the wrapper. Unless these MDLs are causing the
DMA APIs to fail or corruptions to occur it’s probably worth spending your
time elsewhere.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
> [ScottN]
>>You pass the SRB to StorPorGetScatterGatherList, not the MDL. Thus, it’s
>>StorPort’s problem (if it’s even a problem at all). It’s still not clear
>>why
>>you’re even messing with the MDL. Did this come from
>> >StorPortGetOriginalMdl
>>(Vista and later) or did you poof up your own mechanism?
>
> This is virtual miniport. For such, storport doesn’t build SGL just in
> case, and StorPorGetScatterGatherList returns NULL. Thus, we need to call
> StorPortBuildSGL.
>
>
>

Following up on this:

The “short MDL” condition happens in FlushViewOfFile path, if the file contents is not in the file cache (which means it was never touched by ReadFile/WriteFile), and the file length is not exact multiple of sectors.

If I feed Srb->DataTransferLength to StorPortBuildScatterGatherList, it will simply extend the last item, regardless that MDL length doesn’t cover it. It’s benign, but I wonder if that’s the right thing to do. I suspect this is what non-virtual storport path does.

Block devices can’t (obviously) have less than a blocks worth of data. Just
write away and don’t worry about it. If there isn’t an actual physical
memory location for the extra bytes, somebody above you screwed up.

On Fri, Apr 18, 2008 at 4:24 PM, wrote:

> Following up on this:
>
> The “short MDL” condition happens in FlushViewOfFile path, if the file
> contents is not in the file cache (which means it was never touched by
> ReadFile/WriteFile), and the file length is not exact multiple of sectors.
>
> If I feed Srb->DataTransferLength to StorPortBuildScatterGatherList, it
> will simply extend the last item, regardless that MDL length doesn’t cover
> it. It’s benign, but I wonder if that’s the right thing to do. I suspect
> this is what non-virtual storport path does.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy