STATUS_PENDING from IRP_MJ_CREATE

I wish I could tell you the number of times I have heard people say things like 'Make sure you can handle pending from any request ’ when talking about filters. Countless times I have heard of people who did not handle STATUS_PENDING in places they were not expecting it.

I have a monolithic redirector where I am now contemplating returning STATUS_PENDING from IRP_MJ_CREATE. I say I am contemplating this, not because I do not think it is the correct thing, but because I fear what side effects may arise. I have heard the warnings to filter writers so often that I know the handling of this situation is a common mistake. My question is whether this is just a common ‘pre-release’ mistake, or is this something that will cause me to run into problems with ‘common’ filters? Is there any reason I should avoid doing this?

To answer the question of why I need to do this: my redirector requires some synchronization on create that may take a rather long time. I have experimented with just blocking on the create, but I really feel that pending the request would be more appropriate.

Thanks.

John Eastman
Simdesk Technologies, Inc.

FAT can return STATUS_PENDING from create, although it only does so
under heavy load. Verifier has a mode where it returns STATUS_PENDING
from every operation. Vista relies upon asynchronous create (for
cancellation handling.)

If those filters break with your FSD, they will break in other cases as
well. Every I/O operation in the OS has the possibility of being
pended, and anyone that doesn’t handle it has a bug.

Tony

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@simdesk.com
Sent: Monday, May 14, 2007 6:06 AM
To: ntfsd redirect
Subject: [ntfsd] STATUS_PENDING from IRP_MJ_CREATE

I wish I could tell you the number of times I have heard people say
things like 'Make sure you can handle pending from any request ’ when
talking about filters. Countless times I have heard of people who did
not handle STATUS_PENDING in places they were not expecting it.

I have a monolithic redirector where I am now contemplating returning
STATUS_PENDING from IRP_MJ_CREATE. I say I am contemplating this, not
because I do not think it is the correct thing, but because I fear what
side effects may arise. I have heard the warnings to filter writers so
often that I know the handling of this situation is a common mistake. My
question is whether this is just a common ‘pre-release’ mistake, or is
this something that will cause me to run into problems with ‘common’
filters? Is there any reason I should avoid doing this?

To answer the question of why I need to do this: my redirector requires
some synchronization on create that may take a rather long time. I have
experimented with just blocking on the create, but I really feel that
pending the request would be more appropriate.

Thanks.

John Eastman
Simdesk Technologies, Inc.


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

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

> FAT can return STATUS_PENDING from create
Wait a minute, how about this whole thread:
http://www.osronline.com/lists_archive/ntfsd/thread3764.html?

Quote: “Many times on this list (and also on ntdev list) it was said that
IRP_MJ_CREATE must be processed synchronously.”

Not true any more?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tony Mason
Sent: Monday, May 14, 2007 12:55 PM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] STATUS_PENDING from IRP_MJ_CREATE

FAT can return STATUS_PENDING from create, although it only does so
under heavy load. Verifier has a mode where it returns STATUS_PENDING
from every operation. Vista relies upon asynchronous create (for
cancellation handling.)

If those filters break with your FSD, they will break in other cases as
well. Every I/O operation in the OS has the possibility of being
pended, and anyone that doesn’t handle it has a bug.

Tony

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@simdesk.com
Sent: Monday, May 14, 2007 6:06 AM
To: ntfsd redirect
Subject: [ntfsd] STATUS_PENDING from IRP_MJ_CREATE

I wish I could tell you the number of times I have heard people say
things like 'Make sure you can handle pending from any request ’ when
talking about filters. Countless times I have heard of people who did
not handle STATUS_PENDING in places they were not expecting it.

I have a monolithic redirector where I am now contemplating returning
STATUS_PENDING from IRP_MJ_CREATE. I say I am contemplating this, not
because I do not think it is the correct thing, but because I fear what
side effects may arise. I have heard the warnings to filter writers so
often that I know the handling of this situation is a common mistake. My
question is whether this is just a common ‘pre-release’ mistake, or is
this something that will cause me to run into problems with ‘common’
filters? Is there any reason I should avoid doing this?

To answer the question of why I need to do this: my redirector requires
some synchronization on create that may take a rather long time. I have
experimented with just blocking on the create, but I really feel that
pending the request would be more appropriate.

