Thread holds Fcb->PagionIoResource, IoGetTopLevelIrp() returns null

Gentlefolk

The IFS documentation for IoGetTopLevelIrp() says “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns NULL.”. I
have always taken this to mean that the thread does not hold either of the
Fcb main resource or paging io resource of the Fcb relevant to the i/o
request in progress; for example the file being written in the case of an
IRP_MJ_WRITE. Is this a correct interpretation?

I ask because I have just seen an interesting deadlock for the first time on
W2K3 SP1. In this deadlock a first thread has sent IRP_MJ_FLUSH_BUFFERS for
the volume which contains AppEvent.evt the windows application event log.
This first thread holds the shared vcb resource and is waiting to acquire
the paging io resource for the Fcb for this file. In this state a second
thread has called IoSynchronousPageWrite and a filter driver in its dispatch
handler in that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
filename a la filespy) for the file object which happens to refer to the
same Fcb. There is a deadlock of course because the second thread holds the
paging io resource and waits for the shared vcb resource. The filter driver
in the second thread will not send IRP_MJ_QUERY_INFORMATION unless
IoGetTopLevelIrp() returns NULL; on this occasion IoGetTopLevelIrp() has
indeed returned NULL.

Thanks in advance
Lyndon

I doesn’t sound right. If the thread is executing IoSynchronousPageWrite I
would not expect Top level Irp to be NULL; it should be one of predefined
constants like FSRTL_MOD_WRITE_TOP_LEVEL_IRP if there is no recursion or
actual Top level IRP if there is recursion.
Are you sure that top level IRP was not reset to NULL by some other filter
above your filter?

Alexei.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 9:55 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] Thread holds Fcb->PagionIoResource, IoGetTopLevelIrp()
returns null

Gentlefolk

The IFS documentation for IoGetTopLevelIrp() says “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns NULL.”. I
have always taken this to mean that the thread does not hold either of the
Fcb main resource or paging io resource of the Fcb relevant to the i/o
request in progress; for example the file being written in the case of an
IRP_MJ_WRITE. Is this a correct interpretation?

I ask because I have just seen an interesting deadlock for the first time on
W2K3 SP1. In this deadlock a first thread has sent IRP_MJ_FLUSH_BUFFERS for
the volume which contains AppEvent.evt the windows application event log.
This first thread holds the shared vcb resource and is waiting to acquire
the paging io resource for the Fcb for this file. In this state a second
thread has called IoSynchronousPageWrite and a filter driver in its dispatch
handler in that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
filename a la filespy) for the file object which happens to refer to the
same Fcb. There is a deadlock of course because the second thread holds the
paging io resource and waits for the shared vcb resource. The filter driver
in the second thread will not send IRP_MJ_QUERY_INFORMATION unless
IoGetTopLevelIrp() returns NULL; on this occasion IoGetTopLevelIrp() has
indeed returned NULL.

Thanks in advance
Lyndon


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@vmware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi Alexei

Thanks for the response. I am sure some other filter above has not reset
toplevel irp to null; because my filter is at the top of the device stack.
If it helps, tomorrrow I can extract the relevant kv and !locks outputs.

