Cache manager strangeness

Hi:

I’m writing a file system driver for W2K, and have come across two very
strange (to my mind) examples of cache manager behavior.

In the first, I’m calling CcPinRead() on a FileObject I created with
IoCreateStreamFileObject(). CcPinRead(), as expected, sends a
(non-buffered) Read IRP to my driver, which I end up failing (too
complicated to go into, but I’m expecting this in this case). In this case,
I would expect either:

* CcPinRead() would return FALSE
* CcPinRead() would throw an exception

However, to my dismay, neither is happening. CcPinRead() returns TRUE, but
my Buffer pointer points to garbage. Does anyone out there have a clue as
to why this is, and how I can detect failure without explicitly having to
probe the address returned by this function?

The second case deals with CcPurgeCacheSection(). I observed this behavior:

* I call CcPurgeCacheSection() using the SectionObjectPointers from an
FCB for a file stream.
* CcPurgeCacheSection() sends a Close IRP to my driver for the
FileObject it has kept a reference to.
* This turns out to be the last outstanding reference to this FCB, so
during the Close I delete the FCB. This in turn frees the memory for the
SectionObjectPointers that I’ve sent to CcPurgeCacheSection().
* CcPurgeCacheSection() then calls MmCanFileBeTruncated(), sending it
the same SectionObjectPointers, which have now been freed. This causes a
page fault.

It seems to me that the cache manager should be aware that, once it sends a
Close IRP for its FileObject, then the SectionObjectPointers that were
handed to CcPurgeCacheSection() are now off limits. Am I off target here?

Thanks in advance for any clues that you can provide.

Curt Wohlgemuth


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

>I call CcPurgeCacheSection() using the SectionObjectPointers from an FCB

for a file stream.
CcPurgeCacheSection() sends a Close IRP to my driver for the FileObject it
has kept a reference to.

Looks like the bug is that it must NOT send CLOSE.
Looks like CcPurgeCacheSection uses ObDereferenceObject internally in it -
but this reference must not be the last one, and thus the bug is in your
reference counting.
You can check this with setting the breakpoint on CcPurgeCacheSection and
the CLOSE handler of NTFS or FAT (FAT is better since you have the source).

Max


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

>In the first, I’m calling CcPinRead() on a FileObject I created with
IoCreateStreamFileObject().

We will get a cleanup IRP as a result of calling IoCreateStreamFileObject.
The file system is expected to recognize it and do nothing instead of
uninitializing the cashing for the file object. Are u doing it?

Regards
~Arun.

-----Original Message-----
From: xxxxx@omnishift.com [mailto:xxxxx@omnishift.com]
Sent: Thursday, January 25, 2001 11:11 PM
To: File Systems Developers
Subject: [ntfsd] Cache manager strangeness

Hi:

I’m writing a file system driver for W2K, and have come across two very
strange (to my mind) examples of cache manager behavior.

In the first, I’m calling CcPinRead() on a FileObject I created with
IoCreateStreamFileObject(). CcPinRead(), as expected, sends a
(non-buffered) Read IRP to my driver, which I end up failing (too
complicated to go into, but I’m expecting this in this case). In this case,
I would expect either:

* CcPinRead() would return FALSE

* CcPinRead() would throw an exception

However, to my dismay, neither is happening. CcPinRead() returns TRUE, but
my Buffer pointer points to garbage. Does anyone out there have a clue as
to why this is, and how I can detect failure without explicitly having to
probe the address returned by this function?

The second case deals with CcPurgeCacheSection(). I observed this behavior:

* I call CcPurgeCacheSection() using the SectionObjectPointers from an
FCB for a file stream.

* CcPurgeCacheSection() sends a Close IRP to my driver for the
FileObject it has kept a reference to.

* This turns out to be the last outstanding reference to this FCB, so
during the Close I delete the FCB. This in turn frees the memory for the
SectionObjectPointers that I’ve sent to CcPurgeCacheSection().

* CcPurgeCacheSection() then calls MmCanFileBeTruncated(), sending it
the same SectionObjectPointers, which have now been freed. This causes a
page fault.

It seems to me that the cache manager should be aware that, once it sends a
Close IRP for its FileObject, then the SectionObjectPointers that were
handed to CcPurgeCacheSection() are now off limits. Am I off target here?

Thanks in advance for any clues that you can provide.

Curt Wohlgemuth

You are currently subscribed to ntfsd as: xxxxx@nestec.net
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

>In the first, I’m calling CcPinRead() on a FileObject I created with
IoCreateStreamFileObject().

We will get a cleanup IRP as a result of calling IoCreateStreamFileObject.
The file system is expected to recognize it and do nothing instead of
uninitializing the cashing for the file object. Are u doing it?

I’m doing nothing for the Cleanup for the stream file object I create.
Everything works fine as long as the non-buffered read, originating from the
cache manager, is successful: until I call ObDereferenceObject() on the
stream file object, caching works great.

Failing the read origination from CcPinRead() causes the problem I outlined
earlier.

Thanks,
Curt


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com