CacheManager Confusion?? (please clarify if you can)

Hi all,

In the process of trying to debug a filter driver, I have run into some
behavior that I truely do not understand. It is probably something stupid,
but I am hoping someone can shed some light on this. I am finding that when
I create a file and then write to it (using buffered I/O), sometimes, but
not always, the buffered writes generated by the CacheManager go to a
DIFFERENT FILEOBJECT than the original Create and Write. I can’t find that
the FileObject in question has ever been Created. Below is an example:

I am confused as to where this extra FileObject is coming from. The presence
of this additional FileObject, is greatly confusing my filter driver. The
initial (buffered) write goes to the FileObject as expected, but the paging
writes to support it go to an entirely different FileObject. What is
happening here??

Thanks for any help,

Don

I am running the FileSpy app as shipped with the IFS Kit.

First I create a file, FileHandle = 864BD778

I 00000D68 13:12:28:447 13:12:28:447 c04.668 IRP_MJ_CREATE
85DEFD60 864BD778 00000000:00000002 40000884 --S- e:\test\test.file

Then I write to it (buffered):
I 00000D6F 13:12:32:244 13:12:32:479 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 864BD778 00000000:00400000 40000a00 ----
e:\test\test.file

This of course generates lots of paging writes, some of which are as
follows. but the paging I/O is to fileObject 860ABDE8, not 864BD778. There
are 64 paging writes, which is the correct number to account for the initial
4 MByte buffered I/O.

O 00000D70 13:12:32:244 13:12:32:244 c04.668 ACQUIRE_FOR_CC_FLUSH
85DEFD60 860ABDE8 00000000 e:[-=Nested Operation=-]
I 00000D71 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D72 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D73 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D74 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
O 00000D75 13:12:32:244 13:12:32:244 c04.668 RELEASE_FOR_CC_FLUSH
85DEFD60 860ABDE8 00000000 e:[-=Not In Cache=-]

After a lot more paging writes, the file is cleaned up and closed.

I 00000DD7 13:12:36:244 13:12:36:260 c04.668 IRP_MJ_CLEANUP
85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
I 00000DF4 13:12:36:260 13:12:36:260 c04.668 IRP_MJ_CLOSE
85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file

When I look at the same operation using FileMon from SysInternals, I see the
following:

Here, the file is opened

100 1:33:49 PM AfapTester.exe:3076 IRP_MJ_CREATE E:\test\test3.file SUCCESS
Options: OpenIf Access: All

Here is the initial write
105 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE E:\test\test3.file SUCCESS
Offset: 0 Length: 4194304

Here are some of the Paging writes, again to a different file
($ConvertToNonresident)

106 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 0 Length: 65536
107 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 65536 Length: 65536
108 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 131072 Length: 65536
109 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 196608 Length: 65536

Finally the file is cleaned up and closed:
177 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLEANUP E:\test\test3.file SUCCESS
206 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLOSE E:\test\test3.file SUCCESS

What could be happening is that when caching is initialized for the file,
NTFS creates a stream fileobject to do it. MM stores away the first
fileobject used to initialize caching and uses it for flushes later on.

These fileobjects do not go through the normal IRP_MJ_CREATE pathway but can
be related through their FsContext pointers. Also, you can recognize these
fileobjects by the FO_STREAM_FILE flag set in the fileobject->flags field.

Pete

Peter Scott
Windows Filesystem and Device Driver Consulting
www.KernelDrivers.com
(303)546-0300

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-195687-
xxxxx@lists.osr.com] On Behalf Of Don
Sent: Thursday, December 09, 2004 10:41 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] CacheManager Confusion?? (please clarify if you can)

Hi all,

In the process of trying to debug a filter driver, I have run into some
behavior that I truely do not understand. It is probably something stupid,
but I am hoping someone can shed some light on this. I am finding that
when
I create a file and then write to it (using buffered I/O), sometimes, but
not always, the buffered writes generated by the CacheManager go to a
DIFFERENT FILEOBJECT than the original Create and Write. I can’t find that
the FileObject in question has ever been Created. Below is an example:

I am confused as to where this extra FileObject is coming from. The
presence
of this additional FileObject, is greatly confusing my filter driver. The
initial (buffered) write goes to the FileObject as expected, but the
paging
writes to support it go to an entirely different FileObject. What is
happening here??

Thanks for any help,

Don

I am running the FileSpy app as shipped with the IFS Kit.

First I create a file, FileHandle = 864BD778

I 00000D68 13:12:28:447 13:12:28:447 c04.668 IRP_MJ_CREATE
85DEFD60 864BD778 00000000:00000002 40000884 --S- e:\test\test.file

Then I write to it (buffered):
I 00000D6F 13:12:32:244 13:12:32:479 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 864BD778 00000000:00400000 40000a00 ----
e:\test\test.file

This of course generates lots of paging writes, some of which are as
follows. but the paging I/O is to fileObject 860ABDE8, not 864BD778. There
are 64 paging writes, which is the correct number to account for the
initial
4 MByte buffered I/O.

O 00000D70 13:12:32:244 13:12:32:244 c04.668 ACQUIRE_FOR_CC_FLUSH
85DEFD60 860ABDE8 00000000 e:[-=Nested Operation=-]
I 00000D71 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D72 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D73 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
I 00000D74 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
e:[-=Not In Cache=-]
O 00000D75 13:12:32:244 13:12:32:244 c04.668 RELEASE_FOR_CC_FLUSH
85DEFD60 860ABDE8 00000000 e:[-=Not In Cache=-]

After a lot more paging writes, the file is cleaned up and closed.

I 00000DD7 13:12:36:244 13:12:36:260 c04.668 IRP_MJ_CLEANUP
85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
I 00000DF4 13:12:36:260 13:12:36:260 c04.668 IRP_MJ_CLOSE
85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file

When I look at the same operation using FileMon from SysInternals, I see
the
following:

Here, the file is opened

100 1:33:49 PM AfapTester.exe:3076 IRP_MJ_CREATE E:\test\test3.file
SUCCESS
Options: OpenIf Access: All

Here is the initial write
105 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE E:\test\test3.file
SUCCESS
Offset: 0 Length: 4194304

Here are some of the Paging writes, again to a different file
($ConvertToNonresident)

106 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 0 Length: 65536
107 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 65536 Length: 65536
108 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 131072 Length: 65536
109 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
SUCCESS Offset: 196608 Length: 65536

Finally the file is cleaned up and closed:
177 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLEANUP E:\test\test3.file
SUCCESS
206 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLOSE E:\test\test3.file
SUCCESS


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

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

On NTFS and on FAT directories, stream file objects are created to attach
the cache map to. Paging IO from Cc will go to these file objects.

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

----- Original Message -----
From: “Don”
Newsgroups: ntfsd
To: “Windows File Systems Devs Interest List”
Sent: Thursday, December 09, 2004 9:40 PM
Subject: [ntfsd] CacheManager Confusion?? (please clarify if you can)

