Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

CacheManager Confusion?? (please clarify if you can)

OSR_Community_UserOSR_Community_User Member Posts: 110,217
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

Comments

  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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: [email protected] [mailto:bounce-195687-
    > [email protected]] 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: [email protected]
    > To unsubscribe send a blank email to [email protected]
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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
    [email protected]
    http://www.storagecraft.com

    ----- Original Message -----
    From: "Don" <[email protected]>
    Newsgroups: ntfsd
    To: "Windows File Systems Devs Interest List" <[email protected]>
    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: [email protected]
    > To unsubscribe send a blank email to [email protected]
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]
    >
    > 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: [email protected] [mailto:bounce-195687-
    >> [email protected]] 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: [email protected]
    >> To unsubscribe send a blank email to [email protected]
    >
    >
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]
    > 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
    >
    >
    >
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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.
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]
    >> 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.
    >
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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.
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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: [email protected] [mailto:bounce-195781-
    > [email protected]] 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" <[email protected]> wrote in message news:[email protected]
    > >> 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: [email protected]
    > To unsubscribe send a blank email to [email protected]
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]
    >
    > 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: [email protected] [mailto:bounce-195781-
    >> [email protected]] 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:[email protected]
    >> >> 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: [email protected]
    >> To unsubscribe send a blank email to [email protected]
    >
    >
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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: [email protected] [mailto:bounce-195824-
    > [email protected]] 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" <[email protected]> wrote in message
    > news:[email protected]
    > >
    > > 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: [email protected] [mailto:bounce-195781-
    > >> [email protected]] 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" <[email protected]> wrote in message
    > news:[email protected]
    > >> >> 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: [email protected]
    > >> To unsubscribe send a blank email to [email protected]
    > >
    > >
    > >
    >
    >
    >
    > ---
    > Questions? First check the IFS FAQ at
    > https://www.osronline.com/article.cfm?id=17
    >
    > You are currently subscribed to ntfsd as: [email protected]
    > To unsubscribe send a blank email to [email protected]
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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
    [email protected]
    http://www.storagecraft.com
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 20 Apr 2020 LIVE ONLINE
Writing WDF Drivers 11 May 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA