FLT_PREOP_PENDING/FltCompletePendedPostOperation race?

Consider this situation (it’s from my real work):

PreCleanupCallback(?)
{

?. queue this operation ?.

return FLT_PREOP_PENDING;

}

queued_procedure()
{
FltCompletePendedPostOperation()
}

There is no guarantee that return FLT_PREOP_PENDING will happen before FltCompletePendedPostOperation() is called! It happens in reality? How to synchronize it? What I did is saving current time for the queued operation and call KeDelayExecutionThread with time+5msec before calling FltCompletePendedPostOperation, but it is not elegant :frowning:

Is there a better solution?

Why don’t you just call FltQueueDeferredIoWorkItem function before “return
FLT_PREOP_PENDING” line? If you can’t, from any reason, you should move code
between FltQueue- and return line to your queued_procedure, or use a mutex
to suspend queued_procedure.

Sorry for the ? marks they were added unitentionally- I’m calling:

FltQueueGenericWorkItem( queued_procedure )

before

return FLT_PREOP_PENDING

The problem is that “queued_procedure” sometimes gets called before “return FLT_PREOP_PENDING” is executed, i.e. thread switches to queued work item and returns (to return FLT_PREOP_PENDING) after FltCompletePendedPostOperation is called- so the FilterMngr doesn’t know that this operation was pended when FltCompletePendedPostOperation is called…

Doesn?t matter, the system supports this scenario. I.e. it?s valid to have an IRP complete on a different thread before your IoCallDriver returns STATUS_PENDING (but the IRP must be marked as pending). So you don?t need to worry about this scenario.

However, you might want to worry about the fact that IRP_MJ_CLEANUP must be called in the context of the process that close that last handle so you must queue in such a way that the thread that dequeues it either completes the request or, if it sends it down, it must do so in the same process context.

Thanks,
Alex.
On Jan 8, 2014, at 1:48 PM, xxxxx@arcabit.com wrote:

Sorry for the ? marks they were added unitentionally- I’m calling:

FltQueueGenericWorkItem( queued_procedure )

before

return FLT_PREOP_PENDING

The problem is that “queued_procedure” sometimes gets called before “return FLT_PREOP_PENDING” is executed, i.e. thread switches to queued work item and returns (to return FLT_PREOP_PENDING) after FltCompletePendedPostOperation is called- so the FilterMngr doesn’t know that this operation was pended when FltCompletePendedPostOperation is called…


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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

Alex- it is not a driver routine (for IRP_MJ_CLEANUP), it’s a File System Minifilter Driver- where you don’t return STATUS_PENDING (I know there is IoMarkIrpPending), but it is not the case? You return FLT_PREOP_PENDING, FLT_PREOP_COMPLETE, etc…

Yeah, I realized that we?re talking about a minifilter. However the PreCleanup callback is called in response to the IRP_MJ_CLEANUP request and the rules around IRP_MJ_CLEANUP still apply.

I?m sorry, I tend to refer to the statuses and requests by the their actual name instead of the FltMgr specific name :slight_smile: .

So basically, what I was trying to say before was that you don?t need to worry about it, it?s perfectly fine to complete the request in a different thread before you?ve returned FLT_PREOP_PENDING in the original thread, FltMgr does most of the hard work for you. However, you need to be careful about the specifics of each operation, some of them have certain requirements around pending (like IRP_MJ_CLEANUP and the process context).

Does this make sense ?

Thanks,
Alex.

On Jan 8, 2014, at 1:59 PM, xxxxx@arcabit.com wrote:

Alex- it is not a driver routine (for IRP_MJ_CLEANUP), it’s a File System Minifilter Driver- where you don’t return STATUS_PENDING (I know there is IoMarkIrpPending), but it is not the case? You return FLT_PREOP_PENDING, FLT_PREOP_COMPLETE, etc…


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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

Yes I also think FltMngr handles it, otherwise there is bo way to guarantee for 100% synchronization.

Regarding CLEANUP handling- I think that the proper process contexts are also handled by FltMngr, similar as with pending

Thanks!

FltMgr doesn?t need to guarantee 100% synchronization between pending a request and completing it, the IO manager is the system component that actually does that. FltMgr just uses the interface provided by the IO manager.

Process contexts aren?t handled by FltMgr in the way you seem to expect here. Deferred and generic work items are executed in system context, not in any specific user context.

Thanks,
Alex.

> Process contexts aren?t handled by FltMgr in the way you seem to expect here.