> Hi all,
>
> In the process of trying to debug a filter driver, I have run into some
> behavior that I truely do not understand. It is probably something stupid,
> but I am hoping someone can shed some light on this. I am finding that when
> I create a file and then write to it (using buffered I/O), sometimes, but
> not always, the buffered writes generated by the CacheManager go to a
> DIFFERENT FILEOBJECT than the original Create and Write. I can’t find that
> the FileObject in question has ever been Created. Below is an example:
>
> I am confused as to where this extra FileObject is coming from. The presence
> of this additional FileObject, is greatly confusing my filter driver. The
> initial (buffered) write goes to the FileObject as expected, but the paging
> writes to support it go to an entirely different FileObject. What is
> happening here??
>
> Thanks for any help,
>
> Don
>
> I am running the FileSpy app as shipped with the IFS Kit.
>
> First I create a file, FileHandle = 864BD778
>
> I 00000D68 13:12:28:447 13:12:28:447 c04.668 IRP_MJ_CREATE
> 85DEFD60 864BD778 00000000:00000002 40000884 --S- e:\test\test.file
>
> Then I write to it (buffered):
> I 00000D6F 13:12:32:244 13:12:32:479 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 864BD778 00000000:00400000 40000a00 ----
> e:\test\test.file
>
> This of course generates lots of paging writes, some of which are as
> follows. but the paging I/O is to fileObject 860ABDE8, not 864BD778. There
> are 64 paging writes, which is the correct number to account for the initial
> 4 MByte buffered I/O.
>
> O 00000D70 13:12:32:244 13:12:32:244 c04.668 ACQUIRE_FOR_CC_FLUSH
> 85DEFD60 860ABDE8 00000000 e:[-=Nested Operation=-]
> I 00000D71 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D72 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D73 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D74 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> O 00000D75 13:12:32:244 13:12:32:244 c04.668 RELEASE_FOR_CC_FLUSH
> 85DEFD60 860ABDE8 00000000 e:[-=Not In Cache=-]
>
> After a lot more paging writes, the file is cleaned up and closed.
>
> I 00000DD7 13:12:36:244 13:12:36:260 c04.668 IRP_MJ_CLEANUP
> 85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
> I 00000DF4 13:12:36:260 13:12:36:260 c04.668 IRP_MJ_CLOSE
> 85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
>
>
> When I look at the same operation using FileMon from SysInternals, I see the
> following:
>
> Here, the file is opened
>
> 100 1:33:49 PM AfapTester.exe:3076 IRP_MJ_CREATE E:\test\test3.file SUCCESS
> Options: OpenIf Access: All
>
> Here is the initial write
> 105 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE E:\test\test3.file SUCCESS
> Offset: 0 Length: 4194304
>
> Here are some of the Paging writes, again to a different file
> ($ConvertToNonresident)
>
> 106 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 0 Length: 65536
> 107 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 65536 Length: 65536
> 108 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 131072 Length: 65536
> 109 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 196608 Length: 65536
>
> Finally the file is cleaned up and closed:
> 177 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLEANUP E:\test\test3.file SUCCESS
> 206 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLOSE E:\test\test3.file SUCCESS
>
>
>
>
> —
> Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Thanks to Peter and Maxim for clarifying this for me.

If you don’t mind, let me make sure that I understand this. When caching is
initialized, NTFS creates an additional fileobject and registers that one
with the MM. Thus future flushes come through this FileObject instead of the
one originally used to create the file. The two file objects can be tied
together because their fileObject->FsContext pointers will be the same, so a
filter driver can use the value of the FsContext pointer to associate the
FileObject being used for flushes with the original FileObject used to
create the file.

Does this basicly describe it correctly?

Just out of curosity, why does NTFS do this? What does it gain from the
extra FileObject.

Thanks,

Don