Cheers
Lyndon

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current thread
> holds no resources above the file system, IoGetTopLevelIrp returns NULL.”.
> I have always taken this to mean that the thread does not hold either of
> the Fcb main resource or paging io resource of the Fcb relevant to the i/o
> request in progress; for example the file being written in the case of an
> IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first time
> on W2K3 SP1. In this deadlock a first thread has sent IRP_MJ_FLUSH_BUFFERS
> for the volume which contains AppEvent.evt the windows application event
> log. This first thread holds the shared vcb resource and is waiting to
> acquire the paging io resource for the Fcb for this file. In this state a
> second thread has called IoSynchronousPageWrite and a filter driver in its
> dispatch handler in that thread has sent an IRP_MJ_QUERY_INFORMATION (to
> retrieve the filename a la filespy) for the file object which happens to
> refer to the same Fcb. There is a deadlock of course because the second
> thread holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on this
> occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter != 0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0
Break instruction exception - code 80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000 RUNNING
on processor 0
Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e)
Stack Init f78ef000 Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0
Priority 13 BasePriority 12 PriorityDecrement 0
ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO: [0,0,0])
f78ee950 f60944e1 f78ee988 00000000 84fad4f8 MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:
[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348 nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234 (FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:
[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb (FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb (FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000 nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc)
Mdl = f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000
CancelRoutine = 00000000
UserBuffer = 00000000
&Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0
Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000
Tail.Overlay.ListEntry.Blink = 00000000
Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0
Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000

[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current thread
> holds no resources above the file system, IoGetTopLevelIrp returns NULL.”.
> I have always taken this to mean that the thread does not hold either of
> the Fcb main resource or paging io resource of the Fcb relevant to the i/o
> request in progress; for example the file being written in the case of an
> IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first time
> on W2K3 SP1. In this deadlock a first thread has sent IRP_MJ_FLUSH_BUFFERS
> for the volume which contains AppEvent.evt the windows application event
> log. This first thread holds the shared vcb resource and is waiting to
> acquire the paging io resource for the Fcb for this file. In this state a
> second thread has called IoSynchronousPageWrite and a filter driver in its
> dispatch handler in that thread has sent an IRP_MJ_QUERY_INFORMATION (to
> retrieve the filename a la filespy) for the file object which happens to
> refer to the same Fcb. There is a deadlock of course because the second
> thread holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on this
> occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>

This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000

[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Molly

Thanks for the response. This thread is from a different scenario in which
there is no deadlock. It does however exhibit the behaviour where as a
certain fact you can see from the windbag output the thread holds the
PagingIoResource but IoGetTopLevelIrp returns NULL.

So the question I have is what to be precise does “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns NULL.”
really mean?

It so happens I dont ever perform queries in the paging i/o paths anyhow. I
do however queue a worker thread to perform one or more queries in some
cases.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

>So the question I have is what to be precise does "If the current thread

holds no resources above the file system, IoGetTopLevelIrp returns NULL."
really mean?

Strictly speaking documentation doesn’t contradict to what you are seeing. It
doesn’t say that when IoGetTopLevelIrp return NULL no resources are held; it
is saying that if Top level Irp is not NULL, then somebody holds some file
system resource.

Alexei.

You a lawyer now Alexei? The documetnation says I quote “If the current
thread holds no resources above the file system, IoGetTopLevelIrp returns
NULL”. So okay, this sentence does also allow IoGetTopLevelIrp to return
NULL, if the thread holds one or more resources above the file system. This
is the same as saying “If IoGetTopLevelIrp returns NULL the thread holds
zero or more resources above the file system” which is, well, err, in the
land of ashtrays for motorbikes :slight_smile:

“Alexei Jelvis” wrote in message news:xxxxx@ntfsd…

>So the question I have is what to be precise does “If the current thread
>holds no resources above the file system, IoGetTopLevelIrp returns NULL.”
>really mean?

Strictly speaking documentation doesn’t contradict to what you are seeing.
It
doesn’t say that when IoGetTopLevelIrp return NULL no resources are held; it
is saying that if Top level Irp is not NULL, then somebody holds some file
system resource.

Alexei.

Setting TopLevelIrp is not used in a completely consistent manner, so I
think, in an effort to not say the wrong information, the docs give you
no information with that statement :).

When a file system sets TopLevelIrp, it indicates that some file system
locks are already held for this operation and the file system uses this
information if a recursive IO happens in the context of processing the
original IO request.

The file systems do not set this 100% of the time when a resource is
held, therefore if it is not set, you are not guaranteed that no
resources are held.

Here’s a little table that may make this clearer:
IoGetTopLevelIrp != NULL ==> some file system resources are already
held by this thread
IoGetTopLevelIrp == NULL ==> probably no file system resources are held
by this thread, but this is not 100% true. Instead a filter must rely
on the operation context to determine whether it is safe to issue
queries to the file system.

I’ll talk to Diane about clarifying the documentation for
IoGetTopLevelIrp().

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 2:22 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks for the response. This thread is from a different scenario in
which there is no deadlock. It does however exhibit the behaviour where
as a certain fact you can see from the windbag output the thread holds
the PagingIoResource but IoGetTopLevelIrp returns NULL.

So the question I have is what to be precise does “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns
NULL.”
really mean?

It so happens I dont ever perform queries in the paging i/o paths
anyhow. I do however queue a worker thread to perform one or more
queries in some cases.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Molly

Thanks. So please can you explain in this case

IoGetTopLevelIrp == NULL ==> probably no file system resources are held
by this thread, but this is not 100% true. Instead a filter must rely
on the operation context to determine whether it is safe to issue
queries to the file system.

the actual rules for “rely on the context”. I trust you appreciate that
without those rules, what you have said is that IoGetTopLevelIrp is, to be
as kind as possible, just useless.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
Setting TopLevelIrp is not used in a completely consistent manner, so I
think, in an effort to not say the wrong information, the docs give you
no information with that statement :).

When a file system sets TopLevelIrp, it indicates that some file system
locks are already held for this operation and the file system uses this
information if a recursive IO happens in the context of processing the
original IO request.

The file systems do not set this 100% of the time when a resource is
held, therefore if it is not set, you are not guaranteed that no
resources are held.

Here’s a little table that may make this clearer:
IoGetTopLevelIrp != NULL ==> some file system resources are already
held by this thread
IoGetTopLevelIrp == NULL ==> probably no file system resources are held
by this thread, but this is not 100% true. Instead a filter must rely
on the operation context to determine whether it is safe to issue
queries to the file system.

I’ll talk to Diane about clarifying the documentation for
IoGetTopLevelIrp().

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 2:22 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks for the response. This thread is from a different scenario in
which there is no deadlock. It does however exhibit the behaviour where
as a certain fact you can see from the windbag output the thread holds
the PagingIoResource but IoGetTopLevelIrp returns NULL.

So the question I have is what to be precise does “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns
NULL.”
really mean?

It so happens I dont ever perform queries in the paging i/o paths
anyhow. I do however queue a worker thread to perform one or more
queries in some cases.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

IoGetTopLevelIrp isn’t completely useless, it is just not as useful as
many filter writers expect. If it is non NULL, it tells you that you
are within a recursive operation and file system locks are held - that’s
useful. If it is NULL, it doesn’t tell you anything.

When it is NULL, you need to rely on other pieces of information, like
what operation is this, is the paging IO flag set, etc. (that’s what I
meant by operation context), to know if it is safe to issue queries to
the file system.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 4:10 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks. So please can you explain in this case

IoGetTopLevelIrp == NULL ==> probably no file system resources are
held by this thread, but this is not 100% true. Instead a filter must

rely on the operation context to determine whether it is safe to issue

queries to the file system.

the actual rules for “rely on the context”. I trust you appreciate that
without those rules, what you have said is that IoGetTopLevelIrp is, to
be as kind as possible, just useless.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
Setting TopLevelIrp is not used in a completely consistent manner, so I
think, in an effort to not say the wrong information, the docs give you
no information with that statement :).

When a file system sets TopLevelIrp, it indicates that some file system
locks are already held for this operation and the file system uses this
information if a recursive IO happens in the context of processing the
original IO request.

The file systems do not set this 100% of the time when a resource is
held, therefore if it is not set, you are not guaranteed that no
resources are held.

Here’s a little table that may make this clearer:
IoGetTopLevelIrp != NULL ==> some file system resources are already
held by this thread IoGetTopLevelIrp == NULL ==> probably no file
system resources are held by this thread, but this is not 100% true.
Instead a filter must rely on the operation context to determine whether
it is safe to issue queries to the file system.

I’ll talk to Diane about clarifying the documentation for
IoGetTopLevelIrp().

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 2:22 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks for the response. This thread is from a different scenario in
which there is no deadlock. It does however exhibit the behaviour where
as a certain fact you can see from the windbag output the thread holds
the PagingIoResource but IoGetTopLevelIrp returns NULL.

So the question I have is what to be precise does “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns
NULL.”
really mean?

It so happens I dont ever perform queries in the paging i/o paths
anyhow. I do however queue a worker thread to perform one or more
queries in some cases.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> IoGetTopLevelIrp isn’t completely useless, it is just not as useful as

many filter writers expect.

Yet another “may/can/must-not” rule in the FS world …

L.

Youu are right, of course. Many thanks for your kind help once again.

Cheers
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
IoGetTopLevelIrp isn’t completely useless, it is just not as useful as
many filter writers expect. If it is non NULL, it tells you that you
are within a recursive operation and file system locks are held - that’s
useful. If it is NULL, it doesn’t tell you anything.

When it is NULL, you need to rely on other pieces of information, like
what operation is this, is the paging IO flag set, etc. (that’s what I
meant by operation context), to know if it is safe to issue queries to
the file system.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 4:10 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks. So please can you explain in this case

> IoGetTopLevelIrp == NULL ==> probably no file system resources are
> held by this thread, but this is not 100% true. Instead a filter must

> rely on the operation context to determine whether it is safe to issue

> queries to the file system.

the actual rules for “rely on the context”. I trust you appreciate that
without those rules, what you have said is that IoGetTopLevelIrp is, to
be as kind as possible, just useless.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
Setting TopLevelIrp is not used in a completely consistent manner, so I
think, in an effort to not say the wrong information, the docs give you
no information with that statement :).

When a file system sets TopLevelIrp, it indicates that some file system
locks are already held for this operation and the file system uses this
information if a recursive IO happens in the context of processing the
original IO request.

The file systems do not set this 100% of the time when a resource is
held, therefore if it is not set, you are not guaranteed that no
resources are held.

Here’s a little table that may make this clearer:
IoGetTopLevelIrp != NULL ==> some file system resources are already
held by this thread IoGetTopLevelIrp == NULL ==> probably no file
system resources are held by this thread, but this is not 100% true.
Instead a filter must rely on the operation context to determine whether
it is safe to issue queries to the file system.

I’ll talk to Diane about clarifying the documentation for
IoGetTopLevelIrp().

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 2:22 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

Molly

Thanks for the response. This thread is from a different scenario in
which there is no deadlock. It does however exhibit the behaviour where
as a certain fact you can see from the windbag output the thread holds
the PagingIoResource but IoGetTopLevelIrp returns NULL.

So the question I have is what to be precise does “If the current thread
holds no resources above the file system, IoGetTopLevelIrp returns
NULL.”
really mean?

It so happens I dont ever perform queries in the paging i/o paths
anyhow. I do however queue a worker thread to perform one or more
queries in some cases.

Thanks
Lyndon

“Molly Brown” wrote in message
news:xxxxx@ntfsd…
This is an explicit flush from the registry to flush the hives. Top
level IRP will not be set in this case. Are you sure that this is one
of the threads that is involved in the deadlock? From looking at this
stack, I wouldn’t expect any file system resources to be acquired if
your filter were to issue a query at this point.

Despite the fact that you may be able to safely query in this particular
stack, it is not generally safe to query in the paging IO paths
regardless of whether or not TopLevelIrp is set. You will definitely
see deadlocks if you do queries during paging IOs - it won’t happen 100%
of the time, but a filter cannot tell the difference between when it is
safe vs. when it is not, so you should design your filter to not rely on
querying during paging IO.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Lyndon J Clarke
Sent: Thursday, June 16, 2005 1:05 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Thread holds Fcb->PagionIoResource,
IoGetTopLevelIrp() returns null

No need for tomorrow … I have it here in breakpoint … simpler world,
different file, just the one filter, just the one thread …

Here is snippet of debug code which ran when IoGetTopLevelIrp() returned
NULL.

{
PIRP TopLevelIrp = IoGetTopLevelIrp();
ULONG PagingIoResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->PagingIoResource);
ULONG ResourceCounter =
ExIsResourceAcquiredSharedLite(((PFSRTL_COMMON_FCB_HEADER)(FileObject->F
sContext))->Resource);

if ((PagingIoResourceCounter != 0) || (PagingIoResourceCounter !=
0))
{
DbgPrint(“MYDRV: PANIC FO %08X FCB %08X IoGetTopLevel %08X
PagingIoResource %d Resource %d\n”, FileObject, FileObject->FsContext,
TopLevelIrp, PagingIoResourceCounter, ResourceCounter);
DbgBreakPoint();
}
}

Here is simple enough outputs from windbag.

----------------- %< ----------------------------------
MYDRV: PANIC FO 84FAEED0 FCB E1650A70 IoGetTopLevel 00000000
PagingIoResource 1 Resource 0 Break instruction exception - code
80000003 (first chance)
nt!DbgBreakPoint:
8086c810 cc int 3

kd> !thread
THREAD 855a3db0 Cid 0004.0050 Teb: 00000000 Win32Thread: 00000000
RUNNING on processor 0 Not impersonating
DeviceMap e1000400
Owning Process 855a77a8 Image: System
Wait Start TickCount 29954 Ticks: 0
Context Switch Count 751
UserTime 00:00:00.0000
KernelTime 00:00:02.0812
Start Address nt!ExpWorkerThread (0x8087a37e) Stack Init f78ef000
Current f78ee5d4 Base f78ef000 Limit f78ec000 Call 0 Priority 13
BasePriority 12 PriorityDecrement 0 ChildEBP RetAddr Args to Child
f78ee938 f6094275 f6095aa4 f6096240 f78ee9d8 nt!DbgBreakPoint (FPO:
[0,0,0]) f78ee950 f60944e1 f78ee988 00000000 84fad4f8
MYDRV!MyCacheFile+0x465 (FPO:
[Non-Fpo]) (CONV: stdcall)
f78ee99c f6084773 f78ee9d8 84faeed0 f78eea08 MYDRV!MyFilterFile+0xc1
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea18 f60855b9 84fad4f8 84f36e28 84fad4f8 MYDRV!MyHookRoutine+0x1d5
(FPO:
[Non-Fpo]) (CONV: stdcall)
f78eea34 8081d39d 84fad4f8 84f36e28 00000000 MYDRV!MyDispatch+0x2b (FPO:

[Non-Fpo]) (CONV: stdcall)
f78eea48 8081daa7 00000000 f78eea84 8535c348 nt!IofCallDriver+0x45 (FPO:

[Non-Fpo])
f78eea5c 80832bef 84faee0a f78eea84 f78eeb4c
nt!IoSynchronousPageWrite+0xaf
(FPO: [Non-Fpo])
f78eeb78 80833fa4 e147ee50 e147ee70 8535c348
nt!MiFlushSectionInternal+0x6b7
(FPO: [Non-Fpo])
f78eebbc 8080f552 8535c310 f78eec00 00004000 nt!MmFlushSection+0x234
(FPO:
[Non-Fpo])
f78eec44 808c6115 00004000 f78eec70 00000200 nt!CcFlushCache+0x38c (FPO:

[Non-Fpo])
f78eec9c 808b6983 e1ff9008 00000000 f78eecc0
nt!CmpFileWriteThroughCache+0xa1 (FPO: [Non-Fpo])
f78eed24 808b79b4 e1ff9008 00000000 e1ff9008 nt!HvpDoWriteHive+0xdb
(FPO:
[Non-Fpo])
f78eed3c 808b953f e1ff9001 855a3db0 8089d968 nt!HvSyncHive+0x92 (FPO:
[Non-Fpo])
f78eed58 808c248b 00000000 e1ff9300 f78eed78 nt!CmpDoFlushNextHive+0xe1
(FPO: [Non-Fpo])
f78eed80 8087a469 00000000 00000000 855a3db0 nt!CmpLazyFlushWorker+0x7f
(FPO: [Non-Fpo])
f78eedac 8094095c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
(FPO:
[Non-Fpo])
f78eeddc 8088757a 8087a37e 00000001 00000000
nt!PspSystemThreadStartup+0x2e
(FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> !object 84FAEED0
Object: 84faeed0 Type: (8559fe70) File
ObjectHeader: 84faeeb8
HandleCount: 1 PointerCount: 4
Directory Object: 00000000 Name: \Documents and
Settings\NetworkService\NTUSER.DAT {HarddiskVolume1}

kd> !irp 84f36e28 1
Irp is active with 10 stacks 10 is current (= 0x84f36fdc) Mdl =
f78eea84 Thread 855a3db0: Irp stack trace.
Flags = 00000043
ThreadListEntry.Flink = 84f36e38
ThreadListEntry.Blink = 84f36e38
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = f78eec68
UserEvent = f78eeb20
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000
UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = 84f36e68
Tail.Overlay.Thread = 855a3db0 Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink =
00000000 Tail.Overlay.CurrentStackLocation = 84f36fdc
Tail.Overlay.OriginalFileObject = 84faeed0 Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[4, 0] 0 0 84fad4f8 84faeed0 00000000-00000000
\Driver\MYDRV
Args: 00004000 00000000 00000000 00000000

kd> dt nt!_IO_STACK_LOCATION 84f36fdc
+0x000 MajorFunction : 0x4 ‘’
+0x001 MinorFunction : 0 ‘’
+0x002 Flags : 0 ‘’
+0x003 Control : 0 ‘’
+0x004 Parameters : __unnamed
+0x014 DeviceObject : 0x84fad4f8
+0x018 FileObject : 0x84faeed0
+0x01c CompletionRoutine : (null)
+0x020 Context : (null)

kd> dt MYDRV!_FSRTL_COMMON_FCB_HEADER E1650A70
+0x000 NodeTypeCode : 1797
+0x002 NodeByteSize : 328
+0x004 Flags : 0x60 ‘`’
+0x005 IsFastIoPossible : 0x1 ‘’
+0x006 Flags2 : 0x2 ‘’
+0x007 Reserved : 0 ‘’
+0x008 Resource : 0x8535c0a0
+0x00c PagingIoResource : 0x8535c3a8
+0x010 AllocationSize : _LARGE_INTEGER 0x36000
+0x018 FileSize : _LARGE_INTEGER 0x36000
+0x020 ValidDataLength : _LARGE_INTEGER 0x36000
+0x028 FastMutex : 0x8535c3e8
+0x02c FilterContexts : _LIST_ENTRY [0xe1650a9c - 0xe1650a9c]

kd> !locks 8535c0a0

Resource @ 0x8535c0a0 Available
1 total locks

kd> !locks 8535c3a8

Resource @ 0x8535c3a8 Shared 1 owning threads
Threads: 855a3db0-01<*>
1 total locks, 1 locks currently held
----------------- %< ----------------------------------

“Lyndon J Clarke” wrote in message
news:xxxxx@ntfsd…
> Gentlefolk
>
> The IFS documentation for IoGetTopLevelIrp() says “If the current
> thread holds no resources above the file system, IoGetTopLevelIrp
returns NULL.”.
> I have always taken this to mean that the thread does not hold either
> of the Fcb main resource or paging io resource of the Fcb relevant to
> the i/o request in progress; for example the file being written in the

> case of an IRP_MJ_WRITE. Is this a correct interpretation?
>
> I ask because I have just seen an interesting deadlock for the first
> time on W2K3 SP1. In this deadlock a first thread has sent
> IRP_MJ_FLUSH_BUFFERS for the volume which contains AppEvent.evt the
> windows application event log. This first thread holds the shared vcb
> resource and is waiting to acquire the paging io resource for the Fcb
> for this file. In this state a second thread has called
> IoSynchronousPageWrite and a filter driver in its dispatch handler in
> that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
> filename a la filespy) for the file object which happens to refer to
> the same Fcb. There is a deadlock of course because the second thread
holds the paging io resource and waits for the shared vcb resource.
> The filter driver in the second thread will not send
> IRP_MJ_QUERY_INFORMATION unless IoGetTopLevelIrp() returns NULL; on
> this occasion IoGetTopLevelIrp() has indeed returned NULL.
>
> Thanks in advance
> Lyndon
>
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> the paging io resource for the Fcb for this file. In this state a second

thread has called IoSynchronousPageWrite and a filter driver in its dispatch
handler in that thread has sent an IRP_MJ_QUERY_INFORMATION (to retrieve the
filename a la filespy) for the file object which happens to refer to the
same Fcb.

This is for sure a deadlock-prone thing. Try to not re-enter the filesystem in
the paging write paths.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

>This is an explicit flush from the registry to flush the hives. Top

level IRP will not be set in this case.

Yes, and this is a well-known deadlock source.

In our snapshot engine, we have the analog of
IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES for OSes starting from NT4 up. I remember
having several deadlock issues with this registry flusher about 2 years ago.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> You a lawyer now Alexei?

No, he is correct from the pure formal logic point of view :slight_smile: BTW, in Russia
lawyers do study it, while the engineers (including software) do not :slight_smile:

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Interesting. Here I think lawyers do not study it but students in most
numerate disciplines do study it. It sure is a funny old world :wink:

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntfsd…
>> You a lawyer now Alexei?
>
> No, he is correct from the pure formal logic point of view :slight_smile: BTW, in
> Russia
> lawyers do study it, while the engineers (including software) do not :slight_smile:
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>

> Interesting. Here I think lawyers do not study it but students in most

numerate disciplines do study it. It sure is a funny old world :wink:

> No, he is correct from the pure formal logic point of view :slight_smile: BTW, in
> Russia
> lawyers do study it, while the engineers (including software) do not :slight_smile:

Comments from a russian living in US.

As I see in standard US IQ tests, this logical error (math people would
call it a confusion of necessary and sufficient conditions) is considered to
be
deadly in both worlds.

"Assume that both of the the folllowing two statements are true:

  • each and every russian drink no less than a gallon (=3.84 liters) of vodka
    per minute;
  • Ivan drinks 3.85 liters of vodka per minute.
    Question:
    Is Ivan a russian?"

The correct answer is “I don’t know”, because the assumption does not
exclude John from, say, Australia, who just happens to drink 3.86 liters
of vodka per minute.

Given that “if A, then B” and given that B happens to be true, one can not
assume that A is also true (B can be true for different reasons, nobody
said that A is the ONLY reason for B to be true - that’s the key point).

It’s not lawers (or mathenaticians) vs everyone else.

It’s also not about different education systems (and they ARE different:
european style is “teach how to learn”, the american style being
“teach how to do”).

It’s about… Well, it’s all about beer (I hope).

Regards,
Alex

PsTerminateSystemThread(STATUS_SUCCESS); // beer is good :slight_smile:

“xxxxx@Home” wrote in message news:xxxxx@ntfsd…
>> Interesting. Here I think lawyers do not study it but students in most
>> numerate disciplines do study it. It sure is a funny old world :wink:
>
>>> No, he is correct from the pure formal logic point of view :slight_smile: BTW, in
>>> Russia
>>> lawyers do study it, while the engineers (including software) do not :slight_smile:
>
> Comments from a russian living in US.
>
> As I see in standard US IQ tests, this logical error (math people would
> call it a confusion of necessary and sufficient conditions) is considered
> to be
> deadly in both worlds.
>
> “Assume that both of the the folllowing two statements are true:
> - each and every russian drink no less than a gallon (=3.84 liters) of
> vodka per minute;
> - Ivan drinks 3.85 liters of vodka per minute.
> Question:
> Is Ivan a russian?”
>
> The correct answer is “I don’t know”, because the assumption does not
> exclude John from, say, Australia, who just happens to drink 3.86 liters
> of vodka per minute.
>
> Given that “if A, then B” and given that B happens to be true, one can not
> assume that A is also true (B can be true for different reasons, nobody
> said that A is the ONLY reason for B to be true - that’s the key point).
>
> It’s not lawers (or mathenaticians) vs everyone else.
>
> It’s also not about different education systems (and they ARE different:
> european style is “teach how to learn”, the american style being
> “teach how to do”).
>
> It’s about… Well, it’s all about beer (I hope).
>
> Regards,
> Alex
>
>
>