Hmm, I think I see what your problem is. As long as all user handles to
a deleted file are closed, the filesystem will allow new creates to come
down for a file that is pending delete (i.e. the file object pending
delete is between cleanup and close). However, since you seem to be
holding a ZwCreateFile-generated handle for the STORAGE FILE open even
after the ORIGINAL FILE has been cleaned-up, new create requests for the
STORAGE file will bounce with delete pending even if create requests for
the ORIGINAL file succeed.
You need to close your user handle for the storage file in the cleanup
handler for the original file. If you still need to perform I/O on the
storage file after that point, grab a file object with
ObReferenceObjectByHandle and then close the handle, then send down
paging I/O reads and writes on that file object. Basically, the idea
should be to match the state of the storage file object with the state
of the original file object as closely as possible.
Also, it is still illegal to call ZwClose or send down a flush buffer
request for any file during any IRP_MJ_CLOSE handler, again due to the
possibility of elevated IRQL.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Gilad Ben-Zeev
Sent: Wednesday, November 13, 2002 4:17 PM
To: File Systems Developers
Subject: [ntfsd] RE: Strange blue screen
As for the first question, the problem is that the user may have some
application that she wants to delete from the cache, and then she
decides to create it again. What I saw is when I create the storage
file, sometime, the file still exists and I get status DELETE_PENDING,
and I fail to create the file (I create it with OVERWRITE_IF). I could
change the open mechanism and send FileDispositionInformation with DELTE
= FALSE to disable the delete, but I decided that flushing the file
buffers will ensure it will be deleted when I close the last handle.
As for the second question you are right. The OnLastHandleClose takes
place on IRP_MJ_CLEANUP, but I don’t delete any internal structure until
my reference count of the File hits Zero which happens on the last close
(so I will still be able to track any other I/O going to this file after
clean up). So I mislead you when I wrote that the delete CStorageFile
happens OnLastHandleClose. It is actually happening when I get the last
close for the original file, which I track.
Gilad
-----Original Message-----
From: Nicholas Ryan [mailto:xxxxx@nryan.com]
Sent: Wed, November 13, 2002 4:04 PM
To: File Systems Developers
Subject: [ntfsd] RE: Strange blue screen
My first question is, why did you add the call to flush the storage file
in the first place? If it’s going to be deleted anyways, why bother? 
Second, it’s unclear to me whether the ‘OnLastHandleClose’ function is
being called from within the IRP_MJ_CLEANUP handler or the IRP_MJ_CLOSE
handler for the actual file. You’ve got to call it from cleanup, not
close, since close can run above PASSIVE_LEVEL. Cleanup represents the
last user handle close for the file anyways, so it’s a logical place for
it.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Gilad Ben-Zeev
Sent: Wednesday, November 13, 2002 2:59 PM
To: File Systems Developers
Subject: [ntfsd] Strange blue screen
Hi,
I have a filter driver that “emulates” a sparse file system. When the
user deletes some file (wanting to clear the cache or the application
itself deletes some files) I delete a storage file dedicated to keep the
data for this file. Recently I added to the deletion process a call to
flush the storage file buffers before closing and deleting it. The
pseudo code for this process is something like this:
OnLastHandleClose
{
.
.
if (fileIsMarkedForDeletion)
{
OpenStorageFile with Delete_On_Close_Flag
CloseTheFile
Delete CStorageFile
}
}
in the destructor of the CStorageFile I do the following:
~CStorageFile
{
IoBuildSynchronousFsdRequest(MJ_FLUSH_BUFFERS)
…
if(status == STATUS_PENDING)
{
Wait(event)
}
ObDereferenceObject(m_pStorageFileObj);
ZwClose(hFile);
}
The blue screen stack looks like this:
ed42b814 8042bef7 00000003 ed42b85c ff767f78
nt!RtlpBreakWithStatusInstruction
ed42b844 8042c2bb 00000003 c03fdd9c 80069590
nt!KiBugCheckDebugBreak+0x31
ed42bbd0 80449b3f 00000001 ff767f78 00000000 nt!KeBugCheckEx+0x390
ed42bc18 80467cc6 00000000 ff767f78 00000000 nt!MmAccessFault+0x74e
ed42bc18 8044ef1e 00000000 ff767f78 00000000 nt!KiTrap0E+0xc3
ed42bcbc 80412a35 800695c0 ff9d77e8 ed42bd00 nt!ObfDereferenceObject+0xf
ed42bce4 80410901 00000001 804754f8 816ee5e8
nt!CcDeleteSharedCacheMap+0x150
ed42bd0c 80414e10 818cd088 8046cae0 818a7700 nt!CcWriteBehind+0x289
ed42bd78 80418c49 818cd088 00000000 00000000 nt!CcWorkerThread+0x12c
ed42bda8 80454faf 818cd088 00000000 00000000 nt!ExpWorkerThread+0xae
ed42bddc 80468ec2 80418b84 00000000 00000000
nt!PspSystemThreadStartup+0x69
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
Now, after introducing the flush buffers I started to get blue screen
when cleaning our cache. Most blue screens were some kind of memory
corruption, but this one seems to be the “real” problem. It seems that
the cache manager is trying to de-reference an invalid object. I suppose
that when the memory it is trying to de-reference is allocated then the
other blue screens that showed all sort of memory corruption occurs.
One other bit of information is that all of the above occurs in the
context of an IRP_MJ_CLOSE request that comes with a stream file object,
which I identify as my filtered file by the FCB.
Any suggestion why the flushing of the buffers causes some kind of
mismatch in references in the object manager? Should I look for the
problem somewhere else and this problem is only a symptom of another
problem popping up because of more IO going on with the flush buffers?
Thanks,
Gilad
You are currently subscribed to ntfsd as: xxxxx@nryan.com
To unsubscribe send a blank email to %%email.unsub%%
You are currently subscribed to ntfsd as: xxxxx@appstream.com
To unsubscribe send a blank email to %%email.unsub%%
You are currently subscribed to ntfsd as: xxxxx@nryan.com
To unsubscribe send a blank email to %%email.unsub%%