“Peter Scott” wrote in message
news:xxxxx@ntfsd…
>
> What could be happening is that when caching is initialized for the file,
> NTFS creates a stream fileobject to do it. MM stores away the first
> fileobject used to initialize caching and uses it for flushes later on.
>
> These fileobjects do not go through the normal IRP_MJ_CREATE pathway but
> can
> be related through their FsContext pointers. Also, you can recognize these
> fileobjects by the FO_STREAM_FILE flag set in the fileobject->flags field.
>
> Pete
>
> Peter Scott
> Windows Filesystem and Device Driver Consulting
> www.KernelDrivers.com
> (303)546-0300
>
>
>> -----Original Message-----
>> From: xxxxx@lists.osr.com [mailto:bounce-195687-
>> xxxxx@lists.osr.com] On Behalf Of Don
>> Sent: Thursday, December 09, 2004 10:41 AM
>> To: Windows File Systems Devs Interest List
>> Subject: [ntfsd] CacheManager Confusion?? (please clarify if you can)
>>
>> Hi all,
>>
>> In the process of trying to debug a filter driver, I have run into some
>> behavior that I truely do not understand. It is probably something
>> stupid,
>> but I am hoping someone can shed some light on this. I am finding that
>> when
>> I create a file and then write to it (using buffered I/O), sometimes, but
>> not always, the buffered writes generated by the CacheManager go to a
>> DIFFERENT FILEOBJECT than the original Create and Write. I can’t find
>> that
>> the FileObject in question has ever been Created. Below is an example:
>>
>> I am confused as to where this extra FileObject is coming from. The
>> presence
>> of this additional FileObject, is greatly confusing my filter driver. The
>> initial (buffered) write goes to the FileObject as expected, but the
>> paging
>> writes to support it go to an entirely different FileObject. What is
>> happening here??
>>
>> Thanks for any help,
>>
>> Don
>>
>> I am running the FileSpy app as shipped with the IFS Kit.
>>
>> First I create a file, FileHandle = 864BD778
>>
>> I 00000D68 13:12:28:447 13:12:28:447 c04.668 IRP_MJ_CREATE
>> 85DEFD60 864BD778 00000000:00000002 40000884 --S- e:\test\test.file
>>
>> Then I write to it (buffered):
>> I 00000D6F 13:12:32:244 13:12:32:479 c04.668 IRP_MJ_WRITE
>> IRP_MN_NORMAL 85DEFD60 864BD778 00000000:00400000 40000a00 ----
>> e:\test\test.file
>>
>> This of course generates lots of paging writes, some of which are as
>> follows. but the paging I/O is to fileObject 860ABDE8, not 864BD778.
>> There
>> are 64 paging writes, which is the correct number to account for the
>> initial
>> 4 MByte buffered I/O.
>>
>> O 00000D70 13:12:32:244 13:12:32:244 c04.668 ACQUIRE_FOR_CC_FLUSH
>> 85DEFD60 860ABDE8 00000000 e:[-=Nested Operation=-]
>> I 00000D71 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
>> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
>> e:[-=Not In Cache=-]
>> I 00000D72 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
>> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
>> e:[-=Not In Cache=-]
>> I 00000D73 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
>> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
>> e:[-=Not In Cache=-]
>> I 00000D74 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
>> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
>> e:[-=Not In Cache=-]
>> O 00000D75 13:12:32:244 13:12:32:244 c04.668 RELEASE_FOR_CC_FLUSH
>> 85DEFD60 860ABDE8 00000000 e:[-=Not In Cache=-]
>>
>> After a lot more paging writes, the file is cleaned up and closed.
>>
>> I 00000DD7 13:12:36:244 13:12:36:260 c04.668 IRP_MJ_CLEANUP
>> 85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
>> I 00000DF4 13:12:36:260 13:12:36:260 c04.668 IRP_MJ_CLOSE
>> 85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
>>
>>
>> When I look at the same operation using FileMon from SysInternals, I see
>> the
>> following:
>>
>> Here, the file is opened
>>
>> 100 1:33:49 PM AfapTester.exe:3076 IRP_MJ_CREATE E:\test\test3.file
>> SUCCESS
>> Options: OpenIf Access: All
>>
>> Here is the initial write
>> 105 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE E:\test\test3.file
>> SUCCESS
>> Offset: 0 Length: 4194304
>>
>> Here are some of the Paging writes, again to a different file
>> ($ConvertToNonresident)
>>
>> 106 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
>> SUCCESS Offset: 0 Length: 65536
>> 107 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
>> SUCCESS Offset: 65536 Length: 65536
>> 108 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
>> SUCCESS Offset: 131072 Length: 65536
>> 109 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
>> SUCCESS Offset: 196608 Length: 65536
>>
>> Finally the file is cleaned up and closed:
>> 177 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLEANUP E:\test\test3.file
>> SUCCESS
>> 206 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLOSE E:\test\test3.file
>> SUCCESS
>>
>>
>>
>>
>> —
>> Questions? First check the IFS FAQ at
>> https://www.osronline.com/article.cfm?id=17
>>
>> You are currently subscribed to ntfsd as: xxxxx@kerneldrivers.com
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>

Hi,

Peter and Maxims response helped me a lot, but it left me wondering
something else. Perhaps someone can clarify this.

Suppose that two different user mode applications open the same file. This
would create two different FileObjects, both pointing to the same FCB.

Now, NTFS creates the stream file object, making a third FileObject. The
filter driver starts seeing paging I/O on the third (Stream) file object. Is
there anyway to determine in the filter driver which of the two original
FileObjects the paging I/O is being done on behalf of?