Thanks.

John Eastman
Simdesk Technologies, Inc.


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

You are currently subscribed to ntfsd as: xxxxx@osr.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: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

It has *never* been true that one must process IRP_MJ_CREATE
synchronously.

The thread referenced refers to issues for filter drivers, but certainly
for a file system there is considerably more latitude (e.g., the FSD can
do the security checks before posting, capture the security credentials,
etc.) Filters must contend with the assumptions of the file systems,
whereas file systems have no similar constratints.

I have done asynchronous create handling in a file system filter driver
before, but it’s definitely quite a lot of additional work. It’s less
work in an FSD since I’m not going to do impersonation, just use the
caller’s token.

Note that prior to Windows Vista the I/O Manager would block and wait
for the completion of the IRP_MJ_CREATE Irps that it creates. In
Windows Vista it still blocks, but it does so in a cancelable fashion.

Digging into the source for FastFat provides further information. The
first case I found related to oplock breaks; if you are interested, look
in create.c in the FastFat source code and look for STATUS_PENDING -
there are several cases, but none of them are “main line” paths, and
thus seeing this returned is unusual (of course, not handling it
properly in a layered legacy filter driver is a bit too common…)

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

> It has *never* been true that one must process IRP_MJ_CREATE

synchronously.
Well, you saw the quote…
I would bet that I also read it in some other serious source, and I was wondering why on earth create should be so much different from others.

The thread referenced refers to issues for filter drivers
Either create must be always synch or it is allowed to be asynch as everyone else is.
The fact that the posts I quoted refer to filters does not seem to be relevant in this context.

If I read that thread correctly, the whole point was: “there’s a bug in FAT, it takes security from a wrong place (do it as doctor Maxim prescribed as opposed to the way FAT does it), that’s why you must do creates synchronously”.

less
work in an FSD since I’m not going to do impersonation, just use the
caller’s token.
You lost me here, sorry…
If you can use caller’s token down below in FSD, why can’t you use it higher, in a filter?

Btw, when you say “caller’s token”, you mean the token of a requestor process, right?

If yes, then why I can start with IoGetRequestorProcessId in FSD to get to the token but not in FSFD?

I am almost sure that I [successfully] used IoGetRequestorProcessId in a [w2kSP4RUP - Vista mini]filter.

So - why is it “less work”?

Note that prior to Windows Vista the I/O Manager would block and wait
for the completion of the IRP_MJ_CREATE Irps that it creates.
Yep.
Nagar, chapter 4: “Many of the NT system services provided for I/O operations by the NT I/O Manager allow asynchronous operations. … Note that create/open requests are always processed synchronously …”

In
Windows Vista it still blocks, but it does so in a cancelable fashion.
Hmm, I must think it over.
[So, before Vista creates were supposed to be “fast enough not to bother with cancelling”? Like: let cancelled create complete, we will cleanup/close immediately. Then these two should also be “fast enough”. Ok, why did they change it in Vista? What is the problem that has been solved by this change?]

if you are interested, look
in create.c in the FastFat source code and look for STATUS_PENDING -
there are several cases, but none of them are “main line” paths
I will, for the upteenth time though.
Every time there’s something new:-)

Thanks, Tony.

-------------- Original message --------------
From: “Tony Mason”

> It has never been true that one must process IRP_MJ_CREATE
> synchronously.
>
> The thread referenced refers to issues for filter drivers, but certainly
> for a file system there is considerably more latitude (e.g., the FSD can
> do the security checks before posting, capture the security credentials,
> etc.) Filters must contend with the assumptions of the file systems,
> whereas file systems have no similar constratints.
>
> I have done asynchronous create handling in a file system filter driver
> before, but it’s definitely quite a lot of additional work. It’s less
> work in an FSD since I’m not going to do impersonation, just use the
> caller’s token.
>
> Note that prior to Windows Vista the I/O Manager would block and wait
> for the completion of the IRP_MJ_CREATE Irps that it creates. In
> Windows Vista it still blocks, but it does so in a cancelable fashion.
>
> Digging into the source for FastFat provides further information. The
> first case I found related to oplock breaks; if you are interested, look
> in create.c in the FastFat source code and look for STATUS_PENDING -
> there are several cases, but none of them are “main line” paths, and
> thus seeing this returned is unusual (of course, not handling it
> properly in a layered legacy filter driver is a bit too common…)
>
> Tony
>
> Tony Mason
> Consulting Partner
> OSR Open Systems Resources, Inc.
> http://www.osr.com
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com

