Which context shall I use?

Mark Roddy wrote:

Yes a FO will be held open for an indefinite amount of time after the
last user handle is closed on all FO for a file. If you use stream
contexts you are going to leverage that behavior understanding that
you will have to reconstruct your data on a particular file when the
system decides to finally close the last FO. In general this works
just fine, your mileage may vary. Don’t count on the behavior of a
system that is not under much stress as typical of all systems under
all loads.
If I understand correctly, then the stream context (and any driver
specific data included) would be valid after IRP_MJ_CLEANUP (which,
AFAIK is sent after the last user handle is closed) with one condition:
to have the Cache Manager or Memory Manager holding a reference to any
FO of the file. Please correct me if I’m wrong.

Then, another aspect: when we receive an IRP_MJ_CLOSE (which, AFAIK is
sent after the last reference to the FO is removed) then we shall expect
an immediate destruction of the stream context? Is this true? OR, this
is true ONLY when we receive the IRP_MJ_CLOSE on the LAST FO of the same
file? If the second case is true, then how can we decide, that one
arbitrary IRP_MJ_CLOSE that we receive is THE LAST for a particular file
(and that there are NO more other FOs kept alive for the same file)?

thank you very much,

Sandor LUKACS

Hi Sandor,

If I understand correctly, then the stream context (and any driver
specific data included) would be valid after IRP_MJ_CLEANUP (which,
AFAIK is sent after the last user handle is closed) with one condition:
to have the Cache Manager or Memory Manager holding a reference to any
FO of the file. Please correct me if I’m wrong.

You can query the stream context till Pre Close. It does not really matter
whether some component of the kernel has a reference on any other FO (
obviously no component can have a reference on this particular FO; otherwise
you won’t have received a Close for it).

Then, another aspect: when we receive an IRP_MJ_CLOSE (which, AFAIK is
sent after the last reference to the FO is removed) then we shall expect
an immediate destruction of the stream context? Is this true? OR, this
is true ONLY when we receive the IRP_MJ_CLOSE on the LAST FO of the same
file?

Stream Context is torn down when the FCB is. And the FCB is torn down after
the LAST file object representing a stream is closed.
However Stream Handle Context is associated with a file object and hence it
is torn down when the Close for THAT file object is received.

If the second case is true, then how can we decide, that one
arbitrary IRP_MJ_CLOSE that we receive is THE LAST for a particular file
(and that there are NO more other FOs kept alive for the same file)?

That’s not possible. Because for some FOs representing that stream, you may
not even see Create & Close. For example, the ones that have been created by
a filter driver which is below yours in the stack by calling
IoCreateFileSpecifyDeviceObjectHint.
If there is a way to know, please let me know.

Regards,
Ayush Gupta

> OR, this

is true ONLY when we receive the IRP_MJ_CLOSE on the LAST FO of the same
file?

Yes.


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

To come back to the OP’s question (sort of), is it the cache manager
that potentially holds the FCB open indefinitely, keeping the stream
context around for a long time? If so, then the issue of the stream
context’s continued existence is related to the perennial question of
“How do I get a file out of the cache? (Reboot)”, right? Or have I
misunderstood something here?

By the way, thank you everybody for the input on whether or not I should
be using stream contexts instead of my own caching, Ayush, Don, Daniel,
Joseph, and anybody else who helped explain this. Also, Daniel, I think
I owe you an apology for my poorly phrased response to you. I re-read
it when I was reading somebody else’s response and I realized it sort of
sounded like I thought you were an idiot or something. I meant nothing
of the sort; you’ve certainly been doing this a lot longer than I have,
and I have much to learn. At the moment, I’m trying to learn without
re-coding some aspect of the project several times over. Thus
soliciting more input when I see different recommendations, since I
often really don’t have enough experience to make a decision I’m
confident in. Gaining that experience by reimplementing things I’ve
done wrong the first time is educational, but not necessarily productive
in the business sense.

Thanks again, and I’ll try to phrase my questions more carefully in the
future.

~Eric

Hi Sandor,

If I understand correctly, then the stream context (and any driver
specific data included) would be valid after IRP_MJ_CLEANUP (which,
AFAIK is sent after the last user handle is closed) with one condition:

to have the Cache Manager or Memory Manager holding a reference to any
FO of the file. Please correct me if I’m wrong.

You can query the stream context till Pre Close. It does not really
matter whether some component of the kernel has a reference on any other
FO ( obviously no component can have a reference on this particular FO;
otherwise you won’t have received a Close for it).

Then, another aspect: when we receive an IRP_MJ_CLOSE (which, AFAIK is
sent after the last reference to the FO is removed) then we shall
expect
an immediate destruction of the stream context? Is this true? OR, this
is true ONLY when we receive the IRP_MJ_CLOSE on the LAST FO of the
same
file?

Stream Context is torn down when the FCB is. And the FCB is torn down
after the LAST file object representing a stream is closed.

However Stream Handle Context is associated with a file object and hence
it is torn down when the Close for THAT file object is received.

If the second case is true, then how can we decide, that one
arbitrary IRP_MJ_CLOSE that we receive is THE LAST for a particular
file
(and that there are NO more other FOs kept alive for the same file)?

That’s not possible. Because for some FOs representing that stream, you
may not even see Create & Close. For example, the ones that have been
created by a filter driver which is below yours in the stack by calling
IoCreateFileSpecifyDeviceObjectHint.

If there is a way to know, please let me know.

Regards,

Ayush Gupta