Are you sure, where is this documented? The doc says that we can return FILT_PREOP_PENDING and complete operation later in an arbitrary thread context? If synchronization would be required- it may be simply implemented by FiltMngr as synchronous user-mode request are handled: when receiving FILT_PREOP_PENDING, FiltMngr would block that tread waiting for completion by minifilter driver, and when this occurs- unblock that hread and call MJ_CLEANUP in it’s context. Minifilter drivers don’t call MJ_CLEANUP directly, this is always done by FiltMngr so it can handle proper contexts itself?

FS Minifilter dirvers doc doesn’t say about any required thread context when completing (strictly: asking FltMngr for completion) ANY pended operation…

I?m quite sure. As far as I know the documentation doesn?t clearly discuss the implementation on pending operations, but the approach you suggested (to wait for the minifilter to complete the operation on a different thread and then send it down (or complete it) on the original thread) has the disadvantage that it would prevent a filter from ever passing an operation down in a different context (the filter would be forced to allocate a new CallbackData in the new context, send that down, and on its completion it would have to complete back the original context). This is definitely more complicated than the current implementation, where the filter would just pend and then ?continue? the operation in the new context.

Also, from a design perspective, this would be a departure from the asynchronous model of NT.

FS Minifilter documentation should be read as complementary to the legacy file system filter documentation, and not as a replacement. It mostly tries to describe the FltMgr specific bits, so if it doesn?t mention anything specific to contexts for IRP_MJ_CLEANUP, I don?t think you should take that to mean that there are no other requirements, but instead I would read it to mean that there are no FltMgr specific constraints.

Thanks,
Alex.

On Jan 10, 2014, at 1:04 PM, xxxxx@arcabit.com wrote:

> Process contexts aren?t handled by FltMgr in the way you seem to expect here.

Are you sure, where is this documented? The doc says that we can return FILT_PREOP_PENDING and complete operation later in an arbitrary thread context? If synchronization would be required- it may be simply implemented by FiltMngr as synchronous user-mode request are handled: when receiving FILT_PREOP_PENDING, FiltMngr would block that tread waiting for completion by minifilter driver, and when this occurs- unblock that hread and call MJ_CLEANUP in it’s context. Minifilter drivers don’t call MJ_CLEANUP directly, this is always done by FiltMngr so it can handle proper contexts itself?

FS Minifilter dirvers doc doesn’t say about any required thread context when completing (strictly: asking FltMngr for completion) ANY pended operation…


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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

>doesn?t mention anything specific to contexts for IRP_MJ_CLEANUP

Am I wrong that MJ_CLEANUP is inherently synchronous?


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

I?m not sure what you mean by that. That the IO manager treats it as a synchronous operation and waits for the IRP to complete even if it gets pended somewhere ? Or that FltMgr calls the postCleanup in the same context as the preCleanup (as if the filter had returned FLT_PREOP_SYNCHRONIZE) ?

Thanks,
Alex.
On Jan 12, 2014, at 10:04 AM, Maxim S. Shatskih wrote:

>> doesn?t mention anything specific to contexts for IRP_MJ_CLEANUP
>
> Am I wrong that MJ_CLEANUP is inherently synchronous?
>
> –
> Maxim S. Shatskih
> Microsoft MVP on File System And Storage
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system 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

>I?m not sure what you mean by that. That the IO manager treats it as a synchronous operation and

waits for the IRP to complete even if it gets pended somewhere ?

Yes


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

The I/O Manager does indeed force NtClose to be a synchronous operation, no
one expects to have to deal with getting STATUS_PENDING back from that :slight_smile:

-scott
OSR

“Maxim S. Shatskih” wrote in message news:xxxxx@ntfsd…

I’m not sure what you mean by that. That the IO manager treats it as a
synchronous operation and
waits for the IRP to complete even if it gets pended somewhere ?

Yes


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

However, this doesn?t mean that a filter can?t change the context of the operation. I just want to clarify that this is orthogonal to OP?s question.

Thanks,
Alex.
On Jan 14, 2014, at 10:45 AM, Scott Noone wrote:

> The I/O Manager does indeed force NtClose to be a synchronous operation, no one expects to have to deal with getting STATUS_PENDING back from that :slight_smile:
>
> -scott
> OSR
>
> “Maxim S. Shatskih” wrote in message news:xxxxx@ntfsd…
>
>> I?m not sure what you mean by that. That the IO manager treats it as a synchronous operation and
>> waits for the IRP to complete even if it gets pended somewhere ?
>
> Yes
>
> –
> Maxim S. Shatskih
> Microsoft MVP on File System And Storage
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system 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