I think you misunderstand my comments.

A file system driver assumes that it will be called in the correct
context. A filter driver must preserve those assumptions to ensure
correct operation of the file system driver. The file system driver,
however, is the “end of the line” and does not pass create operations
(or the complex logic associated with those operations) to a lower
driver. Thus, the file system driver can simplify its implementation
because it need not preserve that context for another driver lower in
its stack. Filter drivers must preserve that context.

Thus, if a filter driver wishes to post an IRP_MJ_CREATE, it must also
re-create the original calling context so that the file system driver’s
assumptions are preserved. Typically, I have done this using
impersonation (and I look at the thread first, moving to the process
only if the thread has no security token. This is the same logic that
should be used in a file system driver to ensure correct behavior in the
presence of impersonation.) It was certainly not my intention to say
“you cannot do this.” However, getting this right is surprisingly
challenging since security is just one aspect of context (e.g., think
about IRP_MJ_SET_INFORMATION where you are passed handles for various
functions. Such handles require correct process context to be valid.
Get this wrong and the system just doesn’t quite work right.)

So, a filter driver must do impersonation. A file system could, but why
would it do so? Better to make the security decision prior to posting
the request (if possible, of course) or at worst capturing a pointer to
the appropriate token so it can be passed to the relevant Se routine.
I’m sure given sufficient time I can come up with a case where the file
system might find impersonation useful, but it certainly wouldn’t be a
general case. Hence, my comment that this would be less work (no
impersonation logic in the normal case.)

The Nagar quotation is carefully worded: “create/open requests are
always processed synchronously…” This does not say “must be
processed synchronously” and it certainly does not mean that they must
be processed synchronously by the driver. The I/O Manager
implementation has always been implemented synchronously (send-and-wait
style) but if you return STATUS_PENDING from create the I/O Manager does
handle it properly. Thus, the comment refers to the OS implementation,
not to a requirement for the driver’s implementation.

My position remains the same: the I/O architecture of Windows is
inherently asynchronous. Synchronous optimizations were introduced to
improve the performance of typically synchronous applications and user
APIs, but the driver model allows asynchronous behavior. Commenting on
how the I/O Manager implements something is useful in that anyone that
builds and sends IRP must be consistent with the I/O Manager’s behavior,
but this does not restrict the driver’s ability to perform asynchronous
operations.

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com http:</http:>

> I think you misunderstand my comments.

I think I did. This post does clarify a thing or two.

the comment refers to the OS implementation, not to a requirement for the
driver’s implementation.

Yes, that’s why I quoted not just one (second) sentence from Nagar but two.
It makes it clear that he’s

talking about how I/O mgr works, not about how mj_create is processed.

My position remains the same: the I/O architecture of Windows is
inherently asynchronous.

I think it’s more than just a position (yours or mine), it’s an
architectural principle.

That’s why I was stunned by that statement and thread I referred to at the
beginning.

To recap, "Many times on this list (and also on ntdev list) it was said that

IRP_MJ_CREATE must be processed synchronously", as if it’s something
obvious.

That’s why I was scratching my head: is windows “semi-async”?

Async always, except inside mj_create?

Sounds like a joke, and I’m glad it is.

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tony Mason
Sent: Tuesday, May 15, 2007 5:45 PM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] STATUS_PENDING from IRP_MJ_CREATE

I think you misunderstand my comments.

A file system driver assumes that it will be called in the correct context.
A filter driver must preserve those assumptions to ensure correct operation
of the file system driver. The file system driver, however, is the “end of
the line” and does not pass create operations (or the complex logic
associated with those operations) to a lower driver. Thus, the file system
driver can simplify its implementation because it need not preserve that
context for another driver lower in its stack. Filter drivers must preserve
that context.

