Dealing with MmProbeAndLockPages failures

I’ve got a user of my file system driver who gets a return status of STATUS_INVALID_USER_BUFFER on some I/O requests. I return this status if MmProbeAndLockPages() fails, following the example of the FASTFAT driver.
I haven’t gotten to the bottom of the failure yet, but it raised a question in my mind. How can a top-level FS driver split up a user’s request into smaller chunks? The only examples I’ve seen use IoCreatePartialMdl() to split up requests for lower-level drivers, but that only works if you’ve already locked the top-level buffer in a big MDL.
If MmProbeAndLockPages() is failing because there’s not enough physical memory or kernel address space, it seems worthwhile to break up the request. Does it make sense for me to stand on my head to get back into original process context to continue processing pieces of the original buffer if I need to break it up and do a piece at a time?

Carl

One thing you might consider doing if you’re going to slice and dice the user buffer is to do it synchronously. As an FSD that is your right. In that case you just loop through the user’s buffer, break it into chunks, probe and lock each one, and then perform the processing of it. You could pick some modest number, like 16MB (I think we used that at one point because it was the maximum memory that could be described by an MDL at one point, though that limit has been lifted.) Or figure out what works dynamically and then use that value.

I suppose you could build up sufficient context so that any IRP you send onwards for that piece of the user buffer can be used to continue on processing the buffer (e.g., process context so you can KeStackAttachProcess). FAT doesn’t do anything that fancy, but that’s not likely to be a major concern for FAT, either. But there’s nothing that says you can’t slice and dice the buffer. How fancy you make it is pretty much up to your imagination.

Tony
OSR

Good suggestions, Tony. Thanks.

Carl