Thanks,

Don

“Don” wrote in message news:xxxxx@ntfsd…
> Hi all,
>
> In the process of trying to debug a filter driver, I have run into some
> behavior that I truely do not understand. It is probably something stupid,
> but I am hoping someone can shed some light on this. I am finding that
> when I create a file and then write to it (using buffered I/O), sometimes,
> but not always, the buffered writes generated by the CacheManager go to a
> DIFFERENT FILEOBJECT than the original Create and Write. I can’t find that
> the FileObject in question has ever been Created. Below is an example:
>
> I am confused as to where this extra FileObject is coming from. The
> presence of this additional FileObject, is greatly confusing my filter
> driver. The initial (buffered) write goes to the FileObject as expected,
> but the paging writes to support it go to an entirely different
> FileObject. What is happening here??
>
> Thanks for any help,
>
> Don
>
> I am running the FileSpy app as shipped with the IFS Kit.
>
> First I create a file, FileHandle = 864BD778
>
> I 00000D68 13:12:28:447 13:12:28:447 c04.668 IRP_MJ_CREATE 85DEFD60
> 864BD778 00000000:00000002 40000884 --S- e:\test\test.file
>
> Then I write to it (buffered):
> I 00000D6F 13:12:32:244 13:12:32:479 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 864BD778 00000000:00400000 40000a00 ----
> e:\test\test.file
>
> This of course generates lots of paging writes, some of which are as
> follows. but the paging I/O is to fileObject 860ABDE8, not 864BD778. There
> are 64 paging writes, which is the correct number to account for the
> initial 4 MByte buffered I/O.
>
> O 00000D70 13:12:32:244 13:12:32:244 c04.668 ACQUIRE_FOR_CC_FLUSH
> 85DEFD60 860ABDE8 00000000 e:[-=Nested Operation=-]
> I 00000D71 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D72 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D73 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> I 00000D74 13:12:32:244 13:12:32:244 c04.668 IRP_MJ_WRITE
> IRP_MN_NORMAL 85DEFD60 860ABDE8 00000000:00010000 40000043 NP-Y
> e:[-=Not In Cache=-]
> O 00000D75 13:12:32:244 13:12:32:244 c04.668 RELEASE_FOR_CC_FLUSH
> 85DEFD60 860ABDE8 00000000 e:[-=Not In Cache=-]
>
> After a lot more paging writes, the file is cleaned up and closed.
>
> I 00000DD7 13:12:36:244 13:12:36:260 c04.668 IRP_MJ_CLEANUP
> 85DEFD60 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
> I 00000DF4 13:12:36:260 13:12:36:260 c04.668 IRP_MJ_CLOSE 85DEFD60
> 864BD778 00000000:00000000 40000404 --S- e:\test\test.file
>
>
> When I look at the same operation using FileMon from SysInternals, I see
> the following:
>
> Here, the file is opened
>
> 100 1:33:49 PM AfapTester.exe:3076 IRP_MJ_CREATE E:\test\test3.file
> SUCCESS Options: OpenIf Access: All
>
> Here is the initial write
> 105 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE E:\test\test3.file
> SUCCESS Offset: 0 Length: 4194304
>
> Here are some of the Paging writes, again to a different file
> ($ConvertToNonresident)
>
> 106 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 0 Length: 65536
> 107 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 65536 Length: 65536
> 108 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 131072 Length: 65536
> 109 1:33:54 PM AfapTester.exe:3076 IRP_MJ_WRITE* E:$ConvertToNonresident
> SUCCESS Offset: 196608 Length: 65536
>
> Finally the file is cleaned up and closed:
> 177 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLEANUP E:\test\test3.file
> SUCCESS
> 206 1:34:00 PM AfapTester.exe:3076 IRP_MJ_CLOSE E:\test\test3.file
> SUCCESS
>
>
>
>

> Now, NTFS creates the stream file object, making a third FileObject. The

filter driver starts seeing paging I/O on the third (Stream) file object.
Is there anyway to determine in the filter driver which of the two
original FileObjects the paging I/O is being done on behalf of?