Thus, if a filter driver wishes to post an IRP_MJ_CREATE, it must also
re-create the original calling context so that the file system driver’s
assumptions are preserved. Typically, I have done this using impersonation
(and I look at the thread first, moving to the process only if the thread
has no security token. This is the same logic that should be used in a file
system driver to ensure correct behavior in the presence of impersonation.)
It was certainly not my intention to say “you cannot do this.” However,
getting this right is surprisingly challenging since security is just one
aspect of context (e.g., think about IRP_MJ_SET_INFORMATION where you are
passed handles for various functions. Such handles require correct process
context to be valid. Get this wrong and the system just doesn’t quite work
right.)

So, a filter driver must do impersonation. A file system could, but why
would it do so? Better to make the security decision prior to posting the
request (if possible, of course) or at worst capturing a pointer to the
appropriate token so it can be passed to the relevant Se routine. I’m sure
given sufficient time I can come up with a case where the file system might
find impersonation useful, but it certainly wouldn’t be a general case.
Hence, my comment that this would be less work (no impersonation logic in
the normal case.)

The Nagar quotation is carefully worded: “create/open requests are always
processed synchronously.” This does not say “must be processed
synchronously” and it certainly does not mean that they must be processed
synchronously by the driver. The I/O Manager implementation has always been
implemented synchronously (send-and-wait style) but if you return
STATUS_PENDING from create the I/O Manager does handle it properly. Thus,
the comment refers to the OS implementation, not to a requirement for the
driver’s implementation.

My position remains the same: the I/O architecture of Windows is inherently
asynchronous. Synchronous optimizations were introduced to improve the
performance of typically synchronous applications and user APIs, but the
driver model allows asynchronous behavior. Commenting on how the I/O
Manager implements something is useful in that anyone that builds and sends
IRP must be consistent with the I/O Manager’s behavior, but this does not
restrict the driver’s ability to perform asynchronous operations.

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com http:</http:>


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

You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Tony and Alex, thank you for the extension of my original question. Your discussion has given me not only the answer to my question, but some additional background as well.

However, I am now left with a new question… Does it matter? If the I/O manager is going to block for my create call anyway, will returning pending do anything useful? I imagine that since I will not be returning ‘very quickly’ in my average case, the proper thing to do is to return pending. But if the I/O manager just blocks the call anyway, what have I really gained? I understand that with Vista I may gain the ability to be cancelable during the create, but lets assume (for the moment) that my synchronization isn’t cancelable anyway. Could my create just block?

Thanks again.

John Eastman
Simdesk Technologies, Inc.

“Does it matter” is a complex question:

Are you asking “Does it matter if I only consider the I/O manager case
and ignore all other cases (remember, *anyone* can send an
IRP_MJ_CREATE) and I restrict myself to ancient systems (ergo, anything
before Vista.)” If so, the answer is “no”.

If the question is “does it matter in all possible cases, including
modern versions (e.g., Vista) and considering other callers besides the
I/O Manager.” If so, the answer is “yes”. Honestly, it might break
them because they may not have been tested with Verifier always
returning STATUS_PENDING. But in that case they are broken already.

In Vista, returning allows the create to be *cancelled*. A significant
number of hung applications turn out to be “hung” waiting for a file to
complete it’s open. Microsoft changed the model for usability to allow
canceling an in-progress open operation. This is implemented in the I/O
Manager (for example) but will vanish if you start calling
KeWaitForSingleObject in your driver (unless you use the exact right
magic incantation, which is actually documented as something you should
NOT do - it has to be done “correctly” to ensure the system doesn’t
crash later…)

So if it were me, I’d say “yes, it matters”. Give the option to the
caller. Where it doesn’t matter, it works, where it does matter it
works.

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@simdesk.com
Sent: Thursday, May 17, 2007 2:57 PM
To: ntfsd redirect
Subject: RE:[ntfsd] STATUS_PENDING from IRP_MJ_CREATE

Tony and Alex, thank you for the extension of my original question. Your
discussion has given me not only the answer to my question, but some
additional background as well.

However, I am now left with a new question… Does it matter? If the I/O
manager is going to block for my create call anyway, will returning
pending do anything useful? I imagine that since I will not be returning
‘very quickly’ in my average case, the proper thing to do is to return
pending. But if the I/O manager just blocks the call anyway, what have I
really gained? I understand that with Vista I may gain the ability to be
cancelable during the create, but lets assume (for the moment) that my
synchronization isn’t cancelable anyway. Could my create just block?

Thanks again.

