Is there a recommended mechanism to determine if a given create callback is occurring within the context of a instance setup callback from some other filter? I’m trying to avoid the various fltmgr dead-locks that occur if volume information is queried during an instance setup callback.
Thanks,
t.
Well, drivers usually call FltGetVolumeGuidName/IoVolumeDeviceToDosName from
instance setup callback. I don’t recommend to call these functions from this
callback, because sometimes it leads to a deadlock with MountMgr (it’s
better to move this code to a workitem with a referenced PDO and
FLT_VOLUME). I think these functions invoke some create requests from
MountMgr, is that correct? Maybe you can see if the volume is already
mounted (VPB_MOUNTED flag? or
IOCTL_VOLUME_ONLINE/IOCTL_VOLUME_SUPPORTS_ONLINE_OFFLINE?).
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@openmars.com
Sent: Wednesday, August 05, 2015 10:40 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] fltmgr instance setup deadlock avoidance
Is there a recommended mechanism to determine if a given create callback is
occurring within the context of a instance setup callback from some other
filter? I’m trying to avoid the various fltmgr dead-locks that occur if
volume information is queried during an instance setup callback.
Thanks,
t.
I already defer all i/o from the instance setup callback (though supposedly the mountmgr deadlocks are resolved in vista+). I’m more concerned about the scenario where a filter above me in the stack is instance setup callback, has issued i/o (which is apparently never safe to do in the fltmgr design if there are two filters running at the same time) and now my filter is getting a create-pre callout. Depending on what i/o I do in create-pre fltmgr can end up stacking up against its internal instance setup resource.
Something like this (edited to protect the innocent and to fit your screen). FilterA is doing stuff in instance setup, FilterB wants to normalize the file name and creates a worker thread to avoid stack-overflow, the worker thread never finishes because it stacks up against the instance setup notify resource.
nt!KiCommitThreadWait+0x1d2
nt!KeWaitForSingleObject+0x19f
FilterB!DeferredWorkItem+0c45
FilterB!FilterCommonIoPreOp+0x815
fltmgr!FltpPerformPreCallbacks+0x2f7
fltmgr!FltpPassThroughFastIo+0x4d
fltmgr!FltWriteFile+0x260
FilterA+0xbd5a
FilterA+0x15f8
fltmgr!FltpDoInstanceSetupNotification+0x86
fltmgr!FltpInitInstance+0x27b
fltmgr!FltpCreateInstanceFromName+0x1d1
fltmgr!FltpEnumerateRegistryInstances+0x15b
fltmgr!FltpDoFilterNotificationForNewVolume+0xec
fltmgr!FltpCreate+0x3e0
nt!IopParseDevice+0x14d3
nt!ObpLookupObjectName+0x588
nt!ObOpenObjectByName+0x306
nt!IopCreateFile+0x2bc
nt!NtOpenFile+0x58
nt!KiSystemServiceCopyEnd+0x13
And this is the worker thread:
4.000048 fffffa8012ddc040 fffffcad Blocked nt!KiSwapContext+0x7a
nt!KiCommitThreadWait+0x1d2
nt!KeWaitForSingleObject+0x19f
nt!ExpWaitForResource+0xae
nt!ExAcquireResourceExclusiveLite+0x14f
fltmgr!FltpDoFilterNotificationForNewVolume+0x4a
fltmgr!FltpCreate+0x3e0
nt!IopParseDevice+0x14d3
nt!ObpLookupObjectName+0x588
nt!ObOpenObjectByName+0x306
nt!IopCreateFile+0x2bc
nt!IoCreateFileEx+0xfb
fltmgr!FltpNormalizeNameFromCache+0x190
fltmgr!FltpExpandShortNames+0x239
fltmgr!FltpGetNormalizedFileNameWorker+0xc1
fltmgr!FltpCreateFileNameInformation+0xee
fltmgr!FltpGetFileNameInformation+0x26b
fltmgr!FltGetFileNameInformation+0x184
FilterB!Normalize+0x2b
nt!IopProcessWorkItem+0x23
nt!ExpWorkerThread+0x111
nt!PspSystemThreadStartup+0x5a
nt!KxStartSystemThread+0x16
The present solution involves looking at internal fltmgr FLT_VOLUME flags to determine if the volume has completed instance setup yet or not. I’m trying to clear such reach-in knowledge from the code. I think at this point the VPB flags would indicate that the volume is mounted.
- It think it is ok for minifilters to do I/O from instancesetup callback
as long as they don’t violate layering. I didn’t find anything like this
documented. It would be glad if you can refer me to any such doc.
- Two filters running at the same time is almost always.
- As long as the I/O goes only below the filters below you in
instancesetup there is not a problem as there instancesetup would have been
complete. The problem is that FltGetFileNameInformation issues I/O to the
top of the stack thus violating layering.
W
On Thu, Aug 6, 2015 at 10:46 PM, wrote:
> I already defer all i/o from the instance setup callback (though
> supposedly the mountmgr deadlocks are resolved in vista+). I’m more
> concerned about the scenario where a filter above me in the stack is
> instance setup callback, has issued i/o (which is apparently never safe to
> do in the fltmgr design if there are two filters running at the same time)
> and now my filter is getting a create-pre callout. Depending on what i/o I
> do in create-pre fltmgr can end up stacking up against its internal
> instance setup resource.
>
> Something like this (edited to protect the innocent and to fit your
> screen). FilterA is doing stuff in instance setup, FilterB wants to
> normalize the file name and creates a worker thread to avoid
> stack-overflow, the worker thread never finishes because it stacks up
> against the instance setup notify resource.
>
> nt!KiCommitThreadWait+0x1d2
> nt!KeWaitForSingleObject+0x19f
> FilterB!DeferredWorkItem+0c45
> FilterB!FilterCommonIoPreOp+0x815
>
> fltmgr!FltpPerformPreCallbacks+0x2f7
> fltmgr!FltpPassThroughFastIo+0x4d
> fltmgr!FltWriteFile+0x260
> FilterA+0xbd5a
> FilterA+0x15f8
>
> fltmgr!FltpDoInstanceSetupNotification+0x86
> fltmgr!FltpInitInstance+0x27b
>
> fltmgr!FltpCreateInstanceFromName+0x1d1
>
> fltmgr!FltpEnumerateRegistryInstances+0x15b
>
> fltmgr!FltpDoFilterNotificationForNewVolume+0xec
> fltmgr!FltpCreate+0x3e0
> nt!IopParseDevice+0x14d3
> nt!ObpLookupObjectName+0x588
> nt!ObOpenObjectByName+0x306
> nt!IopCreateFile+0x2bc
> nt!NtOpenFile+0x58
> nt!KiSystemServiceCopyEnd+0x13
>
> And this is the worker thread:
>
> 4.000048 fffffa8012ddc040 fffffcad Blocked nt!KiSwapContext+0x7a
> nt!KiCommitThreadWait+0x1d2
> nt!KeWaitForSingleObject+0x19f
> nt!ExpWaitForResource+0xae
>
> nt!ExAcquireResourceExclusiveLite+0x14f
>
> fltmgr!FltpDoFilterNotificationForNewVolume+0x4a
> fltmgr!FltpCreate+0x3e0
> nt!IopParseDevice+0x14d3
> nt!ObpLookupObjectName+0x588
> nt!ObOpenObjectByName+0x306
> nt!IopCreateFile+0x2bc
> nt!IoCreateFileEx+0xfb
>
> fltmgr!FltpNormalizeNameFromCache+0x190
> fltmgr!FltpExpandShortNames+0x239
>
> fltmgr!FltpGetNormalizedFileNameWorker+0xc1
>
> fltmgr!FltpCreateFileNameInformation+0xee
>
> fltmgr!FltpGetFileNameInformation+0x26b
>
> fltmgr!FltGetFileNameInformation+0x184
> FilterB!Normalize+0x2b
> nt!IopProcessWorkItem+0x23
> nt!ExpWorkerThread+0x111
> nt!PspSystemThreadStartup+0x5a
> nt!KxStartSystemThread+0x16
>
> The present solution involves looking at internal fltmgr FLT_VOLUME flags
> to determine if the volume has completed instance setup yet or not. I’m
> trying to clear such reach-in knowledge from the code. I think at this
> point the VPB flags would indicate that the volume is mounted.
>
> —
> 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
>