Warnings in MSDN about FltFreeDeferredIoWorkItem

Hello,

I have a question about some warnings in MSDN.

In my minifilter, I subscribe to IRP_MJ_READ, and I need to access the buffers in the Post callback. After I perform computations on the buffers, I would like to send a message (FltSendMessage) to communicate to my other components.
I am aware that this is not allowed at DPC, and that PostRead will sometimes happen at DPC. I was therefore planning to use FltQueueDeferredIoWorkItem, or FltDoCompletionProcessingWhenSafe.

There is, however, the following warning in MSDN for both functions:
"
Caution
To avoid deadlocks, a minifilter must not post an I/O operation to a system work queue in the post-operation callback for any I/O operations that a driver can complete directly in the storage stack, such as the following:
IRP_MJ_READ
IRP_MJ_WRITE
IRP_MJ_FLUSH_BUFFERS
"

But I note that in the swap buffers minifilter example, there is a call to FltDoCompletionProcessingWhenSafe, which contradicts the MSDN warning…

What is the correct way of handling calls that are forbidden at DPC in PostRead?
Is it okay to ignore the warning, as the sample seems to do?
Or rather, under which conditions can we ignore the warning?

If this question has already been answered, please send me a link…
Thanks,
Max

These comments in the docs are confusing. And they’ve confused many people
before you, they really need changed.

There are two problems that you need to be aware of:

  1. You can’t post a PostOperation callback to a worker thread if the
    operation was completed synchronously. This is due to the fact that the I/O
    Manager will believe that the request was completed synchronously, but your
    driver would force the operation to be asynchronous.

  2. You can’t to submit I/O from your PostOp callback back down into the file
    system (i.e. send a write down the file in response to a read).

Discussed a bit before:

http://www.osronline.com/showThread.CFM?link=286533

Bottom line is that if you’re just looking at the data buffer of a read
operation you’re safe using FltDoCompletionProcessingWhenSafe (as in the
sample).

-scott
OSR
@OSRDrivers

Hello Scott,

Many thanks for the clarifications.

I have a couple of follow-ups given your answer:
1- if the operation is completed synchronously, is it safe to assume that the PostOp callback cannot take place at DPC? I seem to recall that returning “synchronize” from the PreOp guarantees that the PostOp is <= APC. Is there a way for me to tell that the operation was completed synchronously?

2- All I am doing is sending a message to my user mode app using FltSendMessage. I would however like to wait for the reply.
If at DPC, my strategy has been to just return “post_op_complete”, and call the FltSendMessage on a system thread (i.e. simply not wait for the reply), but I would like to know if I can do better.
From your answer, it sounds like calling “FltDoCompletionWhenSafe” to do this is acceptable, but I’d like to confirm. The user mode app keeps the information that it receives in a map in memory, so I expect it could only trigger paging I/O…

Thanks,
Max

Yes.

The definitive answer is in the IRP, but the FltMgr abstraction hides this
from you. If you really cared you could compare the originating thread with
the current thread.

Yes, that should work. You just need to be careful that YOU don’t create any
deadlocks due to the wait (e.g. your user app might need to page in a DLL
while handling your synchronous message, which will call back into your
filter’s PreRead/PostRead callbacks). You also need to make sure that you
don’t try to do this with paging *file* I/O as that path is not allowed to
page fault.

-scott
OSR
@OSRDrivers