John Eastman
Simdesk Technologies, Inc.


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

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

> what have I really gained?
… is an echo of my question: “what is the real problem that has
been solved (by making creates truly async and cancelable)?”

I still think - well, above and beyond an idealistic answer “let’s
make this OS async 100%, not 99%” - that it may be related to timing.

If you can bet that creates are “fast” (what is “fast”?), you can just
sit and wait for [already cancelled] create to complete - a couple of
microseconds are wasted once in a while, but who cares?

I therefore suspect that MS came across “slow” creates, remote share
is the first to come to mind here.

A “slow” create is really worth cancelling: say, you try to open
something through WebDAV and after the first 30 minutes of waiting
decide that you had enough and cancel it, and guess what? In a sync
case you just have to sip another coffee (or buy another pillow).

[I think/hope my exaggeration is obvious, ok? After all, smb and friends do have timeouts of their own.]

I may be wrong, as usual, but there must be a practical reason anyway,
I don’t think that internal changes were cheap.

But I’m happy, call me an idealist; whatever the reason for making
creates “normal” was, semi-async OS sounds like semi-pregnant to me:-)

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tony Mason
Sent: Thursday, May 17, 2007 11:48 PM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] STATUS_PENDING from IRP_MJ_CREATE

“Does it matter” is a complex question:

Are you asking “Does it matter if I only consider the I/O manager case
and ignore all other cases (remember, *anyone* can send an
IRP_MJ_CREATE) and I restrict myself to ancient systems (ergo, anything
before Vista.)” If so, the answer is “no”.

If the question is “does it matter in all possible cases, including
modern versions (e.g., Vista) and considering other callers besides the
I/O Manager.” If so, the answer is “yes”. Honestly, it might break
them because they may not have been tested with Verifier always
returning STATUS_PENDING. But in that case they are broken already.

In Vista, returning allows the create to be *cancelled*. A significant
number of hung applications turn out to be “hung” waiting for a file to
complete it’s open. Microsoft changed the model for usability to allow
canceling an in-progress open operation. This is implemented in the I/O
Manager (for example) but will vanish if you start calling
KeWaitForSingleObject in your driver (unless you use the exact right
magic incantation, which is actually documented as something you should
NOT do - it has to be done “correctly” to ensure the system doesn’t
crash later…)

So if it were me, I’d say “yes, it matters”. Give the option to the
caller. Where it doesn’t matter, it works, where it does matter it
works.

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@simdesk.com
Sent: Thursday, May 17, 2007 2:57 PM
To: ntfsd redirect
Subject: RE:[ntfsd] STATUS_PENDING from IRP_MJ_CREATE

Tony and Alex, thank you for the extension of my original question. Your
discussion has given me not only the answer to my question, but some
additional background as well.

However, I am now left with a new question… Does it matter? If the I/O
manager is going to block for my create call anyway, will returning
pending do anything useful? I imagine that since I will not be returning
‘very quickly’ in my average case, the proper thing to do is to return
pending. But if the I/O manager just blocks the call anyway, what have I
really gained? I understand that with Vista I may gain the ability to be
cancelable during the create, but lets assume (for the moment) that my
synchronization isn’t cancelable anyway. Could my create just block?

Thanks again.

John Eastman
Simdesk Technologies, Inc.


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

You are currently subscribed to ntfsd as: xxxxx@osr.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: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

In fact, it is the network opens that are the problem. While there are
timeouts, those timeouts are measured in seconds in many cases, and when
that becomes a stacking of such timeouts, what the users sees look like
hangs.

Theoretically, though, any open could be slow enough that the user
decides she does not want to wait.

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

> In fact, it is the network opens that are the problem.
Yep.

Theoretically, though, any open could be slow enough
Exactly.
This is another way of saying that OS should be async always.

-------------- Original message --------------
From: “Tony Mason”

> In fact, it is the network opens that are the problem. While there are
> timeouts, those timeouts are measured in seconds in many cases, and when
> that becomes a stacking of such timeouts, what the users sees look like
> hangs.
>
> Theoretically, though, any open could be slow enough that the user
> decides she does not want to wait.
>
> Tony
>
> Tony Mason
> Consulting Partner
> OSR Open Systems Resources, Inc.
> http://www.osr.com
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com