The cache is shared for all instances of one open file (and thus,
for all file objects). It is immaterial to determine which file object
has initiated the paging IO. Filter or file system does not
care about it, it cares only about FCB.

L.

Ladislav,

Thanks for your answer, I thought that this would probably be the case.

Unfortunately, it does make a bit of a problem for my particluar filter. The
point of my filter is to prioritize I/O getting to the file systems. Some
FileObjects are low priority, others are HighPriority. It is possible for
there to be a LowPriority and a HighPriority FileObject open to the same
file. Thus it would be good if I could determine if this particluar I/O
originated with the LowPriority object or the HighPriority object because
that will tell the filter how to handle the paging I/O. But I think you are
right, there is probably no good way to tell.

Don

“Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
>> Now, NTFS creates the stream file object, making a third FileObject. The
>> filter driver starts seeing paging I/O on the third (Stream) file object.
>> Is there anyway to determine in the filter driver which of the two
>> original FileObjects the paging I/O is being done on behalf of?
>
> The cache is shared for all instances of one open file (and thus,
> for all file objects). It is immaterial to determine which file object
> has initiated the paging IO. Filter or file system does not
> care about it, it cares only about FCB.
>
> L.
>
>

> Unfortunately, it does make a bit of a problem for my particluar filter.

The point of my filter is to prioritize I/O getting to the file systems.
Some FileObjects are low priority, others are HighPriority. It is possible
for there to be a LowPriority and a HighPriority FileObject open to the
same

I think you should leave paging I/O requests be.
If you will hold them until requests on “higher-priority”
file objects will be completed, you may hang the system.
Your filter could so bring more problems than useful things.

L.

One other issue with prioritizing IO based upon the fileobjects is that
memory mapped IO is out the door. If several people open a file and memory
map it, there is no way to determine which paging flushes are associated to
which user performing IO.

If you are attempting to prioritize the IO, I would suggest doing it at the
top level. Prioritize the cached requests which will come in against the
original fileobject, don’t prioritize the paging IO. As Ladislav indicated
you could cause other problems by blocking paging requests. Of course,
again, the prioritization of top level IO requests is still out the door
when you introduce memory mapped files since you don’t have top level IO.

Pete

Peter Scott
Windows Filesystem and Device Driver Consulting
www.KernelDrivers.com
(303)546-0300

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-195781-
xxxxx@lists.osr.com] On Behalf Of Don
Sent: Friday, December 10, 2004 6:15 AM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Re:CacheManager Confusion?? (please clarify if you
can)

Ladislav,

Thanks for your answer, I thought that this would probably be the case.

Unfortunately, it does make a bit of a problem for my particluar filter.
The
point of my filter is to prioritize I/O getting to the file systems. Some
FileObjects are low priority, others are HighPriority. It is possible for
there to be a LowPriority and a HighPriority FileObject open to the same
file. Thus it would be good if I could determine if this particluar I/O
originated with the LowPriority object or the HighPriority object because
that will tell the filter how to handle the paging I/O. But I think you
are
right, there is probably no good way to tell.

Don

“Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
> >> Now, NTFS creates the stream file object, making a third FileObject.
> The
> >> filter driver starts seeing paging I/O on the third (Stream) file
> object.
> >> Is there anyway to determine in the filter driver which of the two
> >> original FileObjects the paging I/O is being done on behalf of?
> >
> > The cache is shared for all instances of one open file (and thus,
> > for all file objects). It is immaterial to determine which file object
> > has initiated the paging IO. Filter or file system does not
> > care about it, it cares only about FCB.
> >
> > L.
> >
> >
>
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@kerneldrivers.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

Peter and Ladislav,

Thanks for all your input.

I had originally decided to ignore the top level IO since it is only going
to hit RAM and not the disk, which is the resource I am trying to protect. I
also figured that by doing the prioritization at the paging level, I would
get memory mapped files as well.

However, you are starting to convince me that this is a bad design. However,
I wanted to ask one question. I am not blocking or even marking these paging
IRPs pending, I am simply causing them to wait on an event for a while. Is
this still likely to cause deadlocks or other nasty problems? So far, it
seems to be working, aside from the issue mentioned of not being able to
figure out what the original FileObject is.

Let me know what you think,

Thanks,

Don

“Peter Scott” wrote in message
news:xxxxx@ntfsd…
>
> One other issue with prioritizing IO based upon the fileobjects is that
> memory mapped IO is out the door. If several people open a file and memory
> map it, there is no way to determine which paging flushes are associated
> to
> which user performing IO.
>
> If you are attempting to prioritize the IO, I would suggest doing it at
> the
> top level. Prioritize the cached requests which will come in against the
> original fileobject, don’t prioritize the paging IO. As Ladislav indicated
> you could cause other problems by blocking paging requests. Of course,
> again, the prioritization of top level IO requests is still out the door
> when you introduce memory mapped files since you don’t have top level IO.
>
> Pete
>
> Peter Scott
> Windows Filesystem and Device Driver Consulting
> www.KernelDrivers.com
> (303)546-0300
>
>> -----Original Message-----
>> From: xxxxx@lists.osr.com [mailto:bounce-195781-
>> xxxxx@lists.osr.com] On Behalf Of Don
>> Sent: Friday, December 10, 2004 6:15 AM
>> To: Windows File Systems Devs Interest List
>> Subject: Re:[ntfsd] Re:CacheManager Confusion?? (please clarify if you
>> can)
>>
>> Ladislav,
>>
>> Thanks for your answer, I thought that this would probably be the case.
>>
>> Unfortunately, it does make a bit of a problem for my particluar filter.
>> The
>> point of my filter is to prioritize I/O getting to the file systems. Some
>> FileObjects are low priority, others are HighPriority. It is possible for
>> there to be a LowPriority and a HighPriority FileObject open to the same
>> file. Thus it would be good if I could determine if this particluar I/O
>> originated with the LowPriority object or the HighPriority object because
>> that will tell the filter how to handle the paging I/O. But I think you
>> are
>> right, there is probably no good way to tell.
>>
>> Don
>>
>> “Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
>> >> Now, NTFS creates the stream file object, making a third FileObject.
>> The
>> >> filter driver starts seeing paging I/O on the third (Stream) file
>> object.
>> >> Is there anyway to determine in the filter driver which of the two
>> >> original FileObjects the paging I/O is being done on behalf of?
>> >
>> > The cache is shared for all instances of one open file (and thus,
>> > for all file objects). It is immaterial to determine which file object
>> > has initiated the paging IO. Filter or file system does not
>> > care about it, it cares only about FCB.
>> >
>> > L.
>> >
>> >
>>
>>
>>
>> —
>> Questions? First check the IFS FAQ at
>> https://www.osronline.com/article.cfm?id=17
>>
>> You are currently subscribed to ntfsd as: xxxxx@kerneldrivers.com
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>

Right, waiting on an event is blocking the request. It is not advised to
block MM if it is trying to issue an IO. It would be better to pend these
types of requests to allow for the thread to continue doing other work, but
this is not fail safe. Blocking CC is not quite as bad.

Try to stress the system and you will likely get into system deadlocks.

Look in the FAT code and you will see checks for CanIWait(), or something
like that, at the top of the write dispatch routine. Try to follow these
semantics.

Pete

Peter Scott
Windows Filesystem and Device Driver Consulting
www.KernelDrivers.com
(303)546-0300

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-195824-
xxxxx@lists.osr.com] On Behalf Of Don
Sent: Friday, December 10, 2004 2:39 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Re:CacheManager Confusion?? (please clarify if you
can)

Peter and Ladislav,

Thanks for all your input.

I had originally decided to ignore the top level IO since it is only going
to hit RAM and not the disk, which is the resource I am trying to protect.
I
also figured that by doing the prioritization at the paging level, I would
get memory mapped files as well.

However, you are starting to convince me that this is a bad design.
However,
I wanted to ask one question. I am not blocking or even marking these
paging
IRPs pending, I am simply causing them to wait on an event for a while. Is
this still likely to cause deadlocks or other nasty problems? So far, it
seems to be working, aside from the issue mentioned of not being able to
figure out what the original FileObject is.

Let me know what you think,

Thanks,

Don

“Peter Scott” wrote in message
> news:xxxxx@ntfsd…
> >
> > One other issue with prioritizing IO based upon the fileobjects is that
> > memory mapped IO is out the door. If several people open a file and
> memory
> > map it, there is no way to determine which paging flushes are associated
> > to
> > which user performing IO.
> >
> > If you are attempting to prioritize the IO, I would suggest doing it at
> > the
> > top level. Prioritize the cached requests which will come in against the
> > original fileobject, don’t prioritize the paging IO. As Ladislav
> indicated
> > you could cause other problems by blocking paging requests. Of course,
> > again, the prioritization of top level IO requests is still out the door
> > when you introduce memory mapped files since you don’t have top level
> IO.
> >
> > Pete
> >
> > Peter Scott
> > Windows Filesystem and Device Driver Consulting
> > www.KernelDrivers.com
> > (303)546-0300
> >
> >> -----Original Message-----
> >> From: xxxxx@lists.osr.com [mailto:bounce-195781-
> >> xxxxx@lists.osr.com] On Behalf Of Don
> >> Sent: Friday, December 10, 2004 6:15 AM
> >> To: Windows File Systems Devs Interest List
> >> Subject: Re:[ntfsd] Re:CacheManager Confusion?? (please clarify if you
> >> can)
> >>
> >> Ladislav,
> >>
> >> Thanks for your answer, I thought that this would probably be the case.
> >>
> >> Unfortunately, it does make a bit of a problem for my particluar
> filter.
> >> The
> >> point of my filter is to prioritize I/O getting to the file systems.
> Some
> >> FileObjects are low priority, others are HighPriority. It is possible
> for
> >> there to be a LowPriority and a HighPriority FileObject open to the
> same
> >> file. Thus it would be good if I could determine if this particluar I/O
> >> originated with the LowPriority object or the HighPriority object
> because
> >> that will tell the filter how to handle the paging I/O. But I think you
> >> are
> >> right, there is probably no good way to tell.
> >>
> >> Don
> >>
> >> “Ladislav Zezula” wrote in message
> news:xxxxx@ntfsd…
> >> >> Now, NTFS creates the stream file object, making a third FileObject.
> >> The
> >> >> filter driver starts seeing paging I/O on the third (Stream) file
> >> object.
> >> >> Is there anyway to determine in the filter driver which of the two
> >> >> original FileObjects the paging I/O is being done on behalf of?
> >> >
> >> > The cache is shared for all instances of one open file (and thus,
> >> > for all file objects). It is immaterial to determine which file
> object
> >> > has initiated the paging IO. Filter or file system does not
> >> > care about it, it cares only about FCB.
> >> >
> >> > L.
> >> >
> >> >
> >>
> >>
> >>
> >> —
> >> Questions? First check the IFS FAQ at
> >> https://www.osronline.com/article.cfm?id=17
> >>
> >> You are currently subscribed to ntfsd as: xxxxx@kerneldrivers.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@kerneldrivers.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

> I wanted to ask one question. I am not blocking or even marking these paging

IRPs pending, I am simply causing them to wait on an event for a while. Is
this still likely to cause deadlocks or other nasty problems?

Yes. Starvation, for instance.

Also you cannot wait in paging write paths, they are nonblocking (or your will
deadlock the MM).

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

> this still likely to cause deadlocks or other nasty problems? So far, it

seems to be working, aside from the issue mentioned of not being able to

Yes, at the first sight, it seems to be “working”.
But if you have implemented some feature
that has an designed bug, sooner or later you will
experience problems.

Try to run it on an environment where Task Manager shows
two - three pages of running processes, and you will see
how suddenly strange things will happen :-))

Or try it on environment where the boot and explorer start
takes 10-15 minutes (I’ve seen such configurations).

Or try to run some system stress test.

Or try to mark a network folder to be “offline folder”
and then try to copy 3 GB of small files there
(I recommend instalation DVD of the latest MSDN :-))

L.